From 6bdd28a09c589cf631fce948476d48e9375f72a0 Mon Sep 17 00:00:00 2001
From: Joel Grunbaum <joelgrun@gmail.com>
Date: Mon, 10 Jan 2022 04:50:34 +0000
Subject: [PATCH] Click trader working, with exchange communication
---
click.cpp | 84 +++++++++++++++++++++++++--
book.cpp | 1
json.hpp | 10 +++
secrets.hpp | 2
json.cpp | 55 ++++++++++++++++++
protocol.cpp | 18 +++---
6 files changed, 152 insertions(+), 18 deletions(-)
diff --git a/book.cpp b/book.cpp
index 4473e8c..a450a08 100644
--- a/book.cpp
+++ b/book.cpp
@@ -144,7 +144,6 @@
std::size_t count = 0;
std::sort(askCopy.begin(), askCopy.end());
std::reverse(askCopy.begin(), askCopy.end());
- uint64_t volume = 0;
double price = askCopy.front().price;
for (auto i : askCopy) {
std::cout << i << std::endl;
diff --git a/click.cpp b/click.cpp
index f373fce..749d649 100644
--- a/click.cpp
+++ b/click.cpp
@@ -7,7 +7,7 @@
#include <iostream>
#include <unordered_map>
-enum clickType { Buy, Sell, Flash };
+enum clickType { Buy, Sell, Flash, Delete };
static std::unordered_map<std::string, clickType> mapClick;
@@ -15,7 +15,8 @@
{
mapClick = {{"BUY", Buy}, {"SELL", Sell}, {"FLASH", Flash},
{"b", Buy}, {"s", Sell}, {"f", Flash},
- {"B", Buy}, {"S", Sell}, {"F", Flash}};
+ {"B", Buy}, {"S", Sell}, {"F", Flash},
+ {"DELETE", Delete}, {"D", Delete}, {"d", Delete}};
}
void usage()
@@ -25,7 +26,7 @@
<< std::endl
<< "USAGE" << std::endl
<< "\t-a product" << std::endl
- << "\t-t click type (buy, sell, flash)" << std::endl
+ << "\t-t click type (buy, sell, flash, delete)" << std::endl
<< "\t-p price" << std::endl
<< "\t-v volume" << std::endl
<< "\t-i id" << std::endl
@@ -34,25 +35,80 @@
<< std::endl;
}
+void buy(std::string& product, double price, uint64_t volume)
+{
+ json::AddMessage a(json::ADD, product, price, book::Buy, volume);
+ json::AddedMessage* b = static_cast<json::AddedMessage*>(protocol::addOrder(a));
+ std::cout << b->as_string() << std::endl;
+}
+
+void sell(std::string& product, double price, uint64_t volume)
+{
+ json::AddMessage a(json::ADD, product, price, book::Sell, volume);
+ json::AddedMessage* b = static_cast<json::AddedMessage*>(protocol::addOrder(a));
+ std::cout << b->as_string() << std::endl;
+ delete b;
+}
+
+void flash(std::string& product, double price, uint64_t volume, book::OrderSideEnum side)
+{
+ json::AddMessage a(json::ADD, product, price, side, volume);
+ json::Message* b = static_cast<json::Message*>(protocol::addOrder(a));
+ if (b->type == json::ERROR) {
+ std::cout << static_cast<json::ErrorMessage*>(b)->as_string() << std::endl;
+ return;
+ }
+ json::DeleteMessage c(json::DELETE, product, static_cast<json::AddedMessage*>(b)->id);
+ json::Message* d = protocol::deleteOrder(c);
+ std::cout << static_cast<json::AddedMessage*>(b)->as_string() << std::endl;
+ if (d->type == json::DELETED) {
+ std::cout << static_cast<json::DeletedMessage*>(d)->as_string()
+ << std::endl;
+ } else {
+ std::cout << static_cast<json::RejectMessage*>(d)->as_string()
+ << std::endl;
+ }
+ delete b;
+ delete d;
+}
+
+void deleteOrder(std::string& product, std::string& id)
+{
+ json::DeleteMessage a(json::DELETE, product, id);
+ json::Message* b = protocol::deleteOrder(a);
+ if (b->type == json::DELETED) {
+ std::cout << static_cast<json::DeletedMessage*>(b)->as_string()
+ << std::endl;
+ } else if (b->type == json::REJECT) {
+ std::cout << static_cast<json::RejectMessage*>(b)->as_string()
+ << std::endl;
+ } else {
+ std::cout << static_cast<json::ErrorMessage*>(b)->as_string() << std::endl;
+ }
+}
+
int main(int argc, char** argv)
{
int c;
std::string product, id;
double price;
- clickType click;
+ clickType click, side;
uint64_t volume;
initialise();
if (argc == 1) {
usage(), exit(0);
}
- while ((c = getopt(argc, argv, "a::t::p::v::i::")) != -1) {
+ while ((c = getopt(argc, argv, "a::t::s::p::v::i::")) != -1) {
switch (c) {
case 'a':
product = std::string(optarg);
break;
- case 's':
+ case 't':
click = mapClick[optarg];
break;
+ case 's':
+ side = mapClick[optarg];
+ break;
case 'p':
price = std::stod(optarg);
break;
@@ -63,14 +119,28 @@
id = std::string(optarg);
break;
case '?':
+ std::cout << "*1" << std::endl;
default:
+ std::cout << "*2 " << (char) c << std::endl;
usage();
exit(0);
}
}
switch (click) {
case Buy:
+ buy(product, price, volume);
+ break;
case Sell:
- case Flash:;
+ sell(product, price, volume);
+ break;
+ case Flash:
+ if (side == clickType::Buy)
+ flash(product, price, volume, book::Buy);
+ else
+ flash(product, price, volume, book::Sell);
+ break;
+ case Delete:
+ deleteOrder(product, id);
+ break;
}
}
diff --git a/json.cpp b/json.cpp
index 5d8e340..ea1016a 100644
--- a/json.cpp
+++ b/json.cpp
@@ -58,10 +58,12 @@
SettleMessage* settle(rapidjson::Value& d);
AddedMessage* added(rapidjson::Value& d);
DeletedMessage* deleted(rapidjson::Value& d);
+RejectMessage* reject(rapidjson::Value& d);
TradeMessage* trade(rapidjson::Value& d);
BrokerRequest* brokerReq(rapidjson::Value& d);
BrokerAck* brokerAck(rapidjson::Value& d);
BrokerConfirm* brokerCon(rapidjson::Value& d);
+ErrorMessage* error(rapidjson::Value& d);
std::queue<Message*> parse(std::string& str)
{
@@ -83,6 +85,7 @@
if (mapTypes.empty()) {
initialise();
}
+ if (d.HasMember("error")) return error(d);
Message* out;
switch (mapTypes[d["type"].GetString()]) {
case FUTURE_TYPE:
@@ -100,6 +103,9 @@
case DELETED:
out = deleted(d);
break;
+ case REJECT:
+ out = reject(d);
+ break;
case TRADE:
out = trade(d);
break;
@@ -161,6 +167,12 @@
d["sequence"].GetInt(), d["timestamp"].GetDouble());
}
+RejectMessage* reject(rapidjson::Value& d)
+{
+ return new RejectMessage(mapTypes[d["type"].GetString()], "",
+ d["error"].GetString(), uint64_t(0), double(0));
+}
+
TradeMessage* trade(rapidjson::Value& d)
{
return new TradeMessage(
@@ -197,6 +209,11 @@
d["id"].GetString());
}
+ErrorMessage* error(rapidjson::Value& d)
+{
+ return new ErrorMessage(d["error"].GetString());
+}
+
Message::Message() : type(NONE), product("error") {}
Message::Message(MessageTypes types, std::string product)
@@ -204,6 +221,15 @@
{
}
+ErrorMessage::ErrorMessage(std::string message)
+ : Message(ERROR, ""), message(message)
+{
+}
+std::string ErrorMessage::as_string()
+{
+ return "{\"error\": \"" + this->message + "\"}";
+}
+
FromExchange::FromExchange(MessageTypes type, std::string product,
uint64_t sequence, double timestamp)
: Message(type, product), sequence(sequence), timestamp(timestamp)
@@ -266,6 +292,18 @@
{
}
+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) + "}";
+}
+
DeleteMessage::DeleteMessage(MessageTypes type, std::string product,
std::string id)
: ToExchange(type, product), id(id)
@@ -286,6 +324,15 @@
{
}
+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) + "}";
+}
+
RejectMessage::RejectMessage(MessageTypes type, std::string product,
std::string error, uint64_t sequence,
double timestamp)
@@ -293,6 +340,14 @@
{
}
+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) + "}";
+}
+
TradeMessage::TradeMessage(MessageTypes type, std::string product, double price,
uint64_t volume, std::string buyer,
std::string seller, TradeTypeEnum tradeType,
diff --git a/json.hpp b/json.hpp
index adcb147..9da1381 100644
--- a/json.hpp
+++ b/json.hpp
@@ -25,6 +25,7 @@
BROKER_REQUEST,
BROKER_ACK,
BROKER_CONFIRM,
+ ERROR,
NONE
};
@@ -38,6 +39,12 @@
virtual ~Message() = default;
};
+struct ErrorMessage : public Message {
+ std::string message;
+ ErrorMessage(std::string message);
+ std::string as_string();
+};
+
struct FromExchange : public Message {
uint64_t sequence;
double timestamp;
@@ -104,6 +111,7 @@
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 as_string();
};
struct DeleteMessage : public ToExchange {
@@ -118,12 +126,14 @@
DeletedMessage(MessageTypes type, std::string product, std::string id,
book::OrderSideEnum side, uint64_t sequence,
double timestamp);
+ std::string as_string();
};
struct RejectMessage : public FromExchange {
std::string error;
RejectMessage(MessageTypes type, std::string product, std::string error,
uint64_t sequence, double timestamp);
+ std::string as_string();
};
struct TradeMessage : public FromExchange {
diff --git a/protocol.cpp b/protocol.cpp
index c15fded..0e168f5 100644
--- a/protocol.cpp
+++ b/protocol.cpp
@@ -49,17 +49,13 @@
json::Message* addOrder(json::AddMessage& order)
{
- std::string message = "{\"message\": " + order.as_string() + ", " +
- "\"username\": \"" + std::string(USER) +
- "\", \"password\": \"" + std::string(PASS) + "\"}";
+ std::string message = order.as_string();
return send(message);
}
json::Message* deleteOrder(json::DeleteMessage& order)
{
- std::string message = "{\"message\": " + order.as_string() +
- ", \"username\": \"" + std::string(USER) +
- "\", \"password\": \"" + std::string(PASS) + "\"}";
+ std::string message = order.as_string();
return send(message);
}
@@ -168,9 +164,13 @@
json::Message* send(std::string& message)
{
- auto res = cli.Post("/execution", message, "text/plain");
- std::queue<json::Message*> a = json::parse(res->body);
- return a.front();
+ httplib::MultipartFormDataItems a = {{"message", message, "", ""},
+ {"username", USER, "", ""},
+ {"password", PASS, "", ""}};
+ auto res = cli.Post("/execution", a);
+ std::string b = res->body;
+ std::queue<json::Message*> c = json::parse(b);
+ return c.front();
}
} // namespace protocol
diff --git a/secrets.hpp b/secrets.hpp
index 398da5c..24acfae 100644
--- a/secrets.hpp
+++ b/secrets.hpp
@@ -2,7 +2,7 @@
#include <string>
-// #define TEST
+#define TEST
constexpr const char* HOST = "sytev070";
#ifdef TEST
--
Gitblit v1.10.0