Joel Grunbaum
2022-01-10 2c515f0de70ad675b5f5d25b6a496d67d8dc0463
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);
61 TradeMessage* trade(rapidjson::Value& d);
62 BrokerRequest* brokerReq(rapidjson::Value& d);
63 BrokerAck* brokerAck(rapidjson::Value& d);
64 BrokerConfirm* brokerCon(rapidjson::Value& d);
16b655 65
b4cf0a 66 std::queue<Message*> parse(std::string& str)
16b655 67 {
2c515f 68     std::queue<Message*> out;
JG 69     rapidjson::Document d;
70     d.Parse(str.c_str());
71     if (d.IsArray()) {
72         for (rapidjson::SizeType i = 0; i < d.Size(); i++) {
73             out.push(parseSingle(d[i]));
74         }
75     } else {
76         out.push(parseSingle(d));
b4cf0a 77     }
2c515f 78     return out;
16b655 79 }
JG 80
b4cf0a 81 Message* parseSingle(rapidjson::Value& d)
16b655 82 {
2c515f 83     if (mapTypes.empty()) {
JG 84         initialise();
85     }
86     Message* out;
87     switch (mapTypes[d["type"].GetString()]) {
88     case FUTURE_TYPE:
89     case SPREAD_TYPE:
90     case CALL_TYPE:
91     case PUT_TYPE:
92         out = announce(d);
93         break;
94     case SETTLEMENT:
95         out = settle(d);
96         break;
97     case ADDED:
98         out = added(d);
99         break;
100     case DELETED:
101         out = deleted(d);
102         break;
103     case TRADE:
104         out = trade(d);
105         break;
106     case BROKER_REQUEST:
107         out = brokerReq(d);
108         break;
109     case BROKER_ACK:
110         out = brokerAck(d);
111         break;
112     case BROKER_CONFIRM:
113         out = brokerCon(d);
114         break;
115     default:
116         out = new Message(NONE, "");
117         break;
118     }
119     return out;
16b655 120 }
JG 121
b4cf0a 122 AnnounceMessage* announce(rapidjson::Value& d)
16b655 123 {
2c515f 124     // std::stringstream expiryStream(d["expiry"].GetString());
JG 125     std::chrono::nanoseconds exp_time(0);
126     // expiryStream >>
127     // date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken
128     return new AnnounceMessage(
129         mapTypes[d["type"].GetString()], d["product"].GetString(),
130         d["stationId"].GetInt(), d["stationName"].GetString(),
131         d["unit"].GetString(), exp_time, d["aggressiveFee"].GetDouble(),
132         d["passiveFee"].GetDouble(), d["brokerFee"].GetDouble(),
133         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 134 }
JG 135
b4cf0a 136 SettleMessage* settle(rapidjson::Value& d)
16b655 137 {
2c515f 138     // std::stringstream expiryStream(d["expiry"].GetString());
JG 139     std::chrono::nanoseconds exp_time(0);
140     // expiryStream >> date::parse("%Y-%m-%d %H:%M%z", exp_time);
141     return new SettleMessage(
142         mapTypes[d["type"].GetString()], d["product"].GetString(),
143         d["stationName"].GetString(), exp_time, d["price"].GetDouble(),
144         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 145 }
JG 146
b4cf0a 147 AddedMessage* added(rapidjson::Value& d)
16b655 148 {
2c515f 149     return new AddedMessage(
JG 150         mapTypes[d["type"].GetString()], d["product"].GetString(),
151         d["id"].GetString(), mapOrder[d["side"].GetString()],
152         d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(),
153         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 154 }
JG 155
b4cf0a 156 DeletedMessage* deleted(rapidjson::Value& d)
16b655 157 {
2c515f 158     return new DeletedMessage(
JG 159         mapTypes[d["type"].GetString()], d["product"].GetString(),
160         d["id"].GetString(), mapOrder[d["side"].GetString()],
161         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 162 }
JG 163
b4cf0a 164 TradeMessage* trade(rapidjson::Value& d)
16b655 165 {
2c515f 166     return new TradeMessage(
JG 167         mapTypes[d["type"].GetString()], d["product"].GetString(),
168         d["price"].GetDouble(), d["volume"].GetInt(), d["buyer"].GetString(),
169         d["seller"].GetString(), mapTrade[d["tradeType"].GetString()],
170         d["passiveOrder"].GetString(), d["passiveOrderRemaining"].GetInt(),
171         d["sequence"].GetInt(), d["timestamp"].GetDouble());
16b655 172 }
JG 173
b4cf0a 174 BrokerRequest* brokerReq(rapidjson::Value& d)
16b655 175 {
2c515f 176     return new BrokerRequest(
JG 177         mapTypes[d["type"].GetString()], d["product"].GetString(),
178         d["price"].GetDouble(), mapOrder[d["side"].GetString()],
179         d["volume"].GetInt(), d["counterparty"].GetString());
16b655 180 }
JG 181
b4cf0a 182 BrokerAck* brokerAck(rapidjson::Value& d)
16b655 183 {
2c515f 184     return new BrokerAck(mapTypes[d["type"].GetString()],
JG 185                          d["product"].GetString(), d["price"].GetDouble(),
186                          mapOrder[d["side"].GetString()], d["volume"].GetInt(),
187                          d["counterparty"].GetString(), d["id"].GetString(),
188                          d["brokerTradeStatus"].GetString(),
189                          d["owner"].GetString());
16b655 190 }
b4cf0a 191 BrokerConfirm* brokerCon(rapidjson::Value& d)
16b655 192 {
2c515f 193     return new BrokerConfirm(
JG 194         mapTypes[d["type"].GetString()], d["product"].GetString(),
195         d["price"].GetDouble(), mapOrder[d["side"].GetString()],
196         d["volume"].GetInt(), d["counterparty"].GetString(),
197         d["id"].GetString());
16b655 198 }
JG 199
200 Message::Message() : type(NONE), product("error") {}
201
202 Message::Message(MessageTypes types, std::string product)
2c515f 203     : type(types), product(product)
16b655 204 {
JG 205 }
206
207 FromExchange::FromExchange(MessageTypes type, std::string product,
208                            uint64_t sequence, double timestamp)
2c515f 209     : Message(type, product), sequence(sequence), timestamp(timestamp)
16b655 210 {
JG 211 }
212
213 ToExchange::ToExchange(MessageTypes type, std::string product)
2c515f 214     : Message(type, product){};
16b655 215
JG 216 Broker::Broker(MessageTypes type, std::string product, double price,
217                book::OrderSideEnum side, uint64_t volume,
218                std::string counterparty)
2c515f 219     : Message(type, product), price(price), side(side), volume(volume),
JG 220       counterparty(counterparty)
16b655 221 {
JG 222 }
223
224 AnnounceMessage::AnnounceMessage(MessageTypes type, std::string product,
b4cf0a 225                                  int stationId, std::string stationName,
16b655 226                                  std::string unit,
JG 227                                  std::chrono::nanoseconds expiry, double aggFee,
228                                  double pasFee, double broFee,
229                                  uint64_t sequence, double timestamp)
2c515f 230     : FromExchange(type, product, sequence, timestamp), stationId(stationId),
JG 231       stationName(stationName), unit(unit), expiry(expiry), aggFee(aggFee),
232       pasFee(pasFee), broFee(broFee)
16b655 233 {
JG 234 }
235
236 SettleMessage::SettleMessage(MessageTypes type, std::string product,
237                              std::string stationName,
238                              std::chrono::nanoseconds expiry, double price,
239                              uint64_t sequence, double timestamp)
2c515f 240     : FromExchange(type, product, sequence, timestamp),
JG 241       stationName(stationName), expiry(expiry), price(price)
16b655 242 {
JG 243 }
244
245 AddMessage::AddMessage(MessageTypes type, std::string product, double price,
246                        book::OrderSideEnum side, uint64_t volume)
2c515f 247     : ToExchange(type, product), price(price), side(side), volume(volume)
16b655 248 {
JG 249 }
250
251 std::string AddMessage::as_string()
252 {
2c515f 253     if (mapOrderSide.empty()) initialise();
JG 254     return "{\"type\": \"ADD\", \"product\": \"" + this->product +
255            "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" +
256            mapOrderSide[this->side] +
257            "\", \"volume\": " + std::to_string(this->volume) + "}";
16b655 258 }
JG 259
260 AddedMessage::AddedMessage(MessageTypes type, std::string product,
261                            std::string id, book::OrderSideEnum side,
262                            double price, uint64_t filled, uint64_t resting,
263                            uint64_t sequence, double timestamp)
2c515f 264     : FromExchange(type, product, sequence, timestamp), id(id), side(side),
JG 265       price(price), filled(filled), resting(resting)
16b655 266 {
JG 267 }
268
269 DeleteMessage::DeleteMessage(MessageTypes type, std::string product,
270                              std::string id)
2c515f 271     : ToExchange(type, product), id(id)
16b655 272 {
JG 273 }
274
275 std::string DeleteMessage::as_string()
276 {
2c515f 277     if (mapOrderSide.empty()) initialise();
JG 278     return "{\"type\": \"DELETE\", \"product\": \"" + this->product +
279            "\", \"id\": \"" + this->id + "\"}";
16b655 280 }
JG 281
282 DeletedMessage::DeletedMessage(MessageTypes type, std::string product,
283                                std::string id, book::OrderSideEnum side,
284                                uint64_t sequence, double timestamp)
2c515f 285     : FromExchange(type, product, sequence, timestamp), id(id), side(side)
16b655 286 {
JG 287 }
288
289 RejectMessage::RejectMessage(MessageTypes type, std::string product,
290                              std::string error, uint64_t sequence,
291                              double timestamp)
2c515f 292     : FromExchange(type, product, sequence, timestamp), error(error)
16b655 293 {
JG 294 }
295
296 TradeMessage::TradeMessage(MessageTypes type, std::string product, double price,
297                            uint64_t volume, std::string buyer,
298                            std::string seller, TradeTypeEnum tradeType,
299                            std::string passiveOrder,
300                            uint64_t passiveOrderRemaining, uint64_t sequence,
301                            double timestamp)
2c515f 302     : FromExchange(type, product, sequence, timestamp), price(price),
JG 303       volume(volume), buyer(buyer), seller(seller), tradeType(tradeType),
304       passiveOrder(passiveOrder), passiveOrderRemaining(passiveOrderRemaining)
16b655 305 {
JG 306 }
307
308 BrokerRequest::BrokerRequest(MessageTypes type, std::string product,
309                              double price, book::OrderSideEnum side,
310                              uint64_t volume, std::string counterparty)
2c515f 311     : Broker(type, product, price, side, volume, counterparty)
16b655 312 {
JG 313 }
314
315 BrokerAck::BrokerAck(MessageTypes type, std::string product, double price,
316                      book::OrderSideEnum side, uint64_t volume,
317                      std::string counterparty, std::string id,
318                      std::string brokerTradeStatus, std::string owner)
2c515f 319     : Broker(type, product, price, side, volume, counterparty), id(id),
JG 320       brokerTradeStatus(brokerTradeStatus), owner(owner)
16b655 321 {
JG 322 }
323
324 BrokerConfirm::BrokerConfirm(MessageTypes type, std::string product,
325                              double price, book::OrderSideEnum side,
326                              uint64_t volume, std::string counterparty,
327                              std::string id)
2c515f 328     : Broker(type, product, price, side, volume, counterparty), id(id)
16b655 329 {
JG 330 }
331 } // namespace json