Joel Grunbaum
2022-01-10 2c515f0de70ad675b5f5d25b6a496d67d8dc0463
commit | author | age
16b655 1 #include "protocol.hpp"
JG 2
3 #include "book.hpp"
4 #include "cpp-httplib/httplib.h"
5 #include "json.hpp"
6 #include "secrets.hpp"
7
8 #include <chrono>
9 #include <iostream>
10 #include <queue>
11 #include <sstream>
12 #include <string>
13 #include <unordered_map>
14
15 namespace protocol
16 {
17 static std::unordered_map<json::MessageTypes, book::ProductTypeEnum>
2c515f 18     mapAnnounce;
16b655 19 std::string server = std::string(HOST) + ":" + std::string(PORT);
JG 20 httplib::Client cli("http://" + server);
21
22 void initialise()
23 {
2c515f 24     mapAnnounce = {{json::FUTURE_TYPE, book::FUTURE},
JG 25                    {json::SPREAD_TYPE, book::SPREAD},
26                    {json::CALL_TYPE, book::CALL},
27                    {json::PUT_TYPE, book::PUT}};
16b655 28 }
JG 29
30 std::unordered_map<std::string, book::Book> recoverBook()
31 {
2c515f 32     std::unordered_map<std::string, book::Book> bs;
JG 33     // std::ifstream sampleFile("../data.test");
34     // std::stringstream ss;
35     // ss << sampleFile.rdbuf();
36     httplib::Client cli("http://" + server);
37     auto res = cli.Get("/recover");
38     std::string l;
39     // l = ss.str();
40     l = res->body;
41     std::queue<json::Message*> a(json::parse(l));
42     while (!a.empty()) {
43         protocol::handleMessage(bs, a.front());
44         delete a.front();
45         a.pop();
46     }
47     return bs;
16b655 48 }
JG 49
6926be 50 json::Message* addOrder(json::AddMessage& order)
16b655 51 {
2c515f 52     std::string message = "{\"message\": " + order.as_string() + ", " +
JG 53                           "\"username\": \"" + std::string(USER) +
54                           "\", \"password\": \"" + std::string(PASS) + "\"}";
55     return send(message);
16b655 56 }
JG 57
6926be 58 json::Message* deleteOrder(json::DeleteMessage& order)
16b655 59 {
2c515f 60     std::string message = "{\"message\": " + order.as_string() +
JG 61                           ", \"username\": \"" + std::string(USER) +
62                           "\", \"password\": \"" + std::string(PASS) + "\"}";
63     return send(message);
16b655 64 }
JG 65
66 void handleMessage(std::unordered_map<std::string, book::Book>& bs,
67                    json::Message* message)
68 {
2c515f 69     if (mapAnnounce.empty()) initialise();
JG 70     switch (message->type) {
71     case json::FUTURE_TYPE:
72     case json::SPREAD_TYPE:
73     case json::CALL_TYPE:
74     case json::PUT_TYPE:
75         announce(bs, dynamic_cast<json::AnnounceMessage*>(message));
76         break;
77     case json::SETTLEMENT:
78         settle(bs, dynamic_cast<json::SettleMessage*>(message));
79         break;
80     case json::ADDED:
81         addedOrder(bs, dynamic_cast<json::AddedMessage*>(message));
82         break;
83     case json::DELETED:
84         deletedOrder(bs, dynamic_cast<json::DeletedMessage*>(message));
85         break;
86     case json::TRADE:
87         tradeOrder(bs, dynamic_cast<json::TradeMessage*>(message));
88         break;
89     case json::BROKER_REQUEST:
90     case json::BROKER_ACK:
91     case json::BROKER_CONFIRM:
92         broker(bs, dynamic_cast<json::Broker*>(message));
93         break;
94     default:;
95     }
16b655 96 }
JG 97
98 void announce(std::unordered_map<std::string, book::Book>& bs,
99               json::AnnounceMessage* message)
100 {
2c515f 101     bs[message->product] =
JG 102         book::Book(mapAnnounce[message->type], message->product,
103                    message->stationId, message->unit, message->expiry,
104                    message->aggFee, message->pasFee, message->broFee);
16b655 105 }
JG 106 void settle(std::unordered_map<std::string, book::Book>& bs,
107             json::SettleMessage* message)
108 {
2c515f 109     bs.erase(message->product);
16b655 110 }
JG 111 void addedOrder(std::unordered_map<std::string, book::Book>& bs,
112                 json::AddedMessage* message)
113 {
2c515f 114     if (message->side == book::Buy) {
JG 115         book::Order t(message->price, book::Buy, message->resting,
116                       message->timestamp, message->id);
117         bs[message->product].bid(t);
118     } else {
119         book::Order t(message->price, book::Sell, message->resting,
120                       message->timestamp, message->id);
121         bs[message->product].ask(t);
122     }
16b655 123 }
JG 124 void deletedOrder(std::unordered_map<std::string, book::Book>& bs,
125                   json::DeletedMessage* message)
126 {
2c515f 127     if (message->side == book::Buy) {
JG 128         for (std::size_t i = 0; i < bs[message->product].bidSide.size(); i++) {
129             if (bs[message->product].bidSide[i].id == message->id) {
130                 bs[message->product].bidSide[i] =
131                     bs[message->product].bidSide.back();
132                 bs[message->product].bidSide.pop_back();
133                 std::make_heap(bs[message->product].bidSide.begin(),
134                                bs[message->product].bidSide.end(),
135                                std::less<book::Level>());
136             }
137         }
138     } else {
139         for (std::size_t i = 0; i < bs[message->product].askSide.size(); i++) {
140             if (bs[message->product].askSide[i].id == message->id) {
141                 bs[message->product].askSide[i] =
142                     bs[message->product].askSide.back();
143                 bs[message->product].askSide.pop_back();
144                 std::make_heap(bs[message->product].askSide.begin(),
145                                bs[message->product].askSide.end(),
146                                std::greater<book::Level>());
147             }
148         }
16b655 149     }
JG 150 }
151 void tradeOrder(std::unordered_map<std::string, book::Book>& bs,
152                 json::TradeMessage* message)
153 {
2c515f 154     if (message->tradeType == json::BUY_AGGRESSOR) {
JG 155         book::Order t(message->price, book::Buy, message->volume,
156                       message->timestamp, message->passiveOrder);
157         bs[message->product].bid(t);
158     } else {
159         book::Order t(message->price, book::Sell, message->volume,
160                       message->timestamp, message->passiveOrder);
161         bs[message->product].ask(t);
162     }
16b655 163 }
JG 164 void broker(std::unordered_map<std::string, book::Book>& bs,
165             json::Broker* message)
166 {
167 }
168
6926be 169 json::Message* send(std::string& message)
16b655 170 {
2c515f 171     auto res = cli.Post("/execution", message, "text/plain");
JG 172     std::queue<json::Message*> a = json::parse(res->body);
173     return a.front();
16b655 174 }
JG 175
176 } // namespace protocol