18 #ifndef ORDER_ENTRY_CLIENT_HPP
19 #define ORDER_ENTRY_CLIENT_HPP
27 #include "exceptions.hpp"
28 #include "messages.hpp"
45 asio::ip::tcp::socket socket;
51 uint32_t output_buffer_size = 0;
55 bool is_authorized =
false;
64 inline void write_buffer() {
68 [
this](
const std::error_code& error, std::size_t) {
70 throw Exception(
"Client::write_buffer - " + error.message());
72 output_buffer.pop_front();
74 if (--output_buffer_size) write_buffer();
80 inline void read_buffer() {
81 input_buffer.emplace_back();
85 [
this](
const std::error_code& error, std::size_t) {
87 if (error == asio::error::eof) {
88 is_authorized = false;
89 throw Exception(
"Client::read_buffer - Connection to remote host closed!");
91 throw Exception(
"Client::read_buffer - " + error.message());
94 auto message = input_buffer.front();
95 input_buffer.pop_front();
100 case Messages::MessageID::LoginResponse: { handle(
reinterpret_cast<Messages::LoginResponse&
>(message));
break; }
102 case Messages::MessageID::OrderResponse: { handle(
reinterpret_cast<Messages::OrderResponse&
>(message));
break; }
105 case Messages::MessageID::PurgeResponse: { handle(
reinterpret_cast<Messages::PurgeResponse&
>(message));
break; }
106 case Messages::MessageID::TradeResponse: { handle(
reinterpret_cast<Messages::TradeResponse&
>(message));
break; }
118 switch (response.
status) {
119 case Messages::LoginResponseStatus::Accepted: { is_authorized =
true;
break; }
120 case Messages::LoginResponseStatus::NotAuthorized: { is_authorized =
false;
break; }
121 case Messages::LoginResponseStatus::AlreadyAuthorized: { is_authorized =
true;
break; }
122 case Messages::LoginResponseStatus::SessionInUse: { is_authorized =
false;
break; }
130 void handle(
const Messages::LogoutResponse& response) {
131 is_authorized =
false;
134 switch (response.reason) {
135 case Messages::LogoutReason::UserRequested: {
break; }
136 case Messages::LogoutReason::EndOfDay: {
break; }
137 case Messages::LogoutReason::Administrative: {
break; }
138 case Messages::LogoutReason::ProtocolViolation: {
break; }
146 void handle(
const Messages::OrderResponse& response) {
147 if (response.status == Messages::OrderStatus::Rejected) {
148 std::cerr <<
"Client::handle(OrderResponse) - order rejected" << std::endl;
152 if (response.order_id == 0)
155 active_orders.insert(response.order_id);
162 void handle(
const Messages::CancelResponse& response) {
163 if (response.status == Messages::CancelStatus::Rejected) {
164 std::cerr <<
"Client::handle(CancelResponse) - cancel rejected" << std::endl;
169 active_orders.erase(response.order_id);
176 void handle(
const Messages::ReplaceResponse& response) {
177 if (response.status == Messages::ReplaceStatus::Rejected) {
178 std::cerr <<
"Client::handle(ReplaceResponse) - replace rejected" << std::endl;
183 if (response.canceled != 0)
184 active_orders.erase(response.canceled);
186 if (response.new_order_id != 0)
187 active_orders.insert(response.new_order_id);
194 void handle(
const Messages::PurgeResponse& response) {
195 if (response.status == Messages::PurgeStatus::Rejected) {
196 std::cerr <<
"Client::handle(PurgeResponse) - purge rejected" << std::endl;
200 active_orders.clear();
207 void handle(
const Messages::TradeResponse& response) {
208 switch (response.side) {
210 shares -= response.quantity;
211 capital += response.quantity * response.price;
215 shares += response.quantity;
216 capital -= response.quantity * response.price;
221 if (response.order_id != 0) {
222 if (response.leaves_quantity == 0)
223 active_orders.erase(response.order_id);
231 void handle(
const Messages::Header& header) {
232 is_authorized =
false;
233 throw Exception(
"Client::handle(Header) - received message with invalid header " + header.to_string());
243 Client(asio::io_context& context, std::string host, std::string port) :
246 asio::connect(socket, asio::ip::tcp::resolver(context).resolve(host, port));
298 template <
class T,
typename ...Args>
299 inline void send(Args && ...args) {
301 output_buffer.emplace_back();
303 new (&output_buffer.back()) T{sequence++, std::forward<Args>(args)...};
306 if (++output_buffer_size == 1) write_buffer();
314 template <
class T,
typename ...Args>
317 output_buffer.emplace_back();
319 new (&output_buffer.back()) T{sequence++, std::forward<Args>(args)...};
322 if (++output_buffer_size == 1) write_buffer();
328 #endif // ORDER_ENTRY_CLIENT_HPP