#include "protocol.hpp"
|
|
#include "book.hpp"
|
#include "cpp-httplib/httplib.h"
|
#include "json.hpp"
|
#include "secrets.hpp"
|
|
#include <chrono>
|
#include <iostream>
|
#include <queue>
|
#include <sstream>
|
#include <string>
|
#include <unordered_map>
|
|
namespace protocol
|
{
|
static std::unordered_map<json::MessageTypes, book::ProductTypeEnum>
|
mapAnnounce;
|
std::string server = std::string(HOST) + ":" + std::string(PORT);
|
httplib::Client cli("http://" + server);
|
|
void initialise()
|
{
|
mapAnnounce = {{json::FUTURE_TYPE, book::FUTURE},
|
{json::SPREAD_TYPE, book::SPREAD},
|
{json::CALL_TYPE, book::CALL},
|
{json::PUT_TYPE, book::PUT}};
|
}
|
|
std::unordered_map<std::string, book::Book> recoverBook()
|
{
|
std::unordered_map<std::string, book::Book> bs;
|
std::ifstream sampleFile("../rec.log");
|
std::stringstream ss;
|
ss << sampleFile.rdbuf();
|
// httplib::Client cli("http://" + server);
|
// auto res = cli.Get("/recover");
|
std::string l;
|
l = ss.str();
|
std::queue<json::Message*> a(json::parseMany(l));
|
while (!a.empty()) {
|
protocol::handleMessage(bs, a.front());
|
delete a.front();
|
a.pop();
|
}
|
return bs;
|
}
|
|
void addOrder(json::AddMessage& order)
|
{
|
std::string message = "{\"message\": " + order.as_string() + ", " +
|
"\"username\": \"" + std::string(USER) +
|
"\", \"password\": \"" + std::string(PASS) + "\"}";
|
send(message);
|
}
|
|
void deleteOrder(json::DeleteMessage& order)
|
{
|
std::string message = "{\"message\": " + order.as_string() +
|
", \"username\": \"" + std::string(USER) +
|
"\", \"password\": \"" + std::string(PASS) + "\"}";
|
send(message);
|
}
|
|
void handleMessage(std::unordered_map<std::string, book::Book>& bs,
|
json::Message* message)
|
{
|
if (mapAnnounce.empty()) initialise();
|
json::AnnounceMessage* a = dynamic_cast<json::AnnounceMessage*>(message);
|
json::SettleMessage* b = dynamic_cast<json::SettleMessage*>(message);
|
json::AddedMessage* c = dynamic_cast<json::AddedMessage*>(message);
|
json::DeletedMessage* d = dynamic_cast<json::DeletedMessage*>(message);
|
json::TradeMessage* e = dynamic_cast<json::TradeMessage*>(message);
|
json::Broker* f = dynamic_cast<json::Broker*>(message);
|
switch (message->type) {
|
case json::FUTURE_TYPE:
|
case json::SPREAD_TYPE:
|
case json::CALL_TYPE:
|
case json::PUT_TYPE:
|
announce(bs, a);
|
break;
|
case json::SETTLEMENT:
|
settle(bs, dynamic_cast<json::SettleMessage*>(message));
|
break;
|
case json::ADDED:
|
addedOrder(bs, dynamic_cast<json::AddedMessage*>(message));
|
break;
|
case json::DELETED:
|
deletedOrder(bs, dynamic_cast<json::DeletedMessage*>(message));
|
break;
|
case json::TRADE:
|
tradeOrder(bs, dynamic_cast<json::TradeMessage*>(message));
|
break;
|
case json::BROKER_REQUEST:
|
case json::BROKER_ACK:
|
case json::BROKER_CONFIRM:
|
broker(bs, dynamic_cast<json::Broker*>(message));
|
break;
|
default:;
|
}
|
}
|
|
void announce(std::unordered_map<std::string, book::Book>& bs,
|
json::AnnounceMessage* message)
|
{
|
bs[message->product] =
|
book::Book(mapAnnounce[message->type], message->product,
|
message->stationId, message->unit, message->expiry,
|
message->aggFee, message->pasFee, message->broFee);
|
}
|
void settle(std::unordered_map<std::string, book::Book>& bs,
|
json::SettleMessage* message)
|
{
|
bs.erase(message->product);
|
}
|
void addedOrder(std::unordered_map<std::string, book::Book>& bs,
|
json::AddedMessage* message)
|
{
|
if (message->side == book::Buy) {
|
book::Order t(message->price, book::Buy, message->resting,
|
message->timestamp, message->id);
|
bs[message->product].bid(t);
|
} else {
|
book::Order t(message->price, book::Sell, message->resting,
|
message->timestamp, message->id);
|
bs[message->product].ask(t);
|
}
|
}
|
void deletedOrder(std::unordered_map<std::string, book::Book>& bs,
|
json::DeletedMessage* message)
|
{
|
if (message->side == book::Buy) {
|
for (auto i = bs[message->product].bidSide.begin();
|
i != bs[message->product].bidSide.end(); i++) {
|
if (i->id == message->id) {
|
bs[message->product].bidSide.erase(i);
|
std::make_heap(bs[message->product].bidSide.begin(),
|
bs[message->product].bidSide.end(),
|
std::less<book::Level>());
|
}
|
}
|
} else {
|
for (auto i = bs[message->product].askSide.begin();
|
i != bs[message->product].askSide.end(); i++) {
|
if (i->id == message->id) {
|
bs[message->product].askSide.erase(i);
|
std::make_heap(bs[message->product].askSide.begin(),
|
bs[message->product].askSide.end(),
|
std::greater<book::Level>());
|
}
|
}
|
}
|
}
|
void tradeOrder(std::unordered_map<std::string, book::Book>& bs,
|
json::TradeMessage* message)
|
{
|
if (message->tradeType == json::BUY_AGGRESSOR) {
|
book::Order t(message->price, book::Buy, message->volume,
|
message->timestamp, message->passiveOrder);
|
bs[message->product].bid(t);
|
} else {
|
book::Order t(message->price, book::Sell, message->volume,
|
message->timestamp, message->passiveOrder);
|
bs[message->product].ask(t);
|
}
|
}
|
void broker(std::unordered_map<std::string, book::Book>& bs,
|
json::Broker* message)
|
{
|
}
|
|
void send(std::string& message)
|
{
|
cli.Post("/execution", message, "text/plain");
|
}
|
|
} // namespace protocol
|