Added .clang-format, applied it to a couple of files.
This commit is contained in:
1 parent
a68ff5342c
commit
b76bec20ad
2 files changed
+133
-107
No files matched your search
@@ -0,0 +1 @@
|
||||
IndentWidth: 3
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "OrderManager.h"
|
||||
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "server/sparkd/jetfix/common/OutFIX.h"
|
||||
#include "server/sparkd/orderman2/actors/order_manager/OrderServices.h"
|
||||
#include "server/sparkd/orderman2/events/OrderManagerReadyEvent.h"
|
||||
#include "server/sparkd/orderman2/order_factory/OrderFactory.h"
|
||||
#include "server/sparkd/orderman2/orders/Order.h"
|
||||
#include "server/sparkd/securities/ISecurityDB.h"
|
||||
#include "server/sparkd/orderman2/actors/order_manager/OrderServices.h"
|
||||
#include "server/sparkd/orderman2/events/OrderManagerReadyEvent.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace bts {
|
||||
namespace orderman2 {
|
||||
@@ -18,33 +17,27 @@ namespace orderman2 {
|
||||
using namespace mercury;
|
||||
const auto fix_buffer_pool_size = 10000;
|
||||
|
||||
enum class OrderManager::State {WAIT_SEC, WAIT_ORDERS, READY } ;
|
||||
enum class OrderManager::State { WAIT_SEC, WAIT_ORDERS, READY };
|
||||
|
||||
struct OrderManager::OrderInfo {
|
||||
OrderInfo (Order &o, OrderServicesData &data)
|
||||
: order(&o),
|
||||
order_services(std::make_unique<OrderServices> (o,data))
|
||||
{}
|
||||
OrderInfo(Order &o, OrderServicesData &data)
|
||||
: order(&o), order_services(std::make_unique<OrderServices>(o, data)) {}
|
||||
|
||||
OrderInfo() = default;
|
||||
OrderInfo(OrderInfo &&src) = default;
|
||||
OrderInfo& operator=(OrderInfo &&src) = default;
|
||||
OrderInfo &operator=(OrderInfo &&src) = default;
|
||||
|
||||
Order *order;
|
||||
std::unique_ptr<OrderServices> order_services;
|
||||
};
|
||||
|
||||
struct OrderManager::PImpl
|
||||
{
|
||||
PImpl(config::JetFIX::Connection const &cfg, Actor&owner) :
|
||||
state (State::WAIT_SEC),
|
||||
cfg(cfg),
|
||||
gw_name(GatewayName(cfg.name())),
|
||||
services_data(cfg,owner)
|
||||
{}
|
||||
struct OrderManager::PImpl {
|
||||
PImpl(config::JetFIX::Connection const &cfg, Actor &owner)
|
||||
: state(State::WAIT_SEC), cfg(cfg), gw_name(GatewayName(cfg.name())),
|
||||
services_data(cfg, owner) {}
|
||||
|
||||
State state;
|
||||
std::unordered_map<OrderKey,OrderInfo> orders;
|
||||
std::unordered_map<OrderKey, OrderInfo> orders;
|
||||
mercury::Actor::SubHandle stored_order_sub;
|
||||
const config::JetFIX::Connection cfg;
|
||||
const GatewayName gw_name;
|
||||
@@ -52,46 +45,48 @@ struct OrderManager::PImpl
|
||||
mercury::Stream<OrderManagerReadyEvent> pub_ready;
|
||||
};
|
||||
|
||||
OrderManager::OrderManager (config::JetFIX::Connection const&cfg) : me (new PImpl(cfg,*this)) {}
|
||||
OrderManager::~OrderManager () {}
|
||||
OrderManager::OrderManager(config::JetFIX::Connection const &cfg)
|
||||
: me(new PImpl(cfg, *this)) {}
|
||||
OrderManager::~OrderManager() {}
|
||||
|
||||
void OrderManager::init()
|
||||
{
|
||||
subscribe<NewSecuritiesEvent>([this] (auto const&sec_update) {this->on_securities(sec_update);});
|
||||
void OrderManager::init() {
|
||||
subscribe<NewSecuritiesEvent>(
|
||||
[this](auto const &sec_update) { this->on_securities(sec_update); });
|
||||
}
|
||||
|
||||
void OrderManager::on_securities(const mercury::Update<NewSecuritiesEvent> &update)
|
||||
{
|
||||
void OrderManager::on_securities(
|
||||
const mercury::Update<NewSecuritiesEvent> &update) {
|
||||
if (update.events) {
|
||||
|
||||
// update our security db
|
||||
for (auto ev : *(update.events)) {
|
||||
auto sec_ptr = ev.security;
|
||||
me->services_data.sec_db.securities[SecurityKey(sec_ptr->id())] = sec_ptr;
|
||||
me->services_data.sec_db.securities[SecurityKey(sec_ptr->id())] =
|
||||
sec_ptr;
|
||||
}
|
||||
|
||||
if (me->state == State::WAIT_SEC) {
|
||||
// obtain recovered orders
|
||||
me->state = State::WAIT_ORDERS;
|
||||
me->stored_order_sub =
|
||||
subscribe<StoredOrderEvent> (me->gw_name,
|
||||
[this] (auto const&orders)
|
||||
{this->on_order_recovery(orders);});
|
||||
me->stored_order_sub = subscribe<StoredOrderEvent>(
|
||||
me->gw_name,
|
||||
[this](auto const &orders) { this->on_order_recovery(orders); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_order_recovery(const mercury::Update<StoredOrderEvent> &update)
|
||||
{
|
||||
void OrderManager::on_order_recovery(
|
||||
const mercury::Update<StoredOrderEvent> &update) {
|
||||
if (update.events)
|
||||
if (me->state == State::WAIT_ORDERS) {
|
||||
// Got the first batch of persisted orders which has to match
|
||||
// the orders stored on disk (since we are the only ones
|
||||
// producing new orders)
|
||||
for (auto const &ev : *(update.events)) {
|
||||
auto &order = me->services_data.order_factory.recover(*ev.order_record);
|
||||
auto const&ostate = ev.order_record->state();
|
||||
OrderInfo oi {order,me->services_data};
|
||||
auto &order =
|
||||
me->services_data.order_factory.recover(*ev.order_record);
|
||||
auto const &ostate = ev.order_record->state();
|
||||
OrderInfo oi{order, me->services_data};
|
||||
auto serv_ptr = oi.order_services.get();
|
||||
me->orders[order.key()] = std::move(oi);
|
||||
order.on_activate(Price(ostate.price()),
|
||||
@@ -115,25 +110,35 @@ void OrderManager::on_order_recovery(const mercury::Update<StoredOrderEvent> &up
|
||||
// it. In that case we will do our best to recover the order
|
||||
// from the execution report. That is the only purpose of
|
||||
// this subscription.
|
||||
subscribe<NewExecutionReportEvent> (me->gw_name,
|
||||
[this] (auto const&ev) {this->on_execution_report(ev);});
|
||||
subscribe<NewExecutionReportEvent>(
|
||||
me->gw_name,
|
||||
[this](auto const &ev) { this->on_execution_report(ev); });
|
||||
|
||||
// we need to know the gateway status because some of our
|
||||
// orders need to know it at activation time. The
|
||||
// ContentSubscription mechanism does not provide a synopsis
|
||||
// so we cache the last known state of the gateway ourselves
|
||||
// and offer it to the orders.
|
||||
subscribe<GatewayStatusChangeEvent> (me->gw_name,
|
||||
[this] (auto const&ev) {this->on_gateway_state(ev);});
|
||||
subscribe<GatewayStatusChangeEvent>(
|
||||
me->gw_name,
|
||||
[this](auto const &ev) { this->on_gateway_state(ev); });
|
||||
|
||||
// Order creation and maintenance
|
||||
subscribe<ActivateOrderEvent>(me->gw_name, [this] (auto const&ev) {this->on_activate_order(ev);});
|
||||
subscribe<UpdateOrderEvent>(me->gw_name, [this] (auto const&ev) {this->on_update_order(ev);});
|
||||
subscribe<CancelOrderEvent>(me->gw_name, [this] (auto const&ev) {this->on_cancel_order(ev);});
|
||||
subscribe<CrackOrderEvent>(me->gw_name, [this] (auto const&ev) {this->on_crack_order(ev);});
|
||||
subscribe<ActivateOrderEvent>(me->gw_name, [this](auto const &ev) {
|
||||
this->on_activate_order(ev);
|
||||
});
|
||||
subscribe<UpdateOrderEvent>(me->gw_name, [this](auto const &ev) {
|
||||
this->on_update_order(ev);
|
||||
});
|
||||
subscribe<CancelOrderEvent>(me->gw_name, [this](auto const &ev) {
|
||||
this->on_cancel_order(ev);
|
||||
});
|
||||
subscribe<CrackOrderEvent>(
|
||||
me->gw_name, [this](auto const &ev) { this->on_crack_order(ev); });
|
||||
|
||||
// clock
|
||||
subscribe<mercury::TimerEvent>([this] (auto const &ev) {this->on_timer(ev);});
|
||||
subscribe<mercury::TimerEvent>(
|
||||
[this](auto const &ev) { this->on_timer(ev); });
|
||||
|
||||
// Allocating FIX buffers is relatively expensive so we try
|
||||
// to keep a pool of pre-allocated buffers ready. To
|
||||
@@ -141,8 +146,9 @@ void OrderManager::on_order_recovery(const mercury::Update<StoredOrderEvent> &up
|
||||
// and listen for replies
|
||||
while (free_buffers().size() != fix_buffer_pool_size)
|
||||
free_buffers().push_back(std::make_shared<jetfix::OutFIX>(me->cfg));
|
||||
subscribe<CreateFIXBufferReplyEvent>(me->gw_name,
|
||||
[this] (auto const &ev) {this->on_new_fix_buffer(ev);});
|
||||
subscribe<CreateFIXBufferReplyEvent>(
|
||||
me->gw_name,
|
||||
[this](auto const &ev) { this->on_new_fix_buffer(ev); });
|
||||
|
||||
// Subscription setup/teardown is a relatively heavy
|
||||
// operation. For that reason we use coarse-grained topics to
|
||||
@@ -150,77 +156,99 @@ void OrderManager::on_order_recovery(const mercury::Update<StoredOrderEvent> &up
|
||||
// can impose more fine-grained and light weight filtering on
|
||||
// top of those topic subscriptions through the
|
||||
// ContentSubscription helper class.
|
||||
me->services_data.md_subs = ContentSubscription<BookUpdateEvent> (*this);
|
||||
me->services_data.child_order_subs = ContentSubscription<OrderStateUpdateEvent,ParentKey> (*this);
|
||||
me->services_data.md_subs = ContentSubscription<BookUpdateEvent> (*this);
|
||||
me->services_data.exe_report_subs = ContentSubscription<NewExecutionReportEvent> (*this,me->gw_name);
|
||||
me->services_data.cancel_reject_subs = ContentSubscription<CancelRejectEvent> (*this,me->gw_name);
|
||||
me->services_data.gateway_status_subs = ContentSubscription<GatewayStatusChangeEvent,NoKey> (*this);
|
||||
me->services_data.time_subs = ContentSubscription<TimerEvent,NoKey> (*this);
|
||||
me->services_data.order_creation_subs = ContentSubscription<CreateOrderReplyEvent> (*this,me->gw_name);
|
||||
me->services_data.md_subs =
|
||||
ContentSubscription<BookUpdateEvent>(*this);
|
||||
me->services_data.child_order_subs =
|
||||
ContentSubscription<OrderStateUpdateEvent, ParentKey>(*this);
|
||||
me->services_data.md_subs =
|
||||
ContentSubscription<BookUpdateEvent>(*this);
|
||||
me->services_data.exe_report_subs =
|
||||
ContentSubscription<NewExecutionReportEvent>(*this, me->gw_name);
|
||||
me->services_data.cancel_reject_subs =
|
||||
ContentSubscription<CancelRejectEvent>(*this, me->gw_name);
|
||||
me->services_data.gateway_status_subs =
|
||||
ContentSubscription<GatewayStatusChangeEvent, NoKey>(*this);
|
||||
me->services_data.time_subs =
|
||||
ContentSubscription<TimerEvent, NoKey>(*this);
|
||||
me->services_data.order_creation_subs =
|
||||
ContentSubscription<CreateOrderReplyEvent>(*this, me->gw_name);
|
||||
|
||||
// Outputs
|
||||
me->services_data.order_state_pub = make_stream<OrderStateUpdateEvent>();
|
||||
me->services_data.out_fix_pub = make_stream<OutFIXMsgEvent>(me->gw_name);
|
||||
me->services_data.activate_order_pub = make_stream<ActivateOrderEvent>(me->gw_name);
|
||||
me->services_data.update_order_pub = make_stream<UpdateOrderEvent>(me->gw_name);
|
||||
me->services_data.cancel_order_pub = make_stream<CancelOrderEvent>(me->gw_name);
|
||||
me->services_data.crack_order_pub = make_stream<CrackOrderEvent>(me->gw_name);
|
||||
me->services_data.create_order_req_pub = make_stream<CreateOrderRequestEvent>(me->gw_name);
|
||||
me->services_data.create_fix_req_pub = make_stream<CreateFIXBufferRequestEvent>(me->gw_name);
|
||||
me->services_data.order_state_pub =
|
||||
make_stream<OrderStateUpdateEvent>();
|
||||
me->services_data.out_fix_pub =
|
||||
make_stream<OutFIXMsgEvent>(me->gw_name);
|
||||
me->services_data.activate_order_pub =
|
||||
make_stream<ActivateOrderEvent>(me->gw_name);
|
||||
me->services_data.update_order_pub =
|
||||
make_stream<UpdateOrderEvent>(me->gw_name);
|
||||
me->services_data.cancel_order_pub =
|
||||
make_stream<CancelOrderEvent>(me->gw_name);
|
||||
me->services_data.crack_order_pub =
|
||||
make_stream<CrackOrderEvent>(me->gw_name);
|
||||
me->services_data.create_order_req_pub =
|
||||
make_stream<CreateOrderRequestEvent>(me->gw_name);
|
||||
me->services_data.create_fix_req_pub =
|
||||
make_stream<CreateFIXBufferRequestEvent>(me->gw_name);
|
||||
me->services_data.md_request_pub = make_stream<MDRequestEvent>();
|
||||
me->services_data.report_order_state_pub = make_stream<OrderStateUpdateEvent>();
|
||||
me->pub_ready = make_stream<OrderManagerReadyEvent> (me->gw_name);
|
||||
me->services_data.report_order_state_pub =
|
||||
make_stream<OrderStateUpdateEvent>();
|
||||
me->pub_ready = make_stream<OrderManagerReadyEvent>(me->gw_name);
|
||||
|
||||
// signal that we are ready
|
||||
publish(me->pub_ready);
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_execution_report(const mercury::Update<NewExecutionReportEvent> &m)
|
||||
{
|
||||
void OrderManager::on_execution_report(
|
||||
const mercury::Update<NewExecutionReportEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto const &report: *m.events) {
|
||||
for (auto const &report : *m.events) {
|
||||
auto k = report.data->order_key;
|
||||
auto it = me->orders.find(k);
|
||||
if (it == me->orders.end()) {
|
||||
LOG(OrderMan,Error,
|
||||
"Received an execution report for an unknown order with key {}. "
|
||||
"Order state will be reconstructed from this report but some information "
|
||||
LOG(OrderMan, Error,
|
||||
"Received an execution report for an unknown order with key "
|
||||
"{}. "
|
||||
"Order state will be reconstructed from this report but some "
|
||||
"information "
|
||||
"will be lost, including CustomerOrFirm,CTI code and "
|
||||
"parent order id", k.value());
|
||||
auto order = &me->services_data.order_factory.recreate_from_exe_report(*report.data);
|
||||
OrderInfo oi {*order,me->services_data};
|
||||
"parent order id",
|
||||
k.value());
|
||||
auto order =
|
||||
&me->services_data.order_factory.recreate_from_exe_report(
|
||||
*report.data);
|
||||
OrderInfo oi{*order, me->services_data};
|
||||
auto serv_ptr = oi.order_services.get();
|
||||
me->orders[order->key()] = std::move(oi);
|
||||
order->on_activate(report.data->price,report.data->quantity,*serv_ptr);
|
||||
order->on_activate(report.data->price, report.data->quantity,
|
||||
*serv_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_activate_order(const mercury::Update<ActivateOrderEvent> &m)
|
||||
{
|
||||
void OrderManager::on_activate_order(
|
||||
const mercury::Update<ActivateOrderEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto const &ev: *m.events) {
|
||||
for (auto const &ev : *m.events) {
|
||||
auto order = ev.order;
|
||||
auto k = order->key();
|
||||
bts_assert(me->orders.find(k) != me->orders.end());
|
||||
OrderInfo oi {*order,me->services_data};
|
||||
OrderInfo oi{*order, me->services_data};
|
||||
auto serv_ptr = oi.order_services.get();
|
||||
me->orders[k] = std::move(oi);
|
||||
order->on_activate(ev.price,ev.quantity,*serv_ptr);
|
||||
order->on_activate(ev.price, ev.quantity, *serv_ptr);
|
||||
}
|
||||
}
|
||||
void OrderManager::on_update_order(const mercury::Update<UpdateOrderEvent> &m)
|
||||
{
|
||||
void OrderManager::on_update_order(const mercury::Update<UpdateOrderEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto const &ev: *m.events) {
|
||||
for (auto const &ev : *m.events) {
|
||||
auto k = ev.key();
|
||||
auto it = me->orders.find(k);
|
||||
if (it != me->orders.end())
|
||||
it->second.order->on_update(ev.price,ev.quantity);
|
||||
it->second.order->on_update(ev.price, ev.quantity);
|
||||
else {
|
||||
LOG(OrderMan,Error,
|
||||
LOG(OrderMan, Error,
|
||||
"Received an update request for an unknown order {}. "
|
||||
"This should not happen and likely indicates a serious bug. ",
|
||||
ev.key().value());
|
||||
@@ -228,16 +256,15 @@ void OrderManager::on_update_order(const mercury::Update<UpdateOrderEvent> &m)
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_cancel_order(const mercury::Update<CancelOrderEvent> &m)
|
||||
{
|
||||
void OrderManager::on_cancel_order(const mercury::Update<CancelOrderEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto const &ev: *m.events) {
|
||||
for (auto const &ev : *m.events) {
|
||||
auto k = ev.key();
|
||||
auto it = me->orders.find(k);
|
||||
if (it != me->orders.end())
|
||||
it->second.order->on_cancel();
|
||||
else {
|
||||
LOG(OrderMan,Error,
|
||||
LOG(OrderMan, Error,
|
||||
"Received a cancel request for an unknown order {}. "
|
||||
"This should not happen and likely indicates a serious bug. ",
|
||||
ev.key().value());
|
||||
@@ -245,16 +272,15 @@ void OrderManager::on_cancel_order(const mercury::Update<CancelOrderEvent> &m)
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_crack_order(const mercury::Update<CrackOrderEvent> &m)
|
||||
{
|
||||
void OrderManager::on_crack_order(const mercury::Update<CrackOrderEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto const &ev: *m.events) {
|
||||
for (auto const &ev : *m.events) {
|
||||
auto k = ev.key();
|
||||
auto it = me->orders.find(k);
|
||||
if (it != me->orders.end())
|
||||
it->second.order->on_crack();
|
||||
else {
|
||||
LOG(OrderMan,Error,
|
||||
LOG(OrderMan, Error,
|
||||
"Received a crack request for an unknown order {}. "
|
||||
"This should not happen and likely indicates a serious bug. ",
|
||||
ev.key().value());
|
||||
@@ -262,30 +288,29 @@ void OrderManager::on_crack_order(const mercury::Update<CrackOrderEvent> &m)
|
||||
}
|
||||
}
|
||||
|
||||
void OrderManager::on_gateway_state(const mercury::Update<GatewayStatusChangeEvent> &m)
|
||||
{
|
||||
void OrderManager::on_gateway_state(
|
||||
const mercury::Update<GatewayStatusChangeEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto ev : *m.events)
|
||||
me->services_data.gw_connected = ev.is_connected;
|
||||
}
|
||||
|
||||
void OrderManager::on_new_fix_buffer(const mercury::Update<CreateFIXBufferReplyEvent> &m)
|
||||
{
|
||||
void OrderManager::on_new_fix_buffer(
|
||||
const mercury::Update<CreateFIXBufferReplyEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto ev : *m.events)
|
||||
free_buffers().insert(free_buffers().end(),
|
||||
ev.buffers.begin(), ev.buffers.end());
|
||||
free_buffers().insert(free_buffers().end(), ev.buffers.begin(),
|
||||
ev.buffers.end());
|
||||
}
|
||||
|
||||
void OrderManager::on_timer(const mercury::Update<mercury::TimerEvent> &m)
|
||||
{
|
||||
void OrderManager::on_timer(const mercury::Update<mercury::TimerEvent> &m) {
|
||||
if (m.events)
|
||||
for (auto ev : *m.events)
|
||||
me->services_data.last_timer_ev = ev;
|
||||
}
|
||||
|
||||
|
||||
std::vector<jetfix::OutFIXPtr> &OrderManager::free_buffers()
|
||||
{return me->services_data.free_buffers;}
|
||||
|
||||
}}
|
||||
std::vector<jetfix::OutFIXPtr> &OrderManager::free_buffers() {
|
||||
return me->services_data.free_buffers;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user