Compare commits

...
Author SHA1 Message Date
Mohammad Arham 420f6d7cc0 all exectuion work 2024-10-18 21:26:43 +00:00
21 changed files with 1004 additions and 51 deletions

No files matched your search

@@ -156,6 +156,8 @@ AdminServiceUtils::resolve_connection(
const bts::api::admin::ExchangeConnection *rv = nullptr;
switch (sec.exchange()) {
case api::Venue::VENUE_GLBX: {
//CME EXECUTION NEEDS TO BE UPDATED, probably merge with VENUE_BINANCE_USDS_FUTURES
auto deployment_type =
boost::to_lower_copy(config::get<config::DeploymentType>().type());
rv = resolve_cme_connection(data, account, sec);
@@ -227,6 +229,7 @@ void AdminServiceUtils::fill_connections_from_config(
connection.set_name(c.name());
switch (c.venue()) {
//CME EXECUTION NEEDS TO BE UPDATED, probably merge default case
case bts::api::VENUE_GLBX:
if (c.cme_market_segment_id() == 0)
connection.mutable_cme_connection()->mutable_cgw_connection();
@@ -236,9 +239,7 @@ void AdminServiceUtils::fill_connections_from_config(
->set_market_segment_id(c.cme_market_segment_id());
add_connection(admin_data, connection);
break;
case bts::api::VENUE_CBOE:
break;
case bts::api::VENUE_TAIFEX:
case bts::api::VENUE_TAIFEX:
break;
case bts::api::VENUE_SIM:
case bts::api::VENUE_SIMICE:
@@ -250,6 +251,7 @@ void AdminServiceUtils::fill_connections_from_config(
c.sender_compid());
add_connection(admin_data, connection);
break;
case bts::api::VENUE_CBOE:
default:
connection.mutable_general_connection()->set_exchange(c.venue());
add_connection(admin_data, connection);
@@ -571,6 +573,13 @@ bts::api::orderman::RoutingRecord AdminServiceUtils::get_routing_record(
return rv;
}
switch (sec.exchange()) {
case api::Venue::VENUE_CBOE:{
rv.set_session("cboe_1");
rv.set_account(account_ptr->name());
rv.set_operator_id(user_ptr->name());
out_result.set_is_success(true);
return rv;
}
case api::Venue::VENUE_DERIBIT: {
rv.set_session("deribit_1");
rv.set_account(account_ptr->name());
@@ -741,7 +750,6 @@ bts::api::orderman::RoutingRecord AdminServiceUtils::get_routing_record(
case api::VENUE_OKX:
case api::Venue::VENUE_UNSET:
case api::Venue::VENUE_BTS:
case api::Venue::VENUE_CBOE:
case api::Venue::VENUE_TAIFEX:
case api::Venue::VENUE_CBOECFE:
case api::Venue::Venue_INT_MIN_SENTINEL_DO_NOT_USE_:
+2
View File
@@ -409,6 +409,7 @@ message RoutingRecord {
message NativeOrderState {
string exchange_order_id = 1;
string external_order_id = 11; //"string : orderkey"
uint64 last_msg_seq_num = 4;
enum SubError {
SUB_ERROR_NONE = 0;
@@ -752,6 +753,7 @@ message RetrievedExchangeOpenOrder{
string exchange_sec_desc = 10;
string exchange_account = 20;
string exchange_order_id = 30;
string external_order_id = 11; //"string : orderkey"
uint32 security_key = 40;
bool security_resolved = 50;
string account_name = 60;
@@ -0,0 +1,12 @@
OnixFixCfg {
value{
name: "trafix",
msg_type: "Order_Single",
protocol_version: "FIX_42",
handl_inst: 2,
sender_sub_id: "BTS",
target_sub_id: "TRFXMRX",
client_id: "BTS",
rule80a: 1
}
}
+23
View File
@@ -0,0 +1,23 @@
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 name = 9;
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;
}
@@ -60,7 +60,7 @@ class OrderStateUpdateEvent : public mercury::Event<OrderStateUpdateEvent> {
} else {
auto native_state = get_native_state(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();
last_msg_seq_num = native_state->last_msg_seq_num();
sub_error_code = native_state->sub_error_code();
@@ -4,9 +4,12 @@
#include "lib/orderman/gateways/CCAPIExecutionGateway.h"
// #include "lib/orderman/gateways/EMExecutionGateway.h"
#include "lib/orderman/gateways/FakeExecutionGateway.h"
#include "lib/orderman/gateways/GeneralExecutionGateway.h"
#include "lib/orderman/gateways/GLBXExecutionGateway.h"
#include "lib/orderman/gateways/GLBXiLink3ExecutionGateway.h"
#include "lib/orderman/gateways/ICEExecutionGateway.h"
#include "lib/orderman/gateways/IFIXGenericAdapter.h"
#include "lib/orderman/gateways/OnixFIXAdapter.h"
#include "lib/orderman/gateways/sim/SimExecutionGatewayFactory.h"
#include "lib/orderman/gateways/sim/SimExecutionGatewayUniqueWrapper.h"
#include "lib/tracing/PerfLog.h"
@@ -21,23 +24,30 @@ std::unique_ptr<IExecutionGateway> ExecutionGatewayFactory::create_gateway(
const config::JetFIX::Connection &conn,
trace::PerfLog &pl,
md::SecurityOracle o) {
LOG(OrderMan, Info, "ExecutionGatewayFactory::create_gateway conn: {}",
utils::pb::to_string(conn));
if (SimExecutionGatewayFactory::is_sim_execution_on(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 ||
conn.venue() == bts::api::VENUE_SIMICE)
return std::make_unique<ICEExecutionGateway>(conn, pl, o);
else if (conn.venue() == bts::api::VENUE_GLBX) {
if (conn.use_ilink3())
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)
// return std::make_unique<EMExecutionGateway>(o);
return std::make_unique<CCAPIExecutionGateway>(conn.venue(), o);
return std::make_unique<FakeExecutionGateway>(o);
switch(conn.venue()){
case bts::api::VENUE_ICE:
case bts::api::VENUE_SIMICE:
return std::make_unique<ICEExecutionGateway>(conn, pl, o);
case bts::api::VENUE_GLBX:{
if (conn.use_ilink3())
return std::make_unique<ilink3::GLBXiLink3ExecutionGateway>( conn, pl, o);
return std::make_unique<GLBXExecutionGateway>(conn, pl, o);
}
case bts::api::VENUE_DERIBIT:
return std::make_unique<CCAPIExecutionGateway>(conn.venue(), o);
case bts::api::VENUE_CBOE:
{
std::unique_ptr<IFIXGenericAdapter> adapter = std::make_unique<OnixFIXAdapter>();
return std::make_unique<GeneralExecutionGateway>(conn.venue(),std::move(adapter),o);
}
default:
return std::make_unique<FakeExecutionGateway>(o);
}
}
} // namespace bts::orderman
@@ -0,0 +1,85 @@
#include "GeneralExecutionGateway.h"
#include "lib/domain_model/Security.pb.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/orderman_utils/CancelReject.h"
#include <memory>
#include <type_traits>
namespace bts::orderman {
struct GeneralExecutionGateway::PImpl {
PImpl(bts::api::Venue venue,
std::unique_ptr<IFIXGenericAdapter> adapter,
md::SecurityOracle o)
: venue(venue), _adapter(std::move(adapter)), sec_oracle(o) {}
bts::api::Venue venue;
std::unique_ptr<IFIXGenericAdapter> _adapter;
md::SecurityOracle sec_oracle;
OnExeReport on_exe_report;
OnGwStatusChange on_gw_status_change;
OnCancelReject on_cancel_reject;
OnExchangePositionState on_exchange_position_state;
OnExchangeOpenOrdersState on_exchange_open_orders;
};
OnGwStatusChange &GeneralExecutionGateway::on_gw_status_change() {
return me->on_gw_status_change;
}
// Modified constructor to accept the adapter from outside
GeneralExecutionGateway::GeneralExecutionGateway(bts::api::Venue venue,
std::unique_ptr<IFIXGenericAdapter> adapter, md::SecurityOracle o)
: IExecutionGateway(), me(new PImpl(venue, std::move(adapter),o)) {
LOG(OrderMan, Info, "ExecutionGateway::ExecutionGateway constructor");
}
GeneralExecutionGateway::~GeneralExecutionGateway() {}
void GeneralExecutionGateway::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 GeneralExecutionGateway::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 GeneralExecutionGateway::dispatch_incoming_fix_messages() {}
void GeneralExecutionGateway::on_securities(
const mercury::Update<NewSecuritiesEvent> &) {}
void GeneralExecutionGateway::on_admin_data(
const mercury::Update<NewAdminDataEvent> &) {}
void GeneralExecutionGateway::send_fix(const jetfix::OutFIXPtr &, trace::CorID) {}
OnExeReport &GeneralExecutionGateway::on_exe_report() { return me->on_exe_report; }
OnCancelReject &GeneralExecutionGateway::on_cancel_reject() {
static OnCancelReject default_cancel_reject;
return default_cancel_reject;
}
OnExchangePositionState &GeneralExecutionGateway::on_exchange_position_state() {
static OnExchangePositionState default_exchange_position_state;
return default_exchange_position_state;
}
OnExchangeOpenOrdersState &GeneralExecutionGateway::on_exchange_open_orders() {
static OnExchangeOpenOrdersState default_exchange_open_orders;
return default_exchange_open_orders;
}
} //namespace bts::orderman
@@ -0,0 +1,29 @@
#pragma once
#include "lib/orderman/gateways/IExecutionGateway.h"
#include "lib/orderman/gateways/IFIXGenericAdapter.h"
namespace bts {
namespace orderman {
class GeneralExecutionGateway : public IExecutionGateway {
public:
GeneralExecutionGateway(bts::api::Venue venue,std::unique_ptr<IFIXGenericAdapter> adapter,
md::SecurityOracle o);
virtual ~GeneralExecutionGateway();
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
@@ -1,3 +1,6 @@
#include "IFIXGenericAdapter.h"
namespace bts::orderman {}
namespace bts::orderman {
IFIXGenericAdapter::~IFIXGenericAdapter(){}
}
+19 -19
View File
@@ -15,8 +15,8 @@
#include "lib/utils/bts_no_copy.h"
#include <functional>
#include <memory>
#include <variant>
namespace bts::orderman {
@@ -29,33 +29,33 @@ class NewAdminDataEvent;
class ExecutionReport;
class CancelReject;
struct OrderStateWithFills {
api::orderman::OrderState ordr_state;
std::vector<api::orderman::Fill> fills = {};
};
// struct OrderStateWithFills {
// api::orderman::OrderState ordr_state;
// 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
class IFIXGenericAdapter {
public:
IFIXGenericAdapter() = default;
virtual ~IFIXGenericAdapter() {}
virtual ~IFIXGenericAdapter();
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
virtual void register_callback(const OnOrderUpdate &);
virtual void launch_new_order(const CreateOrderMsg &);
virtual void modify_order(const CancelReplaceOrderMsg &);
virtual void cancel_order(const CancelOrderMsg &);
// // 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 OnExecutionReport &) =0 ;
virtual void launch_new_order(const CreateOrderMsg &) =0;
virtual void modify_order(const CancelReplaceOrderMsg &) = 0;
virtual void cancel_order(const CancelOrderMsg &) =0;
// as new securities are added
virtual void update_securities(
const mercury::Update<NewSecuritiesEvent> &) = 0;
virtual void update_admin_data(
const mercury::Update<NewAdminDataEvent> &) = 0;
// virtual void update_securities(
// const mercury::Update<NewSecuritiesEvent> &) = 0;
// virtual void update_admin_data(
// const mercury::Update<NewAdminDataEvent> &) = 0;
private:
BTS_NO_COPY(IFIXGenericAdapter);
// private:
// BTS_NO_COPY(IFIXGenericAdapter);
};
} // namespace bts::orderman
@@ -0,0 +1,406 @@
#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/CreateOrderMsg.h"
#include "lib/orderman/gateways/OnixFIXListener.h"
#include "lib/orderman/gateways/TrafixOrderStateHandler.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 <memory>
#include <quickfix/FixFields.h>
#include <string>
namespace bts::orderman {
OnixFIXAdapter::OnixFIXAdapter()
: state_handler(std::make_shared<TrafixOrderStateHandler>()), listener(state_handler), // 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)
sec.option().call_put() == bts::api::PutOrCall::PUTORCALL_CALL ? "1" : "0")
.set(OnixS::FIX::FIX42::Tags::StrikePrice, //strike_price)
std::to_string(sec.option().strike()))
.set(OnixS::FIX::FIX42::Tags::MaturityMonthYear,// maturity_month_year)
std::to_string(sec.option().expiration_month()) +std::to_string(sec.option().expiration_year()))
.set(OnixS::FIX::FIX42::Tags::MaturityDay, //exp_day)
std::to_string(sec.option().expiration_day()))
.set(OnixS::FIX::FIX42::Tags::SecurityType,"OPT")
.set(OnixS::FIX::FIX42::Tags::Symbol,// osi_symbol)
osi)
.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 =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>() //add this
std::string symbol = 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::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)
.set(OnixS::FIX::FIX42::Tags::Currency,msg.security->currency());
}
std::string order_string = order.toString('|');
order.validate();
LOG(OrderMan, Warn, "order Validated");
order.set(847, "SMART");
state_handler->launch_order(msg);
session->send(&order);
// TrafixOrderStateHandler
// auto er = listener.fire_dummy_report(msg);
LOG(OrderMan, Warn, "Order 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::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);
if (msg.security->has_option()) {
parse_option(order_cancel, *msg.security);}
else{
order_cancel.set(OnixS::FIX::FIX42::Tags::Symbol, msg.security->symbol())
.set(OnixS::FIX::FIX42::Tags::Currency,msg.security->currency());
}
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,27 @@
#pragma once
#include "IFIXGenericAdapter.h"
#include "lib/orderman/gateways/OnixFIXListener.h"
#include "lib/orderman/gateways/TrafixOrderStateHandler.h"
#include <memory>
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:
std::shared_ptr<TrafixOrderStateHandler> state_handler;
OnixFixListener listener;
std::unique_ptr<Session> session;
bool updated = false;
};
} // namespace bts::orderman
@@ -0,0 +1,175 @@
#include "OnixFIXListener.h"
#include "lib/api/services/OrderService.pb.h"
#include "lib/domain_model/Security.pb.h"
#include "lib/domain_model/common.h"
#include "lib/logging/logging.h"
#include "lib/orderman/gateways/IExecutionGateway.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 {
ExecutionReport OnixFixListener::fire_dummy_report(CreateOrderMsg msg) {
ExecutionReport *er_p = exe_report_pool.construct();
ExecutionReport &er = *er_p;
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 = msg.security->exchange();
// Set transaction time
ExchangeTimeStamp64 now = ExchangeTimeStamp64(datetime::unix_nano_now());
er.transact_time = now;
cb(er,{});
return er;
}
ExecutionReport OnixFixListener::get_exe_report(Message msg) {
ExecutionReport *er_p = exe_report_pool.construct();
ExecutionReport &er = *er_p;
auto msg_str = msg.toString();
LOG(OrderMan,Info, "OnixFixListener::get_exe_report {}", msg_str);
std::string account_name = "BTSIM";
std::string ops_id = "op_id_bts";
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(
ops_id, &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 = ;
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 = api::orderman::ExecType(std::stoi(msg.get(OnixS::FIX::FIX42::Tags::ExecType).toString()));
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 = Price(std::stod(msg.get(OnixS::FIX::FIX42::Tags::Price)));
er.quantity = Quantity(std::stoi(msg.get(FIX42::Tags::OrderQty)));
er.filled_quantity = Quantity(0);
er.last_shares = Quantity(0);
er.msg = "Message Placed";
er.exchange = api::VENUE_CBOE;
// 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_exe_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,52 @@
#pragma once
#include "lib/orderman/CreateOrderMsg.h"
#include "lib/orderman/gateways/IExecutionGateway.h"
#include "lib/orderman/gateways/TrafixOrderStateHandler.h"
#include "lib/orderman/orderman_utils/ExecutionReport.h"
#include <OnixS/FIXEngine.h>
#include <OnixS/FIXEngine/FIX/Message.h>
#include <boost/pool/object_pool.hpp>
namespace bts::orderman {
using namespace OnixS::FIX;
class OnixFixListener : public OnixS::FIX::ISessionListener {
public:
OnixFixListener( std::shared_ptr<TrafixOrderStateHandler> state_handler) : state_handler(state_handler),cb(dummy) {
LOG(OrderMan, Info, "OnixFixListener::cb set callback registered");
}
std::shared_ptr<TrafixOrderStateHandler> state_handler;
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;
ExecutionReport fire_dummy_report(CreateOrderMsg msg);
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
@@ -0,0 +1,82 @@
#include "TrafixOrderStateHandler.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>
namespace bts::orderman {
// Internal structure for storing order info
struct TrafixOrderStateHandler::OrderInfo {
OrderInfo(const CreateOrderMsg &msg)
: update_count(0), routing_record(msg.routing_record) {}
uint update_count;
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());
}
};
// PImpl structure containing the actual implementation details, including SecurityOracle
struct TrafixOrderStateHandler::PImpl {
PImpl() {}
std::unordered_map<bts::orderman::OrderKey, OrderInfo> orders;
// md::SecurityOracle sec_oracle;
};
// Constructor
TrafixOrderStateHandler::TrafixOrderStateHandler()
: me(std::make_unique<PImpl>()) {}
// Destructor
TrafixOrderStateHandler::~TrafixOrderStateHandler() = default;
// Method to launch an order
bts::orderman::OrderKey TrafixOrderStateHandler::launch_order(const CreateOrderMsg &msg) {
me->orders.emplace(msg.key, OrderInfo(msg));
return bts::orderman::OrderKey(msg.key);
}
// Method to modify an order
bts::orderman::OrderKey TrafixOrderStateHandler::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
return bts::orderman::null_order_key();
}
return it->first;
}
// Utility method to get order key from a string
bts::orderman::OrderKey TrafixOrderStateHandler::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);
}
// Method to get update number from string
int TrafixOrderStateHandler::get_update_number(const std::string& id) {
std::size_t pos = id.find(':');
if (pos == std::string::npos) {
return -1; // No colon found
}
std::string prefix = id.substr(0, pos);
// Check if the prefix contains only digits
if (prefix.empty() || !std::all_of(prefix.begin(), prefix.end(), ::isdigit)) {
return -1; // Not a valid number
}
// Convert the valid numeric prefix to an integer
return std::stoi(prefix);
}
} // namespace b
@@ -0,0 +1,28 @@
#pragma once
#include "IFIXGenericAdapter.h"
#include "lib/orderman/gateways/OnixFIXListener.h"
#include "lib/orderman/orderman_utils/orderman_common.h"
#include <memory>
namespace bts::orderman {
class TrafixOrderStateHandler {
public:
TrafixOrderStateHandler();
~TrafixOrderStateHandler();
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);
static int get_update_number(const std::string& id);
private:
struct OrderInfo;
struct PImpl;
std::unique_ptr<PImpl> me;
};
} // namespace bts::orderman
@@ -129,7 +129,7 @@ NativeOrderBase *OrderFactory::make_order(const api::Venue exchange) {
return new ICENativeOrder();
else if (exchange == api::VENUE_GLBX || exchange == api::VENUE_SIM)
return new GLBXNativeOrder();
return new EMNativeOrder();
return new EMNativeOrder(exchange);
}
NativeOrderBase *OrderFactory::make_native_order(
+15 -6
View File
@@ -5,6 +5,7 @@
#include "lib/config/protos/toggles.pb.h"
#include "lib/domain/OrderStatus.h"
#include "lib/domain_model/Security.h"
#include "lib/domain_model/Security.pb.h"
#include "lib/domain_model/common.h"
#include "lib/jetfix/codec/FIXFragment.h"
#include "lib/jetfix/codec/FieldDefinitions.h"
@@ -52,10 +53,10 @@ struct InflightUpdateState {
};
struct EMNativeOrder::PImpl {
PImpl()
PImpl(const api::Venue exchange)
: instance_id(EMNativeOrder::count++), services(nullptr),
session_services(), sec(nullptr), previous_working_position(0),
definition(), state(), exchange_order_id() {}
definition(), state(), exchange_order_id(), exchange(exchange) {}
const int instance_id;
bool inited = false;
OrderServices *services;
@@ -67,7 +68,7 @@ struct EMNativeOrder::PImpl {
OrderDefinition definition;
OrderState state;
std::optional<ExchangeOrderIDVar> exchange_order_id;
const api::Venue exchange;
OrderServices::ExeReportSubID exe_report_sid;
OrderServices::CancelRejectSubID cancel_reject_sid;
// If a cancel is sent before the order placement is ack'ed this is set to
@@ -82,7 +83,7 @@ struct EMNativeOrder::PImpl {
RoutingRecord routing_record;
};
EMNativeOrder::EMNativeOrder() : me(new PImpl()) {
EMNativeOrder::EMNativeOrder(const api::Venue exchange) : me(new PImpl(exchange)) {
LOG(OrderMan, Info,
"EMNativeOrder::EMNativeOrder instance_id: {} t_id: {} t_name: {}",
me->instance_id, os::get_thread_id(), os::get_application_name());
@@ -501,11 +502,19 @@ OrderOpResult EMNativeOrder::_on_activate(
me->state.set_filled_quantity(0);
me->state.set_last_price(0);
me->state.set_avg_price(0);
me->session_services = &me->services->get_session_services(
get_native_state(me->state).routing_record().session());
// TODO: just to get going
me->session_services = &me->services->get_session_services("deribit_1");
std::string session_name;
switch (me->exchange) {
case api::VENUE_CBOE:
session_name = "cboe_1";
break;
default:
session_name ="deribit_1";
}
me->session_services = &me->services->get_session_services(session_name);
// Checks for the following:
// 1. Gateway connection
+2 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#include "lib/api/services/OrderService.pb.h"
#include "lib/domain_model/Security.pb.h"
#include "lib/domain_model/common.h"
#include "lib/orderman/CreateOrderMsg.h"
#include "lib/orderman/orders/NativeOrderBase.h"
@@ -19,7 +20,7 @@ class SessionServices;
// Wrapper around Emumba's order
class EMNativeOrder : public NativeOrderBase {
public:
EMNativeOrder();
EMNativeOrder(const api::Venue exchange = api::VENUE_DERIBIT);
~EMNativeOrder() override;
api::orderman::OrderDefinition const &definition() const override;
void on_init_new(
+4 -4
View File
@@ -478,7 +478,7 @@ OrderOpResult GLBXNativeOrder::on_activate(
now.to_uint64(), (now - corid.app_arrival).nanoseconds());
// in sim mode, we dont need this,
me->encoder->send_create(*me->services, *me->session_services);
if (me->in_sim_mode) {
if (me->in_sim_mode) { //CME EXECUTION NEEDS TO BE UPDATED
CreateOrderMsg c_msg = {};
_create_create_msg(c_msg);
me->services->queue_order_msg(*me->session_services, c_msg);
@@ -579,7 +579,7 @@ OrderOpResult GLBXNativeOrder::on_update(api::orderman::Update const &update) {
auto p = Price(update.price());
auto q = Quantity(update.quantity());
auto send_update_in_sim_mode = [&]() {
if (me->in_sim_mode) {
if (me->in_sim_mode) { //CME EXECUTION NEEDS TO BE UPDATED
CancelReplaceOrderMsg cxl_repl_msg = {};
_create_create_msg(cxl_repl_msg.create_fields);
Price new_p = Price(update.price());
@@ -799,7 +799,7 @@ OrderOpResult GLBXNativeOrder::on_cancel() {
me->encoder->update_cancel_encoding(*me->services);
me->encoder->send_cancel(*me->services, *me->session_services);
// TODO: check for sim mode here
if (me->in_sim_mode) {
if (me->in_sim_mode) { //CME EXECUTION NEEDS TO BE UPDATED
CancelOrderMsg cxl_msg = {};
cxl_msg.key = key();
LOG(OrderMan, Info, "GLBXNativeOrder queue_order_msg for cxl");
@@ -1381,7 +1381,7 @@ void GLBXNativeOrder::_create_create_msg(CreateOrderMsg &c) {
bts::orderman::get_quantity(me->state, StateQuantityType::OrderQuantity);
c.security = me->sec;
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); //CME EXECUTION NEEDS TO BE UPDATED
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();
@@ -277,6 +277,7 @@ 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);
//CME EXECUTION NEEDS TO BE UPDATED, can be commented out
}
void iLink2OrderEncoder::update_create_order_encoding(