Joel Grunbaum
2022-01-10 6bdd28a09c589cf631fce948476d48e9375f72a0
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 {
6bdd28 52     std::string message = order.as_string();
2c515f 53     return send(message);
16b655 54 }
JG 55
6926be 56 json::Message* deleteOrder(json::DeleteMessage& order)
16b655 57 {
6bdd28 58     std::string message = order.as_string();
2c515f 59     return send(message);
16b655 60 }
JG 61
62 void handleMessage(std::unordered_map<std::string, book::Book>& bs,
63                    json::Message* message)
64 {
2c515f 65     if (mapAnnounce.empty()) initialise();
JG 66     switch (message->type) {
67     case json::FUTURE_TYPE:
68     case json::SPREAD_TYPE:
69     case json::CALL_TYPE:
70     case json::PUT_TYPE:
71         announce(bs, dynamic_cast<json::AnnounceMessage*>(message));
72         break;
73     case json::SETTLEMENT:
74         settle(bs, dynamic_cast<json::SettleMessage*>(message));
75         break;
76     case json::ADDED:
77         addedOrder(bs, dynamic_cast<json::AddedMessage*>(message));
78         break;
79     case json::DELETED:
80         deletedOrder(bs, dynamic_cast<json::DeletedMessage*>(message));
81         break;
82     case json::TRADE:
83         tradeOrder(bs, dynamic_cast<json::TradeMessage*>(message));
84         break;
85     case json::BROKER_REQUEST:
86     case json::BROKER_ACK:
87     case json::BROKER_CONFIRM:
88         broker(bs, dynamic_cast<json::Broker*>(message));
89         break;
90     default:;
91     }
16b655 92 }
JG 93
94 void announce(std::unordered_map<std::string, book::Book>& bs,
95               json::AnnounceMessage* message)
96 {
2c515f 97     bs[message->product] =
JG 98         book::Book(mapAnnounce[message->type], message->product,
99                    message->stationId, message->unit, message->expiry,
100                    message->aggFee, message->pasFee, message->broFee);
16b655 101 }
JG 102 void settle(std::unordered_map<std::string, book::Book>& bs,
103             json::SettleMessage* message)
104 {
2c515f 105     bs.erase(message->product);
16b655 106 }
JG 107 void addedOrder(std::unordered_map<std::string, book::Book>& bs,
108                 json::AddedMessage* message)
109 {
2c515f 110     if (message->side == book::Buy) {
JG 111         book::Order t(message->price, book::Buy, message->resting,
112                       message->timestamp, message->id);
113         bs[message->product].bid(t);
114     } else {
115         book::Order t(message->price, book::Sell, message->resting,
116                       message->timestamp, message->id);
117         bs[message->product].ask(t);
118     }
16b655 119 }
JG 120 void deletedOrder(std::unordered_map<std::string, book::Book>& bs,
121                   json::DeletedMessage* message)
122 {
2c515f 123     if (message->side == book::Buy) {
JG 124         for (std::size_t i = 0; i < bs[message->product].bidSide.size(); i++) {
125             if (bs[message->product].bidSide[i].id == message->id) {
126                 bs[message->product].bidSide[i] =
127                     bs[message->product].bidSide.back();
128                 bs[message->product].bidSide.pop_back();
129                 std::make_heap(bs[message->product].bidSide.begin(),
130                                bs[message->product].bidSide.end(),
131                                std::less<book::Level>());
132             }
133         }
134     } else {
135         for (std::size_t i = 0; i < bs[message->product].askSide.size(); i++) {
136             if (bs[message->product].askSide[i].id == message->id) {
137                 bs[message->product].askSide[i] =
138                     bs[message->product].askSide.back();
139                 bs[message->product].askSide.pop_back();
140                 std::make_heap(bs[message->product].askSide.begin(),
141                                bs[message->product].askSide.end(),
142                                std::greater<book::Level>());
143             }
144         }
16b655 145     }
JG 146 }
147 void tradeOrder(std::unordered_map<std::string, book::Book>& bs,
148                 json::TradeMessage* message)
149 {
2c515f 150     if (message->tradeType == json::BUY_AGGRESSOR) {
JG 151         book::Order t(message->price, book::Buy, message->volume,
152                       message->timestamp, message->passiveOrder);
153         bs[message->product].bid(t);
154     } else {
155         book::Order t(message->price, book::Sell, message->volume,
156                       message->timestamp, message->passiveOrder);
157         bs[message->product].ask(t);
158     }
16b655 159 }
JG 160 void broker(std::unordered_map<std::string, book::Book>& bs,
161             json::Broker* message)
162 {
163 }
164
6926be 165 json::Message* send(std::string& message)
16b655 166 {
6bdd28 167     httplib::MultipartFormDataItems a = {{"message", message, "", ""},
JG 168         {"username", USER, "", ""},
169         {"password", PASS, "", ""}};
170     auto res = cli.Post("/execution", a);
171     std::string b = res->body;
172     std::queue<json::Message*> c = json::parse(b);
173     return c.front();
16b655 174 }
JG 175
176 } // namespace protocol