Joel Grunbaum
2022-01-13 90107c504e5b7d1bea2c93a43c7d07b640350355
commit | author | age
16b655 1 #include "json.hpp"
JG 2 #include "book.hpp"
3 #include "protocol.hpp"
b4cf0a 4 #include "rapidjson/include/rapidjson/document.h"
JG 5 #include "rapidjson/include/rapidjson/rapidjson.h"
16b655 6 #include <chrono>
JG 7 #include <cstddef>
8 #include <cstdint>
9 #include <cstring>
10 #include <deque>
11 #include <iomanip>
12 #include <netdb.h>
13 #include <numeric>
14 #include <queue>
15 #include <sstream>
16 #include <string>
17 #include <unordered_map>
18 #include <utility>
19
20 namespace json
21 {
22 static std::unordered_map<std::string, MessageTypes> mapTypes;
23 static std::unordered_map<MessageTypes, book::ProductTypeEnum> mapAnnounce;
24 static std::unordered_map<std::string, book::OrderSideEnum> mapOrder;
25 static std::unordered_map<std::string, TradeTypeEnum> mapTrade;
26 static std::unordered_map<book::OrderSideEnum, std::string> mapOrderSide;
27
28 void initialise()
29 {
2c515f 30     mapTypes = {{"FUTURE", FUTURE_TYPE},
JG 31                 {"SPREAD", SPREAD_TYPE},
32                 {"CALL", CALL_TYPE},
33                 {"PUT", PUT_TYPE},
34                 {"SETTLEMENT", SETTLEMENT},
35                 {"ADDED", ADDED},
36                 {"DELETED", DELETED},
37                 {"TRADE", TRADE},
38                 {"BROKER_REQUEST", BROKER_REQUEST},
39                 {"BROKER_ACK", BROKER_ACK},
40                 {"BROKER_CONFIRM", BROKER_CONFIRM}};
16b655 41
2c515f 42     mapAnnounce = {{FUTURE_TYPE, book::FUTURE},
JG 43                    {SPREAD_TYPE, book::SPREAD},
44                    {CALL_TYPE, book::CALL},
45                    {PUT_TYPE, book::PUT}};
16b655 46
2c515f 47     mapOrder = {{"BUY", book::Buy}, {"SELL", book::Sell}};
16b655 48
2c515f 49     mapTrade = {{"BUY_AGGRESSOR", BUY_AGGRESSOR},
4fdb65 50                 {"SELL_AGGRESSOR", SELL_AGGRESSOR},
e8c910 51                 {"BROKER_TRADE", BROKER_TRADE}};
16b655 52
2c515f 53     mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}};
16b655 54 }
JG 55
b4cf0a 56 Message* parseSingle(rapidjson::Value& d);
JG 57 AnnounceMessage* announce(rapidjson::Value& d);
58 SettleMessage* settle(rapidjson::Value& d);
59 AddedMessage* added(rapidjson::Value& d);
60 DeletedMessage* deleted(rapidjson::Value& d);
6bdd28 61 RejectMessage* reject(rapidjson::Value& d);
b4cf0a 62 TradeMessage* trade(rapidjson::Value& d);
JG 63 BrokerRequest* brokerReq(rapidjson::Value& d);
64 BrokerAck* brokerAck(rapidjson::Value& d);
65 BrokerConfirm* brokerCon(rapidjson::Value& d);
6bdd28 66 ErrorMessage* error(rapidjson::Value& d);
16b655 67
d2cfd3 68 std::chrono::seconds parseTime(std::string& s);
JG 69
b4cf0a 70 std::queue<Message*> parse(std::string& str)
16b655 71 {
2c515f 72     std::queue<Message*> out;
JG 73     rapidjson::Document d;
74     d.Parse(str.c_str());
75     if (d.IsArray()) {
76         for (rapidjson::SizeType i = 0; i < d.Size(); i++) {
77             out.push(parseSingle(d[i]));
78         }
79     } else {
80         out.push(parseSingle(d));
b4cf0a 81     }
2c515f 82     return out;
16b655 83 }
JG 84
b4cf0a 85 Message* parseSingle(rapidjson::Value& d)
16b655 86 {
2c515f 87     if (mapTypes.empty()) {
JG 88         initialise();
89     }
6bdd28 90     if (d.HasMember("error")) return error(d);
2c515f 91     Message* out;
JG 92     switch (mapTypes[d["type"].GetString()]) {
93     case FUTURE_TYPE:
94     case SPREAD_TYPE:
95     case CALL_TYPE:
96     case PUT_TYPE:
97         out = announce(d);
98         break;
99     case SETTLEMENT:
100         out = settle(d);
101         break;
102     case ADDED:
103         out = added(d);
104         break;
105     case DELETED:
106         out = deleted(d);
6bdd28 107         break;
JG 108     case REJECT:
109         out = reject(d);
2c515f 110         break;
JG 111     case TRADE:
112         out = trade(d);
113         break;
114     case BROKER_REQUEST:
115         out = brokerReq(d);
116         break;
117     case BROKER_ACK:
118         out = brokerAck(d);
119         break;
120     case BROKER_CONFIRM:
121         out = brokerCon(d);
122         break;
123     default:
124         out = new Message(NONE, "");
125         break;
126     }
127     return out;
16b655 128 }
JG 129
d2cfd3 130 std::chrono::seconds parseTime(std::string& s)
JG 131 {
132     return std::chrono::hours{std::stoi(s.substr(0, 4)) * 24 * 30 * 12} +
133            std::chrono::hours{std::stoi(s.substr(5, 2)) * 24 * 30} +
134            std::chrono::hours{std::stoi(s.substr(8, 2)) * 24} +
135            std::chrono::hours{std::stoi(s.substr(11, 2))} +
136            std::chrono::minutes{std::stoi(s.substr(14, 2))} +
137            std::chrono::hours{std::stoi(s.substr(16, 5))};
138 }
139
b4cf0a 140 AnnounceMessage* announce(rapidjson::Value& d)
16b655 141 {
d2cfd3 142     std::string es = d["expiry"].GetString();
2c515f 143     std::chrono::nanoseconds exp_time(0);
d2cfd3 144     exp_time = parseTime(es);
2c515f 145     return new AnnounceMessage(
JG 146         mapTypes[d["type"].GetString()], d["product"].GetString(),
147         d["stationId"].GetInt(), d["stationName"].GetString(),
148         d["unit"].GetString(), exp_time, d["aggressiveFee"].GetDouble(),
149         d["passiveFee"].GetDouble(), d["brokerFee"].GetDouble(),
150         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 151 }
JG 152
b4cf0a 153 SettleMessage* settle(rapidjson::Value& d)
16b655 154 {
2c515f 155     std::chrono::nanoseconds exp_time(0);
d2cfd3 156     std::string es = d["expiry"].GetString();
JG 157     exp_time = parseTime(es);
2c515f 158     return new SettleMessage(
JG 159         mapTypes[d["type"].GetString()], d["product"].GetString(),
160         d["stationName"].GetString(), exp_time, d["price"].GetDouble(),
161         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 162 }
JG 163
b4cf0a 164 AddedMessage* added(rapidjson::Value& d)
16b655 165 {
2c515f 166     return new AddedMessage(
JG 167         mapTypes[d["type"].GetString()], d["product"].GetString(),
168         d["id"].GetString(), mapOrder[d["side"].GetString()],
169         d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(),
170         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 171 }
JG 172
b4cf0a 173 DeletedMessage* deleted(rapidjson::Value& d)
16b655 174 {
2c515f 175     return new DeletedMessage(
JG 176         mapTypes[d["type"].GetString()], d["product"].GetString(),
177         d["id"].GetString(), mapOrder[d["side"].GetString()],
178         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 179 }
JG 180
6bdd28 181 RejectMessage* reject(rapidjson::Value& d)
JG 182 {
183     return new RejectMessage(mapTypes[d["type"].GetString()], "",
184                              d["error"].GetString(), uint64_t(0), double(0));
185 }
186
b4cf0a 187 TradeMessage* trade(rapidjson::Value& d)
16b655 188 {
2c515f 189     return new TradeMessage(
JG 190         mapTypes[d["type"].GetString()], d["product"].GetString(),
191         d["price"].GetDouble(), d["volume"].GetInt(), d["buyer"].GetString(),
192         d["seller"].GetString(), mapTrade[d["tradeType"].GetString()],
193         d["passiveOrder"].GetString(), d["passiveOrderRemaining"].GetInt(),
194         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 195 }
JG 196
b4cf0a 197 BrokerRequest* brokerReq(rapidjson::Value& d)
16b655 198 {
2c515f 199     return new BrokerRequest(
JG 200         mapTypes[d["type"].GetString()], d["product"].GetString(),
201         d["price"].GetDouble(), mapOrder[d["side"].GetString()],
202         d["volume"].GetInt(), d["counterparty"].GetString());
16b655 203 }
JG 204
b4cf0a 205 BrokerAck* brokerAck(rapidjson::Value& d)
16b655 206 {
2c515f 207     return new BrokerAck(mapTypes[d["type"].GetString()],
JG 208                          d["product"].GetString(), d["price"].GetDouble(),
209                          mapOrder[d["side"].GetString()], d["volume"].GetInt(),
210                          d["counterparty"].GetString(), d["id"].GetString(),
211                          d["brokerTradeStatus"].GetString(),
212                          d["owner"].GetString());
16b655 213 }
b4cf0a 214 BrokerConfirm* brokerCon(rapidjson::Value& d)
16b655 215 {
2c515f 216     return new BrokerConfirm(
JG 217         mapTypes[d["type"].GetString()], d["product"].GetString(),
218         d["price"].GetDouble(), mapOrder[d["side"].GetString()],
219         d["volume"].GetInt(), d["counterparty"].GetString(),
220         d["id"].GetString());
16b655 221 }
JG 222
6bdd28 223 ErrorMessage* error(rapidjson::Value& d)
JG 224 {
225     return new ErrorMessage(d["error"].GetString());
226 }
227
16b655 228 Message::Message() : type(NONE), product("error") {}
JG 229
230 Message::Message(MessageTypes types, std::string product)
2c515f 231     : type(types), product(product)
16b655 232 {
6bdd28 233 }
JG 234
235 ErrorMessage::ErrorMessage(std::string message)
236     : Message(ERROR, ""), message(message)
237 {
238 }
239 std::string ErrorMessage::as_string()
240 {
241     return "{\"error\": \"" + this->message + "\"}";
16b655 242 }
JG 243
244 FromExchange::FromExchange(MessageTypes type, std::string product,
245                            uint64_t sequence, double timestamp)
2c515f 246     : Message(type, product), sequence(sequence), timestamp(timestamp)
16b655 247 {
JG 248 }
249
250 ToExchange::ToExchange(MessageTypes type, std::string product)
2c515f 251     : Message(type, product){};
16b655 252
JG 253 Broker::Broker(MessageTypes type, std::string product, double price,
254                book::OrderSideEnum side, uint64_t volume,
255                std::string counterparty)
2c515f 256     : Message(type, product), price(price), side(side), volume(volume),
JG 257       counterparty(counterparty)
16b655 258 {
JG 259 }
260
261 AnnounceMessage::AnnounceMessage(MessageTypes type, std::string product,
b4cf0a 262                                  int stationId, std::string stationName,
16b655 263                                  std::string unit,
JG 264                                  std::chrono::nanoseconds expiry, double aggFee,
265                                  double pasFee, double broFee,
266                                  uint64_t sequence, double timestamp)
2c515f 267     : FromExchange(type, product, sequence, timestamp), stationId(stationId),
JG 268       stationName(stationName), unit(unit), expiry(expiry), aggFee(aggFee),
269       pasFee(pasFee), broFee(broFee)
16b655 270 {
JG 271 }
272
273 SettleMessage::SettleMessage(MessageTypes type, std::string product,
274                              std::string stationName,
275                              std::chrono::nanoseconds expiry, double price,
276                              uint64_t sequence, double timestamp)
2c515f 277     : FromExchange(type, product, sequence, timestamp),
JG 278       stationName(stationName), expiry(expiry), price(price)
16b655 279 {
JG 280 }
281
282 AddMessage::AddMessage(MessageTypes type, std::string product, double price,
283                        book::OrderSideEnum side, uint64_t volume)
2c515f 284     : ToExchange(type, product), price(price), side(side), volume(volume)
16b655 285 {
JG 286 }
287
288 std::string AddMessage::as_string()
289 {
2c515f 290     if (mapOrderSide.empty()) initialise();
JG 291     return "{\"type\": \"ADD\", \"product\": \"" + this->product +
d2cfd3 292            "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" +
JG 293            mapOrderSide[this->side] +
294            "\", \"volume\": " + std::to_string(this->volume) + "}";
16b655 295 }
JG 296
297 AddedMessage::AddedMessage(MessageTypes type, std::string product,
298                            std::string id, book::OrderSideEnum side,
299                            double price, uint64_t filled, uint64_t resting,
300                            uint64_t sequence, double timestamp)
2c515f 301     : FromExchange(type, product, sequence, timestamp), id(id), side(side),
JG 302       price(price), filled(filled), resting(resting)
16b655 303 {
JG 304 }
305
6bdd28 306 std::string AddedMessage::as_string()
JG 307 {
308     return "{\"type\": \"ADDED\", \"product\": \"" + this->product +
d2cfd3 309            "\", \"product\": \"" + this->id + "\" \"side\": \"" +
JG 310            mapOrderSide[this->side] +
311            "\", \"price\": " + std::to_string(this->price) +
312            "\"filled\": " + std::to_string(this->filled) +
313            ", \"resting\": " + std::to_string(this->resting) +
314            ", \"sequence\": " + std::to_string(this->sequence) +
315            ", \"timestamp\":" + std::to_string(this->timestamp) + "}";
6bdd28 316 }
JG 317
16b655 318 DeleteMessage::DeleteMessage(MessageTypes type, std::string product,
JG 319                              std::string id)
2c515f 320     : ToExchange(type, product), id(id)
16b655 321 {
JG 322 }
323
324 std::string DeleteMessage::as_string()
325 {
2c515f 326     if (mapOrderSide.empty()) initialise();
JG 327     return "{\"type\": \"DELETE\", \"product\": \"" + this->product +
d2cfd3 328            "\", \"id\": \"" + this->id + "\"}";
16b655 329 }
JG 330
331 DeletedMessage::DeletedMessage(MessageTypes type, std::string product,
332                                std::string id, book::OrderSideEnum side,
333                                uint64_t sequence, double timestamp)
2c515f 334     : FromExchange(type, product, sequence, timestamp), id(id), side(side)
16b655 335 {
JG 336 }
337
6bdd28 338 std::string DeletedMessage::as_string()
JG 339 {
340     return "{\"type\": \"DELETED\", \"product\": \"" + this->product +
d2cfd3 341            "\", \"product\": \"" + this->id + "\" \"side\": \"" +
JG 342            mapOrderSide[this->side] +
343            ", \"sequence\": " + std::to_string(this->sequence) +
344            ", \"timestamp\":" + std::to_string(this->timestamp) + "}";
6bdd28 345 }
JG 346
16b655 347 RejectMessage::RejectMessage(MessageTypes type, std::string product,
JG 348                              std::string error, uint64_t sequence,
349                              double timestamp)
2c515f 350     : FromExchange(type, product, sequence, timestamp), error(error)
16b655 351 {
JG 352 }
353
6bdd28 354 std::string RejectMessage::as_string()
JG 355 {
356     return "{\"type\": \"REJECT\", \"product\": \"" + this->product =
d2cfd3 357                "\", \"error\": \"" + this->error +
JG 358                "\", \"sequence\": " + std::to_string(this->sequence) +
359                ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
6bdd28 360 }
JG 361
16b655 362 TradeMessage::TradeMessage(MessageTypes type, std::string product, double price,
JG 363                            uint64_t volume, std::string buyer,
364                            std::string seller, TradeTypeEnum tradeType,
365                            std::string passiveOrder,
366                            uint64_t passiveOrderRemaining, uint64_t sequence,
367                            double timestamp)
2c515f 368     : FromExchange(type, product, sequence, timestamp), price(price),
JG 369       volume(volume), buyer(buyer), seller(seller), tradeType(tradeType),
370       passiveOrder(passiveOrder), passiveOrderRemaining(passiveOrderRemaining)
16b655 371 {
JG 372 }
373
374 BrokerRequest::BrokerRequest(MessageTypes type, std::string product,
375                              double price, book::OrderSideEnum side,
376                              uint64_t volume, std::string counterparty)
2c515f 377     : Broker(type, product, price, side, volume, counterparty)
16b655 378 {
JG 379 }
380
381 BrokerAck::BrokerAck(MessageTypes type, std::string product, double price,
382                      book::OrderSideEnum side, uint64_t volume,
383                      std::string counterparty, std::string id,
384                      std::string brokerTradeStatus, std::string owner)
2c515f 385     : Broker(type, product, price, side, volume, counterparty), id(id),
JG 386       brokerTradeStatus(brokerTradeStatus), owner(owner)
16b655 387 {
JG 388 }
389
390 BrokerConfirm::BrokerConfirm(MessageTypes type, std::string product,
391                              double price, book::OrderSideEnum side,
392                              uint64_t volume, std::string counterparty,
393                              std::string id)
2c515f 394     : Broker(type, product, price, side, volume, counterparty), id(id)
16b655 395 {
JG 396 }
397 } // namespace json