From 12f458cf94edde7af65f47b83f281321d2d6c2d3 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sat, 12 Mar 2022 01:54:51 +0100 Subject: [PATCH] kraken: parse: add input file parser --- src/parse/CMakeLists.txt | 3 ++ src/parse/parse.cc | 79 ++++++++++++++++++++++++++++++++++++++++ src/parse/parse.hh | 17 +++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/parse/parse.cc create mode 100644 src/parse/parse.hh diff --git a/src/parse/CMakeLists.txt b/src/parse/CMakeLists.txt index 340b554..9918cde 100644 --- a/src/parse/CMakeLists.txt +++ b/src/parse/CMakeLists.txt @@ -1,9 +1,12 @@ add_library(parse STATIC order.cc order.hh + parse.cc + parse.hh ) target_link_libraries(parse PRIVATE + csv utils ) diff --git a/src/parse/parse.cc b/src/parse/parse.cc new file mode 100644 index 0000000..e582a0a --- /dev/null +++ b/src/parse/parse.cc @@ -0,0 +1,79 @@ +#include "parse.hh" + +#include + +#include + +#include "csv/read-csv.hh" + +namespace kraken::parse { + +namespace { + +Side parse_side(std::string_view side) { + if (side == "B") { + return Side::BID; + } else if (side == "S") { + return Side::ASK; + } else { + throw ParseError("Not a valid side"); + } +} + +TradeOrder trade_from_raw(csv::csv_line_type const& raw_order) { + assert(raw_order[0] == "N"); + + if (raw_order.size() != 7) { + throw ParseError("Not a valid trade order"); + } + + auto const user = User{std::stoi(raw_order[1])}; + auto const symbol = Symbol{raw_order[2]}; + auto const price = Price{std::stoi(raw_order[3])}; + auto const quantity = Quantity{std::stoi(raw_order[4])}; + auto const side = Side{parse_side(raw_order[5])}; + auto const id = UserOrderId{std::stoi(raw_order[6])}; + + return TradeOrder{ + user, symbol, price, quantity, side, id, + }; +} + +CancelOrder cancel_from_raw(csv::csv_line_type const& raw_order) { + assert(raw_order[0] == "C"); + + if (raw_order.size() != 3) { + throw ParseError("Not a valid cancel order"); + } + + auto const user = User{std::stoi(raw_order[1])}; + auto const id = UserOrderId{std::stoi(raw_order[2])}; + + return CancelOrder{ + user, + id, + }; +} + +} // namespace + +std::vector parse_orders(std::istream& input) { + auto const raw_orders = read_csv(input, kraken::csv::CsvHeader::KEEP); + auto orders = std::vector{}; + + for (auto const& raw_order : raw_orders) { + if (raw_order[0] == "N") { + orders.emplace_back(trade_from_raw(raw_order)); + } else if (raw_order[0] == "C") { + orders.emplace_back(cancel_from_raw(raw_order)); + } else if (raw_order[0] == "F") { + orders.emplace_back(FlushOrder{}); + } else { + throw ParseError("Not a valid order"); + } + } + + return orders; +} + +} // namespace kraken::parse diff --git a/src/parse/parse.hh b/src/parse/parse.hh new file mode 100644 index 0000000..ebdb6d1 --- /dev/null +++ b/src/parse/parse.hh @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +#include "order.hh" + +namespace kraken::parse { + +struct ParseError : public std::runtime_error { + using std::runtime_error::runtime_error; +}; + +std::vector parse_orders(std::istream& input); + +} // namespace kraken::parse