From 128c6d51ec8c70e230dc86b100cb887ba3f0378d Mon Sep 17 00:00:00 2001
From: Joel Grunbaum <joelgrun@gmail.com>
Date: Thu, 20 Jan 2022 07:00:50 +0000
Subject: [PATCH] Secrets to macros and c string concat at compile time

---
 json.cpp |  162 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 130 insertions(+), 32 deletions(-)

diff --git a/json.cpp b/json.cpp
index dfcbbf4..3e1ad07 100644
--- a/json.cpp
+++ b/json.cpp
@@ -1,6 +1,5 @@
 #include "json.hpp"
 #include "book.hpp"
-#include "date/include/date/date.h"
 #include "protocol.hpp"
 #include "rapidjson/include/rapidjson/document.h"
 #include "rapidjson/include/rapidjson/rapidjson.h"
@@ -25,6 +24,8 @@
 static std::unordered_map<std::string, book::OrderSideEnum> mapOrder;
 static std::unordered_map<std::string, TradeTypeEnum> mapTrade;
 static std::unordered_map<book::OrderSideEnum, std::string> mapOrderSide;
+static std::unordered_map<MessageTypes, std::string> mapAStr;
+static std::unordered_map<TradeTypeEnum, std::string> mapTTStr;
 
 void initialise()
 {
@@ -52,6 +53,15 @@
 	            {"BROKER_TRADE", BROKER_TRADE}};
 
 	mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}};
+
+	mapAStr = {{FUTURE_TYPE, "FUTURE"},
+	           {SPREAD_TYPE, "SPREAD"},
+	           {CALL_TYPE, "CALL"},
+	           {PUT_TYPE, "PUT"}};
+
+	mapTTStr = {{BUY_AGGRESSOR, "BUY_AGGRESSOR"},
+	            {SELL_AGGRESSOR, "SELL_AGGRESSOR"},
+	            {BROKER_TRADE, "BROKER_TRADE"}};
 }
 
 Message* parseSingle(rapidjson::Value& d);
@@ -65,6 +75,8 @@
 BrokerAck* brokerAck(rapidjson::Value& d);
 BrokerConfirm* brokerCon(rapidjson::Value& d);
 ErrorMessage* error(rapidjson::Value& d);
+
+std::chrono::seconds parseTime(std::string& s);
 
 std::queue<Message*> parse(std::string& str)
 {
@@ -126,12 +138,21 @@
 	return out;
 }
 
