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