| | |
| | | #include "json.hpp" |
| | | #include "book.hpp" |
| | | #include "date/include/date/date.h" |
| | | #include "protocol.hpp" |
| | | #include "rapidjson/include/rapidjson/document.h" |
| | | #include "rapidjson/include/rapidjson/rapidjson.h" |
| | |
| | | static std::unordered_map<std::string, book::OrderSideEnum> mapOrder; |
| | | static std::unordered_map<std::string, TradeTypeEnum> mapTrade; |
| | | static std::unordered_map<book::OrderSideEnum, std::string> mapOrderSide; |
| | | static std::unordered_map<MessageTypes, std::string> mapAStr; |
| | | static std::unordered_map<TradeTypeEnum, std::string> mapTTStr; |
| | | |
| | | void initialise() |
| | | { |
| | |
| | | {"BROKER_TRADE", BROKER_TRADE}}; |
| | | |
| | | mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}}; |
| | | |
| | | mapAStr = {{FUTURE_TYPE, "FUTURE"}, |
| | | {SPREAD_TYPE, "SPREAD"}, |
| | | {CALL_TYPE, "CALL"}, |
| | | {PUT_TYPE, "PUT"}}; |
| | | |
| | | mapTTStr = {{BUY_AGGRESSOR, "BUY_AGGRESSOR"}, |
| | | {SELL_AGGRESSOR, "SELL_AGGRESSOR"}, |
| | | {BROKER_TRADE, "BROKER_TRADE"}}; |
| | | } |
| | | |
| | | Message* parseSingle(rapidjson::Value& d); |
| | |
| | | BrokerAck* brokerAck(rapidjson::Value& d); |
| | | BrokerConfirm* brokerCon(rapidjson::Value& d); |
| | | ErrorMessage* error(rapidjson::Value& d); |
| | | |
| | | std::chrono::seconds parseTime(std::string& s); |
| | | |
| | | std::queue<Message*> parse(std::string& str) |
| | | { |
| | |
| | | return out; |
| | | } |
| | | |
| | | std::chrono::seconds parseTime(std::string& s) |
| | | { |
| | | return std::chrono::hours{std::stoi(s.substr(0, 4)) * 24 * 30 * 12} + |
| | | std::chrono::hours{std::stoi(s.substr(5, 2)) * 24 * 30} + |
| | | std::chrono::hours{std::stoi(s.substr(8, 2)) * 24} + |
| | | std::chrono::hours{std::stoi(s.substr(11, 2))} + |
| | | std::chrono::minutes{std::stoi(s.substr(14, 2))} + |
| | | std::chrono::hours{std::stoi(s.substr(16, 5))}; |
| | | } |
| | | |
| | | AnnounceMessage* announce(rapidjson::Value& d) |
| | | { |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::string es = d["expiry"].GetString(); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> |
| | | // date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken |
| | | exp_time = parseTime(es); |
| | | return new AnnounceMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationId"].GetInt(), d["stationName"].GetString(), |
| | |
| | | |
| | | SettleMessage* settle(rapidjson::Value& d) |
| | | { |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> date::parse("%Y-%m-%d %H:%M%z", exp_time); |
| | | std::string es = d["expiry"].GetString(); |
| | | exp_time = parseTime(es); |
| | | return new SettleMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationName"].GetString(), exp_time, d["price"].GetDouble(), |
| | |
| | | |
| | | AddedMessage* added(rapidjson::Value& d) |
| | | { |
| | | return new AddedMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["id"].GetString(), mapOrder[d["side"].GetString()], |
| | | d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | return new AddedMessage(mapTypes[d["type"].GetString()], |
| | | d["product"].GetString(), d["id"].GetString(), |
| | | mapOrder[d["side"].GetString()], |
| | | d["price"].GetDouble(), d["filled"].GetInt(), |
| | | d["resting"].GetInt(), d["owner"].GetString(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | DeletedMessage* deleted(rapidjson::Value& d) |
| | |
| | | |
| | | RejectMessage* reject(rapidjson::Value& d) |
| | | { |
| | | return new RejectMessage(mapTypes[d["type"].GetString()], "", |
| | | return new RejectMessage(mapTypes[d["type"].GetString()], "", |
| | | d["error"].GetString(), uint64_t(0), double(0)); |
| | | } |
| | | |
| | |
| | | { |
| | | } |
| | | |
| | | std::string AnnounceMessage::as_string() |
| | | { |
| | | return "{\"type\": \"" + mapAStr[this->type] = |
| | | "\", \"product\": \"" + this->product + |
| | | "\", \"stationId\": " + std::to_string(this->stationId) + |
| | | "\", \"stationName\": \"" + this->stationName + |
| | | "\", \"unit\": \"" + this->unit + |
| | | "\", \"expiry\": " + std::to_string(this->expiry.count()) + |
| | | ", \"aggressiveFee\": " + std::to_string(this->aggFee) + |
| | | ", \"passiveFee\": " + std::to_string(this->pasFee) + |
| | | ", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | SettleMessage::SettleMessage(MessageTypes type, std::string product, |
| | | std::string stationName, |
| | | std::chrono::nanoseconds expiry, double price, |
| | |
| | | : FromExchange(type, product, sequence, timestamp), |
| | | stationName(stationName), expiry(expiry), price(price) |
| | | { |
| | | } |
| | | |
| | | std::string SettleMessage::as_string() |
| | | { |
| | | return "{\"type\": \"" + mapAStr[this->type] = |
| | | "\", \"product\": \"" + this->product + |
| | | "\", \"stationName\": \"" + this->stationName + |
| | | "\", \"expiry\": " + std::to_string(this->expiry.count()) + |
| | | ", \"price\": " + std::to_string(this->price) + |
| | | ", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | AddMessage::AddMessage(MessageTypes type, std::string product, double price, |
| | |
| | | { |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"ADD\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"volume\": " + std::to_string(this->volume) + "}"; |
| | | "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"volume\": " + std::to_string(this->volume) + "}"; |
| | | } |
| | | |
| | | AddedMessage::AddedMessage(MessageTypes type, std::string product, |
| | | std::string id, book::OrderSideEnum side, |
| | | double price, uint64_t filled, uint64_t resting, |
| | | uint64_t sequence, double timestamp) |
| | | std::string owner, uint64_t sequence, |
| | | double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), id(id), side(side), |
| | | price(price), filled(filled), resting(resting) |
| | | price(price), filled(filled), resting(resting), owner(owner) |
| | | { |
| | | } |
| | | |
| | | std::string AddedMessage::as_string() |
| | | { |
| | | return "{\"type\": \"ADDED\", \"product\": \"" + this->product + |
| | | "\", \"product\": \"" + this->id + "\" \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | "\"filled\": " + std::to_string(this->filled) + |
| | | ", \"resting\": " + std::to_string(this->resting) + |
| | | ", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\":" + std::to_string(this->timestamp) + "}"; |
| | | "\", \"product\": \"" + this->id + "\", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | ", \"filled\": " + std::to_string(this->filled) + |
| | | ", \"resting\": " + std::to_string(this->resting) + |
| | | ", \"owner\": \"" + this->owner + |
| | | "\", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | DeleteMessage::DeleteMessage(MessageTypes type, std::string product, |
| | |
| | | { |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"DELETE\", \"product\": \"" + this->product + |
| | | "\", \"id\": \"" + this->id + "\"}"; |
| | | "\", \"id\": \"" + this->id + "\"}"; |
| | | } |
| | | |
| | | DeletedMessage::DeletedMessage(MessageTypes type, std::string product, |
| | |
| | | std::string DeletedMessage::as_string() |
| | | { |
| | | return "{\"type\": \"DELETED\", \"product\": \"" + this->product + |
| | | "\", \"product\": \"" + this->id + "\" \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | ", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\":" + std::to_string(this->timestamp) + "}"; |
| | | "\", \"product\": \"" + this->id + "\", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | ", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | RejectMessage::RejectMessage(MessageTypes type, std::string product, |
| | |
| | | |
| | | std::string RejectMessage::as_string() |
| | | { |
| | | return "{\"type\": \"REJECT\", \"product\": \"" + this->product = |
| | | "\", \"error\": \"" + this->error + |
| | | "\", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | return "{\"type\": \"REJECT\", \"product\": \"" + this->product + |
| | | "\", \"error\": \"" + this->error + |
| | | "\", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | TradeMessage::TradeMessage(MessageTypes type, std::string product, double price, |
| | |
| | | { |
| | | } |
| | | |
| | | std::string TradeMessage::as_string() |
| | | { |
| | | return "{\"type\": \"TRADE\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | ", \"volume\": " + std::to_string(this->volume) + ", \"buyer\": \"" + |
| | | this->buyer + "\", \"seller\": \"" + this->seller + |
| | | "\", \"tradeType\": \"" + mapTTStr[this->tradeType] + |
| | | "\", \"passiveOrder\": \"" + this->passiveOrder + |
| | | "\", \"passoveOrderRemaining\": " + |
| | | std::to_string(this->passiveOrderRemaining) + |
| | | "\", \"sequence\": " + std::to_string(this->sequence) + |
| | | ", \"timestamp\": " + std::to_string(this->timestamp) + "}"; |
| | | } |
| | | |
| | | BrokerRequest::BrokerRequest(MessageTypes type, std::string product, |
| | | double price, book::OrderSideEnum side, |
| | | uint64_t volume, std::string counterparty) |
| | | : Broker(type, product, price, side, volume, counterparty) |
| | | { |
| | | } |
| | | |
| | | std::string BrokerRequest::as_string() |
| | | { |
| | | return "{\"type\": \"" + mapAStr[this->type] = |
| | | "\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | ", \"side\": " + mapOrderSide[this->side] + |
| | | ", \"volume\": " + std::to_string(this->volume) + |
| | | ", \"counterparty\": \"" + this->counterparty + "\"}"; |
| | | } |
| | | |
| | | BrokerAck::BrokerAck(MessageTypes type, std::string product, double price, |
| | |
| | | { |
| | | } |
| | | |
| | | std::string BrokerAck::as_string() |
| | | { |
| | | return "{\"type\": \"" + mapAStr[this->type] = |
| | | "\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | ", \"side\": " + mapOrderSide[this->side] + |
| | | ", \"volume\": " + std::to_string(this->volume) + |
| | | ", \"counterparty\": \"" + this->counterparty + +"\", \"id\"" + |
| | | this->id + |
| | | "\", \"brokerTradeStatus\": " + this->brokerTradeStatus + |
| | | "\", \"owner\": \"" + this->owner + "\"}"; |
| | | } |
| | | |
| | | BrokerConfirm::BrokerConfirm(MessageTypes type, std::string product, |
| | | double price, book::OrderSideEnum side, |
| | | uint64_t volume, std::string counterparty, |
| | |
| | | : Broker(type, product, price, side, volume, counterparty), id(id) |
| | | { |
| | | } |
| | | |
| | | std::string BrokerConfirm::as_string() |
| | | { |
| | | return "{\"type\": \"" + mapAStr[this->type] = |
| | | "\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + |
| | | ", \"side\": " + mapOrderSide[this->side] + |
| | | ", \"volume\": " + std::to_string(this->volume) + |
| | | ", \"counterparty\": \"" + this->counterparty + |
| | | "\", \"id\": " + this->id + "\"}"; |
| | | } |
| | | |
| | | } // namespace json |