Joel Grunbaum
2022-01-09 b4cf0a2e71ad2c204925b33f9600dc720e25b827
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 {
31     mapTypes = {{"FUTURE", FUTURE_TYPE},
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}};
42
43     mapAnnounce = {{FUTURE_TYPE, book::FUTURE},
44                    {SPREAD_TYPE, book::SPREAD},
45                    {CALL_TYPE, book::CALL},
46                    {PUT_TYPE, book::PUT}};
47
48     mapOrder = {{"BUY", book::Buy}, {"SELL", book::Sell}};
49
50     mapTrade = {{"BUY_AGGRESSOR", BUY_AGGRESSOR},
51                 {"SELL_AGGRESSOR", SELL_AGGRESSOR}};
52
53     mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}};
54 }
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 {
JG 68     std::queue<Message*> out;
b4cf0a 69     rapidjson::Document d;
JG 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));
16b655 77     }
JG 78     return out;
79 }
80
b4cf0a 81 Message* parseSingle(rapidjson::Value& d)
16b655 82 {
JG 83     if (mapTypes.empty()) {
84     initialise();
85     }
86     Message* out;
b4cf0a 87     switch (mapTypes[d["type"].GetString()]) {
16b655 88     case FUTURE_TYPE:
JG 89     case SPREAD_TYPE:
90     case CALL_TYPE:
91     case PUT_TYPE:
b4cf0a 92     out = announce(d);
16b655 93     break;
JG 94     case SETTLEMENT:
b4cf0a 95     out = settle(d);
16b655 96     break;
JG 97     case ADDED:
b4cf0a 98     out = added(d);
16b655 99     break;
JG 100     case DELETED:
b4cf0a 101     out = deleted(d);
16b655 102     break;
JG 103     case TRADE:
b4cf0a 104     out = trade(d);
16b655 105     break;
JG 106     case BROKER_REQUEST:
b4cf0a 107     out = brokerReq(d);
16b655 108     break;
JG 109     case BROKER_ACK:
b4cf0a 110     out = brokerAck(d);
16b655 111     break;
JG 112     case BROKER_CONFIRM:
b4cf0a 113     out = brokerCon(d);
16b655 114     break;
JG 115     default:
116     out = new Message(NONE, "");
117     break;
118     }
119     return out;
120 }
121
b4cf0a 122 AnnounceMessage* announce(rapidjson::Value& d)
16b655 123 {
b4cf0a 124     // std::stringstream expiryStream(d["expiry"].GetString());
6926be 125     std::chrono::nanoseconds exp_time(0);
JG 126     // expiryStream >>
b4cf0a 127     // date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken
16b655 128     return new AnnounceMessage(
b4cf0a 129     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
b4cf0a 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);
16b655 141     return new SettleMessage(
b4cf0a 142     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
JG 149     return new AddedMessage(
b4cf0a 150     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
JG 158     return new DeletedMessage(
b4cf0a 159     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
JG 166     return new TradeMessage(
b4cf0a 167     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
JG 176     return new BrokerRequest(
b4cf0a 177     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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 {
b4cf0a 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 {
JG 193     return new BrokerConfirm(
b4cf0a 194     mapTypes[d["type"].GetString()], d["product"].GetString(),
JG 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)
203     : type(types), product(product)
204 {
205 }
206
207 FromExchange::FromExchange(MessageTypes type, std::string product,
208                            uint64_t sequence, double timestamp)
209     : Message(type, product), sequence(sequence), timestamp(timestamp)
210 {
211 }
212
213 ToExchange::ToExchange(MessageTypes type, std::string product)
214     : Message(type, product){};
215
216 Broker::Broker(MessageTypes type, std::string product, double price,
217                book::OrderSideEnum side, uint64_t volume,
218                std::string counterparty)
219     : Message(type, product), price(price), side(side), volume(volume),
220       counterparty(counterparty)
221 {
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)
230     : FromExchange(type, product, sequence, timestamp), stationId(stationId),
231       stationName(stationName), unit(unit), expiry(expiry), aggFee(aggFee),
232       pasFee(pasFee), broFee(broFee)
233 {
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)
240     : FromExchange(type, product, sequence, timestamp),
241       stationName(stationName), expiry(expiry), price(price)
242 {
243 }
244
245 AddMessage::AddMessage(MessageTypes type, std::string product, double price,
246                        book::OrderSideEnum side, uint64_t volume)
247     : ToExchange(type, product), price(price), side(side), volume(volume)
248 {
249 }
250
251 std::string AddMessage::as_string()
252 {
253     if (mapOrderSide.empty()) initialise();
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) + "}";
258 }
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)
264     : FromExchange(type, product, sequence, timestamp), id(id), side(side),
265       price(price), filled(filled), resting(resting)
266 {
267 }
268
269 DeleteMessage::DeleteMessage(MessageTypes type, std::string product,
270                              std::string id)
271     : ToExchange(type, product), id(id)
272 {
273 }
274
275 std::string DeleteMessage::as_string()
276 {
277     if (mapOrderSide.empty()) initialise();
278     return "{\"type\": \"DELETE\", \"product\": \"" + this->product +
279            "\", \"id\": \"" + this->id + "\"}";
280 }
281
282 DeletedMessage::DeletedMessage(MessageTypes type, std::string product,
283                                std::string id, book::OrderSideEnum side,
284                                uint64_t sequence, double timestamp)
285     : FromExchange(type, product, sequence, timestamp), id(id), side(side)
286 {
287 }
288
289 RejectMessage::RejectMessage(MessageTypes type, std::string product,
290                              std::string error, uint64_t sequence,
291                              double timestamp)
292     : FromExchange(type, product, sequence, timestamp), error(error)
293 {
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)
302     : FromExchange(type, product, sequence, timestamp), price(price),
303       volume(volume), buyer(buyer), seller(seller), tradeType(tradeType),
304       passiveOrder(passiveOrder), passiveOrderRemaining(passiveOrderRemaining)
305 {
306 }
307
308 BrokerRequest::BrokerRequest(MessageTypes type, std::string product,
309                              double price, book::OrderSideEnum side,
310                              uint64_t volume, std::string counterparty)
311     : Broker(type, product, price, side, volume, counterparty)
312 {
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)
319     : Broker(type, product, price, side, volume, counterparty), id(id),
320       brokerTradeStatus(brokerTradeStatus), owner(owner)
321 {
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)
328     : Broker(type, product, price, side, volume, counterparty), id(id)
329 {
330 }
331 } // namespace json