Joel Grunbaum
2022-01-10 6bdd28a09c589cf631fce948476d48e9375f72a0
Click trader working, with exchange communication
6 files modified
170 ■■■■ changed files
book.cpp 1 ●●●● patch | view | raw | blame | history
click.cpp 84 ●●●●● patch | view | raw | blame | history
json.cpp 55 ●●●●● patch | view | raw | blame | history
json.hpp 10 ●●●●● patch | view | raw | blame | history
protocol.cpp 18 ●●●● patch | view | raw | blame | history
secrets.hpp 2 ●●● patch | view | raw | blame | history
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;
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;
    }
}
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:
@@ -99,6 +102,9 @@
        break;
    case DELETED:
        out = deleted(d);
        break;
    case REJECT:
        out = reject(d);
        break;
    case TRADE:
        out = trade(d);
@@ -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,11 +209,25 @@
        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)
    : type(types), product(product)
{
}
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,
@@ -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,
json.hpp
@@ -25,6 +25,7 @@
    BROKER_REQUEST,
    BROKER_ACK,
    BROKER_CONFIRM,
    ERROR,
    NONE
};
@@ -36,6 +37,12 @@
    Message(MessageTypes type, std::string product);
    Message();
    virtual ~Message() = default;
};
struct ErrorMessage : public Message {
    std::string message;
    ErrorMessage(std::string message);
    std::string as_string();
};
struct FromExchange : public Message {
@@ -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 {
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
secrets.hpp
@@ -2,7 +2,7 @@
#include <string>
// #define TEST
#define TEST
constexpr const char* HOST = "sytev070";
#ifdef TEST