+std::chrono::seconds parseTime(std::string& s)
+{
+	return std::chrono::hours{std::stoi(s.substr(0, 4)) * 24 * 30 * 12} +
+	       std::chrono::hours{std::stoi(s.substr(5, 2)) * 24 * 30} +
+	       std::chrono::hours{std::stoi(s.substr(8, 2)) * 24} +
+	       std::chrono::hours{std::stoi(s.substr(11, 2))} +
+	       std::chrono::minutes{std::stoi(s.substr(14, 2))} +
+	       std::chrono::hours{std::stoi(s.substr(16, 5))};
+}
+
 AnnounceMessage* announce(rapidjson::Value& d)
 {
-	// std::stringstream expiryStream(d["expiry"].GetString());
+	std::string es = d["expiry"].GetString();
 	std::chrono::nanoseconds exp_time(0);
-	// expiryStream >>
-	// date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken
+	exp_time = parseTime(es);
 	return new AnnounceMessage(
 		mapTypes[d["type"].GetString()], d["product"].GetString(),
 		d["stationId"].GetInt(), d["stationName"].GetString(),
@@ -142,9 +163,9 @@
 
 SettleMessage* settle(rapidjson::Value& d)
 {
-	// std::stringstream expiryStream(d["expiry"].GetString());
 	std::chrono::nanoseconds exp_time(0);
-	// expiryStream >> date::parse("%Y-%m-%d %H:%M%z", exp_time);
+	std::string es = d["expiry"].GetString();
+	exp_time = parseTime(es);
 	return new SettleMessage(
 		mapTypes[d["type"].GetString()], d["product"].GetString(),
 		d["stationName"].GetString(), exp_time, d["price"].GetDouble(),
@@ -153,11 +174,12 @@
 
 AddedMessage* added(rapidjson::Value& d)
 {
-	return new AddedMessage(
-		mapTypes[d["type"].GetString()], d["product"].GetString(),
-		d["id"].GetString(), mapOrder[d["side"].GetString()],
-		d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(),
-		d["sequence"].GetInt(), d["timestamp"].GetDouble());
+	return new AddedMessage(mapTypes[d["type"].GetString()],
+	                        d["product"].GetString(), d["id"].GetString(),
+	                        mapOrder[d["side"].GetString()],
+	                        d["price"].GetDouble(), d["filled"].GetInt(),
+	                        d["resting"].GetInt(), d["owner"].GetString(),
+	                        d["sequence"].GetInt(), d["timestamp"].GetDouble());
 }
 
 DeletedMessage* deleted(rapidjson::Value& d)
@@ -260,6 +282,20 @@
 {
 }
 
+std::string AnnounceMessage::as_string()
+{
+	return "{\"type\": \"" + mapAStr[this->type] =
+	           "\", \"product\": \"" + this->product +
+	           "\", \"stationId\": " + std::to_string(this->stationId) +
+	           "\", \"stationName\": \"" + this->stationName +
+	           "\", \"unit\": \"" + this->unit +
+	           "\", \"expiry\": " + std::to_string(this->expiry.count()) +
+	           ", \"aggressiveFee\": " + std::to_string(this->aggFee) +
+	           ", \"passiveFee\": " + std::to_string(this->pasFee) +
+	           ", \"sequence\": " + std::to_string(this->sequence) +
+	           ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
+}
+
 SettleMessage::SettleMessage(MessageTypes type, std::string product,
                              std::string stationName,
                              std::chrono::nanoseconds expiry, double price,
@@ -267,6 +303,17 @@
 	: FromExchange(type, product, sequence, timestamp),
 	  stationName(stationName), expiry(expiry), price(price)
 {
+}
+
+std::string SettleMessage::as_string()
+{
+	return "{\"type\": \"" + mapAStr[this->type] =
+	           "\", \"product\": \"" + this->product +
+	           "\", \"stationName\": \"" + this->stationName +
+	           "\", \"expiry\": " + std::to_string(this->expiry.count()) +
+	           ", \"price\": " + std::to_string(this->price) +
+	           ", \"sequence\": " + std::to_string(this->sequence) +
+	           ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
 }
 
 AddMessage::AddMessage(MessageTypes type, std::string product, double price,
@@ -279,30 +326,32 @@
 {
 	if (mapOrderSide.empty()) initialise();
 	return "{\"type\": \"ADD\", \"product\": \"" + this->product +
-		   "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" +
-		   mapOrderSide[this->side] +
-		   "\", \"volume\": " + std::to_string(this->volume) + "}";
+	       "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" +
+	       mapOrderSide[this->side] +
+	       "\", \"volume\": " + std::to_string(this->volume) + "}";
 }
 
 AddedMessage::AddedMessage(MessageTypes type, std::string product,
                            std::string id, book::OrderSideEnum side,
                            double price, uint64_t filled, uint64_t resting,
-                           uint64_t sequence, double timestamp)
+                           std::string owner, uint64_t sequence,
+                           double timestamp)
 	: FromExchange(type, product, sequence, timestamp), id(id), side(side),
-	  price(price), filled(filled), resting(resting)
+	  price(price), filled(filled), resting(resting), owner(owner)
 {
 }
 
 std::string AddedMessage::as_string()
 {
 	return "{\"type\": \"ADDED\", \"product\": \"" + this->product +
-		   "\", \"product\": \"" + this->id + "\" \"side\": \"" +
-		   mapOrderSide[this->side] +
-		   "\", \"price\": " + std::to_string(this->price) +
-		   "\"filled\": " + std::to_string(this->filled) +
-		   ", \"resting\": " + std::to_string(this->resting) +
-		   ", \"sequence\": " + std::to_string(this->sequence) +
-		   ", \"timestamp\":" + std::to_string(this->timestamp) + "}";
+	       "\", \"product\": \"" + this->id + "\", \"side\": \"" +
+	       mapOrderSide[this->side] +
+	       "\", \"price\": " + std::to_string(this->price) +
+	       ", \"filled\": " + std::to_string(this->filled) +
+	       ", \"resting\": " + std::to_string(this->resting) +
+	       ", \"owner\": \"" + this->owner +
+	       "\", \"sequence\": " + std::to_string(this->sequence) +
+	       ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
 }
 
 DeleteMessage::DeleteMessage(MessageTypes type, std::string product,
@@ -315,7 +364,7 @@
 {
 	if (mapOrderSide.empty()) initialise();
 	return "{\"type\": \"DELETE\", \"product\": \"" + this->product +
-		   "\", \"id\": \"" + this->id + "\"}";
+	       "\", \"id\": \"" + this->id + "\"}";
 }
 
 DeletedMessage::DeletedMessage(MessageTypes type, std::string product,
@@ -328,10 +377,10 @@
 std::string DeletedMessage::as_string()
 {
 	return "{\"type\": \"DELETED\", \"product\": \"" + this->product +
-		   "\", \"product\": \"" + this->id + "\" \"side\": \"" +
-		   mapOrderSide[this->side] +
-		   ", \"sequence\": " + std::to_string(this->sequence) +
-		   ", \"timestamp\":" + std::to_string(this->timestamp) + "}";
+	       "\", \"product\": \"" + this->id + "\", \"side\": \"" +
+	       mapOrderSide[this->side] +
+	       ", \"sequence\": " + std::to_string(this->sequence) +
+	       ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
 }
 
 RejectMessage::RejectMessage(MessageTypes type, std::string product,
@@ -343,10 +392,10 @@
 
 std::string RejectMessage::as_string()
 {
-	return "{\"type\": \"REJECT\", \"product\": \"" + this->product =
-			   "\", \"error\": \"" + this->error +
-			   "\", \"sequence\": " + std::to_string(this->sequence) +
-			   ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
+	return "{\"type\": \"REJECT\", \"product\": \"" + this->product +
+	       "\", \"error\": \"" + this->error +
+	       "\", \"sequence\": " + std::to_string(this->sequence) +
+	       ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
 }
 
 TradeMessage::TradeMessage(MessageTypes type, std::string product, double price,
@@ -361,11 +410,35 @@
 {
 }
 
+std::string TradeMessage::as_string()
+{
+	return "{\"type\": \"TRADE\", \"product\": \"" + this->product +
+	       "\", \"price\": " + std::to_string(this->price) +
+	       ", \"volume\": " + std::to_string(this->volume) + ", \"buyer\": \"" +
+	       this->buyer + "\", \"seller\": \"" + this->seller +
+	       "\", \"tradeType\": \"" + mapTTStr[this->tradeType] +
+	       "\", \"passiveOrder\": \"" + this->passiveOrder +
+	       "\", \"passoveOrderRemaining\": " +
+	       std::to_string(this->passiveOrderRemaining) +
+	       "\", \"sequence\": " + std::to_string(this->sequence) +
+	       ", \"timestamp\": " + std::to_string(this->timestamp) + "}";
+}
+
 BrokerRequest::BrokerRequest(MessageTypes type, std::string product,
                              double price, book::OrderSideEnum side,
                              uint64_t volume, std::string counterparty)
 	: Broker(type, product, price, side, volume, counterparty)
 {
+}
+
+std::string BrokerRequest::as_string()
+{
+	return "{\"type\": \"" + mapAStr[this->type] =
+	           "\", \"product\": \"" + this->product +
+	           "\", \"price\": " + std::to_string(this->price) +
+	           ", \"side\": " + mapOrderSide[this->side] +
+	           ", \"volume\": " + std::to_string(this->volume) +
+	           ", \"counterparty\": \"" + this->counterparty + "\"}";
 }
 
 BrokerAck::BrokerAck(MessageTypes type, std::string product, double price,
@@ -377,6 +450,19 @@
 {
 }
 
+std::string BrokerAck::as_string()
+{
+	return "{\"type\": \"" + mapAStr[this->type] =
+	           "\", \"product\": \"" + this->product +
+	           "\", \"price\": " + std::to_string(this->price) +
+	           ", \"side\": " + mapOrderSide[this->side] +
+	           ", \"volume\": " + std::to_string(this->volume) +
+	           ", \"counterparty\": \"" + this->counterparty + +"\", \"id\"" +
+	           this->id +
+	           "\", \"brokerTradeStatus\": " + this->brokerTradeStatus +
+	           "\", \"owner\": \"" + this->owner + "\"}";
+}
+
 BrokerConfirm::BrokerConfirm(MessageTypes type, std::string product,
                              double price, book::OrderSideEnum side,
                              uint64_t volume, std::string counterparty,
@@ -384,4 +470,16 @@
 	: Broker(type, product, price, side, volume, counterparty), id(id)
 {
 }
+
+std::string BrokerConfirm::as_string()
+{
+	return "{\"type\": \"" + mapAStr[this->type] =
+	           "\", \"product\": \"" + this->product +
+	           "\", \"price\": " + std::to_string(this->price) +
+	           ", \"side\": " + mapOrderSide[this->side] +
+	           ", \"volume\": " + std::to_string(this->volume) +
+	           ", \"counterparty\": \"" + this->counterparty +
+	           "\", \"id\": " + this->id + "\"}";
+}
+
 } // namespace json

--
Gitblit v1.9.3