From 134b1264d699c955e05a4c6e1a186a777611cb8b Mon Sep 17 00:00:00 2001 From: Stephane Janel Date: Sat, 21 Dec 2024 20:41:07 +0100 Subject: [PATCH] Query result - migrate to glaze json --- CMakeLists.txt | 12 - INSTALL.md | 1 - src/api-objects/include/closed-order.hpp | 3 - src/api-objects/include/order.hpp | 9 +- src/api-objects/include/tradeinfo.hpp | 4 +- src/api-objects/include/tradeoptions.hpp | 14 +- src/api-objects/include/withdrawinfo.hpp | 2 +- src/api-objects/include/withdrawoptions.hpp | 16 +- src/api-objects/include/withdrawordeposit.hpp | 15 +- src/api-objects/src/closed-order.cpp | 3 - src/api-objects/src/order.cpp | 20 - src/api-objects/src/tradeoptions.cpp | 14 +- src/api-objects/src/withdrawoptions.cpp | 4 +- src/api-objects/src/withdrawordeposit.cpp | 8 +- src/api-objects/test/closed-order_test.cpp | 4 +- src/api-objects/test/deposit_test.cpp | 10 +- src/api-objects/test/withdraw_test.cpp | 11 +- src/api/common/src/commonapi.cpp | 2 +- src/api/common/src/exchangeprivateapi.cpp | 16 +- .../common/test/exchangeprivateapi_test.cpp | 52 +- src/api/exchanges/src/binanceprivateapi.cpp | 30 +- src/api/exchanges/src/binancepublicapi.cpp | 4 +- src/api/exchanges/src/bithumbprivateapi.cpp | 12 +- src/api/exchanges/src/bithumbpublicapi.cpp | 2 +- src/api/exchanges/src/huobiprivateapi.cpp | 38 +- src/api/exchanges/src/huobipublicapi.cpp | 4 +- src/api/exchanges/src/krakenprivateapi.cpp | 22 +- src/api/exchanges/src/krakenpublicapi.cpp | 2 +- src/api/exchanges/src/kucoinprivateapi.cpp | 16 +- src/api/exchanges/src/kucoinpublicapi.cpp | 5 +- src/api/exchanges/src/upbitprivateapi.cpp | 16 +- src/api/exchanges/src/upbitpublicapi.cpp | 3 +- .../test/bithumb_place_order_test.cpp | 6 +- .../exchanges/test/exchangecommonapi_test.hpp | 2 +- src/basic-objects/include/apioutputtype.hpp | 2 +- .../include/apiquerytypeenum.hpp | 2 +- src/basic-objects/include/cct_const.hpp | 2 +- src/basic-objects/include/currencycode.hpp | 2 +- .../include/generic-object-json.hpp | 2 +- src/basic-objects/include/market.hpp | 2 +- src/basic-objects/include/monetaryamount.hpp | 2 +- src/basic-objects/include/priceoptionsdef.hpp | 2 +- .../src/coincentercommandtype.cpp | 2 +- src/basic-objects/test/currencycode_test.cpp | 2 +- src/basic-objects/test/market_test.cpp | 2 +- .../test/monetaryamount_test.cpp | 2 +- .../include/balanceperexchangeportfolio.hpp | 4 - src/engine/include/queryresultprinter.hpp | 21 +- src/engine/include/traderesult.hpp | 15 +- .../src/balanceperexchangeportfolio.cpp | 41 - .../src/coincenter-commands-processor.cpp | 3 + src/engine/src/coincentercommands.cpp | 11 +- src/engine/src/coincenteroptions.cpp | 12 +- src/engine/src/metricsexporter.cpp | 2 +- src/engine/src/query-result-schema.hpp | 531 ++++++++ src/engine/src/queryresultprinter.cpp | 1171 ++++++++--------- src/engine/src/traderesult.cpp | 19 +- src/engine/test/coincenteroptions_test.cpp | 14 +- .../exchangesorchestrator_private_test.cpp | 14 +- .../test/exchangesorchestrator_trade_test.cpp | 62 +- .../test/queryresultprinter_base_test.hpp | 2 +- .../test/queryresultprinter_private_test.cpp | 120 +- .../test/queryresultprinter_public_test.cpp | 270 ++-- src/http-request/include/request-retry.hpp | 2 +- src/objects/include/time-window.hpp | 56 +- src/objects/include/tradedefinitions.hpp | 41 +- src/objects/include/tradeside.hpp | 21 +- src/objects/src/marketorderbook.cpp | 8 +- src/objects/src/publictrade.cpp | 2 +- src/objects/src/time-window.cpp | 37 +- src/objects/test/marketorderbook_test.cpp | 29 +- src/objects/test/publictrade_test.cpp | 20 +- src/objects/test/time-window_test.cpp | 28 + src/objects/test/writer_mock.hpp | 14 - src/schema/include/duration-schema.hpp | 2 +- src/schema/include/exchange-query-config.hpp | 2 +- src/schema/include/read-json.hpp | 2 +- src/schema/include/secret-schema.hpp | 2 +- src/schema/include/size-bytes-schema.hpp | 2 +- src/schema/include/timepoint-schema.hpp | 2 +- src/schema/include/write-json.hpp | 11 +- src/schema/test/duration-schema_test.cpp | 2 +- src/schema/test/size-bytes-schema_test.cpp | 2 +- .../src/proto-public-trade-converter.cpp | 8 +- .../proto-public-trade-converter_test.cpp | 2 +- ...serialization-and-deserialization_test.cpp | 2 +- src/serialization/test/proto-test-data.hpp | 22 +- src/tech/CMakeLists.txt | 3 - src/tech/include/cct_json-container.hpp | 17 - ...ct_json-serialization.hpp => cct_json.hpp} | 0 .../algorithms/src/example-market-trader.cpp | 2 +- .../common/src/market-trader-engine-state.cpp | 16 +- .../common/src/market-trader-engine.cpp | 4 +- src/trading/common/src/trader-command.cpp | 8 +- 94 files changed, 1774 insertions(+), 1313 deletions(-) delete mode 100644 src/api-objects/src/order.cpp create mode 100644 src/engine/src/query-result-schema.hpp delete mode 100644 src/objects/test/writer_mock.hpp delete mode 100644 src/tech/include/cct_json-container.hpp rename src/tech/include/{cct_json-serialization.hpp => cct_json.hpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 514d41cb..6e9d78cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,18 +99,6 @@ if(CCT_ENABLE_TESTS) enable_testing() endif() -# nlohmann_json - json container library -find_package(nlohmann_json CONFIG) -if(NOT nlohmann_json_FOUND) - FetchContent_Declare( - nlohmann_json - URL https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz - URL_HASH SHA256=0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406 - ) - - list(APPEND fetchContentPackagesToMakeAvailable nlohmann_json) -endif() - # Glaze - fast json serialization library find_package(glaze CONFIG) if(NOT glaze) diff --git a/INSTALL.md b/INSTALL.md index 59418c7c..0fc03feb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -139,7 +139,6 @@ If you are building frequently `coincenter` you can install them to speed up its | -------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------- | | [amc](https://github.com/AmadeusITGroup/amc.git) | High performance C++ containers (maintained by me) | MIT | | [googletest](https://github.com/google/googletest.git) | Google Testing and Mocking Framework | BSD-3-Clause License | -| [json container](https://github.com/nlohmann/json) | JSON for Modern C++ | MIT | | [json serialization](https://github.com/stephenberry/glaze) | Extremely fast, in memory, JSON and interface library for modern C++ | MIT | | [spdlog](https://github.com/gabime/spdlog.git) | Fast C++ logging library | MIT | | [prometheus-cpp](https://github.com/jupp0r/prometheus-cpp.git) | Prometheus Client Library for Modern C++ | MIT | diff --git a/src/api-objects/include/closed-order.hpp b/src/api-objects/include/closed-order.hpp index 2dbd4b06..294dcf01 100644 --- a/src/api-objects/include/closed-order.hpp +++ b/src/api-objects/include/closed-order.hpp @@ -1,6 +1,5 @@ #pragma once -#include "cct_string.hpp" #include "monetaryamount.hpp" #include "order.hpp" #include "orderid.hpp" @@ -16,8 +15,6 @@ class ClosedOrder : public Order { TimePoint matchedTime() const { return _matchedTime; } - string matchedTimeStr() const; - /// Compute the resulting merged closed order from *this and given one. /// Given closed order should be of same ID, TradeSide and Market. [[nodiscard]] ClosedOrder mergeWith(const ClosedOrder &closedOrder) const; diff --git a/src/api-objects/include/order.hpp b/src/api-objects/include/order.hpp index 108b8f37..3d09c1bc 100644 --- a/src/api-objects/include/order.hpp +++ b/src/api-objects/include/order.hpp @@ -1,9 +1,7 @@ #pragma once #include -#include -#include "cct_string.hpp" #include "cct_type_traits.hpp" #include "market.hpp" #include "monetaryamount.hpp" @@ -25,10 +23,6 @@ class Order { TradeSide side() const { return _side; } - std::string_view sideStr() const; - - string placedTimeStr() const; - Market market() const { return Market(_matchedVolume.currencyCode(), _price.currencyCode()); } std::strong_ordering operator<=>(const Order &) const noexcept = default; @@ -36,7 +30,8 @@ class Order { using trivially_relocatable = is_trivially_relocatable::type; protected: - Order(OrderId id, MonetaryAmount matchedVolume, MonetaryAmount price, TimePoint placedTime, TradeSide side); + Order(OrderId id, MonetaryAmount matchedVolume, MonetaryAmount price, TimePoint placedTime, TradeSide side) + : _placedTime(placedTime), _id(std::move(id)), _matchedVolume(matchedVolume), _price(price), _side(side) {} private: TimePoint _placedTime; diff --git a/src/api-objects/include/tradeinfo.hpp b/src/api-objects/include/tradeinfo.hpp index c551127c..717bf089 100644 --- a/src/api-objects/include/tradeinfo.hpp +++ b/src/api-objects/include/tradeinfo.hpp @@ -14,8 +14,8 @@ namespace cct::api { using UserRefInt = int32_t; struct TradeContext { - CurrencyCode fromCur() const { return side == TradeSide::kSell ? market.base() : market.quote(); } - CurrencyCode toCur() const { return side == TradeSide::kBuy ? market.base() : market.quote(); } + CurrencyCode fromCur() const { return side == TradeSide::sell ? market.base() : market.quote(); } + CurrencyCode toCur() const { return side == TradeSide::buy ? market.base() : market.quote(); } Market market; TradeSide side{}; diff --git a/src/api-objects/include/tradeoptions.hpp b/src/api-objects/include/tradeoptions.hpp index 1dddb5be..cbb520ee 100644 --- a/src/api-objects/include/tradeoptions.hpp +++ b/src/api-objects/include/tradeoptions.hpp @@ -26,7 +26,7 @@ class TradeOptions { TradeOptions(const PriceOptions &priceOptions, TradeTimeoutAction timeoutAction, TradeMode tradeMode, Duration maxTradeTime, Duration minTimeBetweenPriceUpdates = kUndefinedDuration, TradeTypePolicy tradeTypePolicy = TradeTypePolicy::kDefault, - TradeSyncPolicy tradeSyncPolicy = TradeSyncPolicy::kSynchronous); + TradeSyncPolicy tradeSyncPolicy = TradeSyncPolicy::synchronous); /// Constructs a new TradeOptions based on 'rhs' with unspecified options overriden from exchange config values TradeOptions(const TradeOptions &rhs, const schema::ExchangeQueryTradeConfig &exchangeTradeConfig); @@ -53,13 +53,15 @@ class TradeOptions { return _priceOptions.isTakerStrategy() && (!isSimulation() || !placeRealOrderInSimulationMode); } - constexpr bool isSimulation() const { return _tradeMode == TradeMode::kSimulation; } + constexpr bool isSimulation() const { return _tradeMode == TradeMode::simulation; } constexpr bool isFixedPrice() const { return _priceOptions.isFixedPrice(); } constexpr bool isRelativePrice() const { return _priceOptions.isRelativePrice(); } - constexpr bool placeMarketOrderAtTimeout() const { return _timeoutAction == TradeTimeoutAction::kMatch; } + constexpr TradeTimeoutAction timeoutAction() const { return _timeoutAction; } + + constexpr bool placeMarketOrderAtTimeout() const { return _timeoutAction == TradeTimeoutAction::match; } constexpr void switchToTakerStrategy() { _priceOptions.switchToTakerStrategy(); } @@ -75,10 +77,10 @@ class TradeOptions { Duration _maxTradeTime = kUndefinedDuration; Duration _minTimeBetweenPriceUpdates = kUndefinedDuration; PriceOptions _priceOptions; - TradeTimeoutAction _timeoutAction = TradeTimeoutAction::kDefault; - TradeMode _tradeMode = TradeMode::kReal; + TradeTimeoutAction _timeoutAction = TradeTimeoutAction::exchange_default; + TradeMode _tradeMode = TradeMode::real; TradeTypePolicy _tradeTypePolicy = TradeTypePolicy::kDefault; - TradeSyncPolicy _tradeSyncPolicy = TradeSyncPolicy::kSynchronous; + TradeSyncPolicy _tradeSyncPolicy = TradeSyncPolicy::synchronous; }; } // namespace cct \ No newline at end of file diff --git a/src/api-objects/include/withdrawinfo.hpp b/src/api-objects/include/withdrawinfo.hpp index 298fae00..d204ccbe 100644 --- a/src/api-objects/include/withdrawinfo.hpp +++ b/src/api-objects/include/withdrawinfo.hpp @@ -56,7 +56,7 @@ class SentWithdrawInfo { private: MonetaryAmount _netEmittedAmount; MonetaryAmount _fee; - Withdraw::Status _withdrawStatus = Withdraw::Status::kInitial; + Withdraw::Status _withdrawStatus = Withdraw::Status::initial; }; class ReceivedWithdrawInfo { diff --git a/src/api-objects/include/withdrawoptions.hpp b/src/api-objects/include/withdrawoptions.hpp index dc1709db..60d31725 100644 --- a/src/api-objects/include/withdrawoptions.hpp +++ b/src/api-objects/include/withdrawoptions.hpp @@ -3,13 +3,14 @@ #include #include +#include "cct_json.hpp" #include "timedef.hpp" namespace cct { enum class WithdrawSyncPolicy : int8_t { - kSynchronous, // Follow lifetime of the withdraw until funds are received at destination - kAsynchronous // Only trigger withdraw and exit withdraw process directly + synchronous, // Follow lifetime of the withdraw until funds are received at destination + asynchronous // Only trigger withdraw and exit withdraw process directly }; class WithdrawOptions { @@ -36,7 +37,14 @@ class WithdrawOptions { static constexpr auto kWithdrawRefreshTime = seconds(5); Duration _withdrawRefreshTime = kWithdrawRefreshTime; - WithdrawSyncPolicy _withdrawSyncPolicy = WithdrawSyncPolicy::kSynchronous; + WithdrawSyncPolicy _withdrawSyncPolicy = WithdrawSyncPolicy::synchronous; Mode _mode = Mode::kReal; }; -} // namespace cct \ No newline at end of file +} // namespace cct + +template <> +struct glz::meta { + using enum cct::WithdrawSyncPolicy; + + static constexpr auto value = enumerate(synchronous, asynchronous); +}; diff --git a/src/api-objects/include/withdrawordeposit.hpp b/src/api-objects/include/withdrawordeposit.hpp index 189e0c27..f32fd377 100644 --- a/src/api-objects/include/withdrawordeposit.hpp +++ b/src/api-objects/include/withdrawordeposit.hpp @@ -3,6 +3,7 @@ #include #include +#include "cct_json.hpp" #include "cct_string.hpp" #include "monetaryamount.hpp" #include "timedef.hpp" @@ -11,10 +12,10 @@ namespace cct { class WithdrawOrDeposit { public: enum class Status : int8_t { - kInitial, - kSuccess, - kProcessing, - kFailureOrRejected, + initial, + success, + processing, + failed, }; template @@ -46,3 +47,9 @@ class WithdrawOrDeposit { }; } // namespace cct + +template <> +struct glz::meta<::cct::WithdrawOrDeposit::Status> { + using enum ::cct::WithdrawOrDeposit::Status; + static constexpr auto value = enumerate(initial, success, processing, failed); +}; diff --git a/src/api-objects/src/closed-order.cpp b/src/api-objects/src/closed-order.cpp index 9fd01766..92cd5cdb 100644 --- a/src/api-objects/src/closed-order.cpp +++ b/src/api-objects/src/closed-order.cpp @@ -2,7 +2,6 @@ #include -#include "cct_string.hpp" #include "monetaryamount.hpp" #include "order.hpp" #include "orderid.hpp" @@ -16,8 +15,6 @@ ClosedOrder::ClosedOrder(OrderId id, MonetaryAmount matchedVolume, MonetaryAmoun TimePoint matchedTime, TradeSide side) : Order(std::move(id), matchedVolume, price, placedTime, side), _matchedTime(matchedTime) {} -string ClosedOrder::matchedTimeStr() const { return TimeToString(_matchedTime); } - ClosedOrder ClosedOrder::mergeWith(const ClosedOrder &closedOrder) const { const MonetaryAmount totalMatchedVolume = closedOrder.matchedVolume() + matchedVolume(); const auto previousMatchedTs = TimestampToMillisecondsSinceEpoch(matchedTime()); diff --git a/src/api-objects/src/order.cpp b/src/api-objects/src/order.cpp deleted file mode 100644 index 65c7a92f..00000000 --- a/src/api-objects/src/order.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "order.hpp" - -#include -#include - -#include "cct_string.hpp" -#include "monetaryamount.hpp" -#include "timedef.hpp" -#include "timestring.hpp" -#include "tradeside.hpp" - -namespace cct { - -Order::Order(string id, MonetaryAmount matchedVolume, MonetaryAmount price, TimePoint placedTime, TradeSide side) - : _placedTime(placedTime), _id(std::move(id)), _matchedVolume(matchedVolume), _price(price), _side(side) {} - -std::string_view Order::sideStr() const { return SideStr(_side); } - -string Order::placedTimeStr() const { return TimeToString(_placedTime); } -} // namespace cct \ No newline at end of file diff --git a/src/api-objects/src/tradeoptions.cpp b/src/api-objects/src/tradeoptions.cpp index cbe35b99..d2bf43d5 100644 --- a/src/api-objects/src/tradeoptions.cpp +++ b/src/api-objects/src/tradeoptions.cpp @@ -14,10 +14,10 @@ namespace cct { namespace { auto ComputeTimeoutAction(TradeTimeoutAction tradeTimeoutAction, bool timeoutMatch) { - if (tradeTimeoutAction != TradeTimeoutAction::kDefault) { + if (tradeTimeoutAction != TradeTimeoutAction::exchange_default) { return tradeTimeoutAction; } - return timeoutMatch ? TradeTimeoutAction::kMatch : TradeTimeoutAction::kCancel; + return timeoutMatch ? TradeTimeoutAction::match : TradeTimeoutAction::cancel; } } // namespace @@ -58,12 +58,12 @@ bool TradeOptions::isMultiTradeAllowed(bool multiTradeAllowedByDefault) const { std::string_view TradeOptions::timeoutActionStr() const { switch (_timeoutAction) { - case TradeTimeoutAction::kDefault: + case TradeTimeoutAction::exchange_default: // Default will behave the same as cancel - this field is not publicly exposed [[fallthrough]]; - case TradeTimeoutAction::kCancel: + case TradeTimeoutAction::cancel: return "cancel"; - case TradeTimeoutAction::kMatch: + case TradeTimeoutAction::match: return "match"; default: unreachable(); @@ -72,9 +72,9 @@ std::string_view TradeOptions::timeoutActionStr() const { std::string_view TradeOptions::tradeSyncPolicyStr() const { switch (_tradeSyncPolicy) { - case TradeSyncPolicy::kSynchronous: + case TradeSyncPolicy::synchronous: return "synchronous"; - case TradeSyncPolicy::kAsynchronous: + case TradeSyncPolicy::asynchronous: return "asynchronous"; default: unreachable(); diff --git a/src/api-objects/src/withdrawoptions.cpp b/src/api-objects/src/withdrawoptions.cpp index 5c506a01..98a8619f 100644 --- a/src/api-objects/src/withdrawoptions.cpp +++ b/src/api-objects/src/withdrawoptions.cpp @@ -11,9 +11,9 @@ WithdrawOptions::WithdrawOptions(Duration withdrawRefreshTime, WithdrawSyncPolic std::string_view WithdrawOptions::withdrawSyncPolicyStr() const { switch (_withdrawSyncPolicy) { - case WithdrawSyncPolicy::kSynchronous: + case WithdrawSyncPolicy::synchronous: return "synchronous"; - case WithdrawSyncPolicy::kAsynchronous: + case WithdrawSyncPolicy::asynchronous: return "asynchronous"; default: unreachable(); diff --git a/src/api-objects/src/withdrawordeposit.cpp b/src/api-objects/src/withdrawordeposit.cpp index aaf8ad46..b83f31a3 100644 --- a/src/api-objects/src/withdrawordeposit.cpp +++ b/src/api-objects/src/withdrawordeposit.cpp @@ -9,13 +9,13 @@ namespace cct { std::string_view WithdrawOrDeposit::statusStr() const { switch (_status) { - case Status::kInitial: + case Status::initial: return "initial"; - case Status::kProcessing: + case Status::processing: return "processing"; - case Status::kFailureOrRejected: + case Status::failed: return "failed"; - case Status::kSuccess: + case Status::success: return "success"; default: unreachable(); diff --git a/src/api-objects/test/closed-order_test.cpp b/src/api-objects/test/closed-order_test.cpp index 66c39a0d..df52b7ec 100644 --- a/src/api-objects/test/closed-order_test.cpp +++ b/src/api-objects/test/closed-order_test.cpp @@ -17,8 +17,8 @@ class ClosedOrderTest : public ::testing::Test { TimePoint tp2{milliseconds{std::numeric_limits::max() / 9900000}}; TimePoint tp3{milliseconds{std::numeric_limits::max() / 9800000}}; - ClosedOrder closedOrder1{"1", MonetaryAmount(15, "BTC", 1), MonetaryAmount(35000, "USDT"), tp1, tp1, TradeSide::kBuy}; - ClosedOrder closedOrder2{"2", MonetaryAmount(25, "BTC", 1), MonetaryAmount(45000, "USDT"), tp2, tp3, TradeSide::kBuy}; + ClosedOrder closedOrder1{"1", MonetaryAmount(15, "BTC", 1), MonetaryAmount(35000, "USDT"), tp1, tp1, TradeSide::buy}; + ClosedOrder closedOrder2{"2", MonetaryAmount(25, "BTC", 1), MonetaryAmount(45000, "USDT"), tp2, tp3, TradeSide::buy}; }; TEST_F(ClosedOrderTest, SelfMerge) { diff --git a/src/api-objects/test/deposit_test.cpp b/src/api-objects/test/deposit_test.cpp index bad569da..005b60b0 100644 --- a/src/api-objects/test/deposit_test.cpp +++ b/src/api-objects/test/deposit_test.cpp @@ -18,11 +18,11 @@ class DepositTest : public ::testing::Test { TimePoint tp3{milliseconds{std::numeric_limits::max() / 8000000}}; TimePoint tp4{milliseconds{std::numeric_limits::max() / 7000000}}; - Deposit deposit1{"id1", tp2, MonetaryAmount("0.045", "BTC"), Deposit::Status::kSuccess}; - Deposit deposit2{"id2", tp4, MonetaryAmount(37, "XRP"), Deposit::Status::kSuccess}; - Deposit deposit3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Deposit::Status::kFailureOrRejected}; - Deposit deposit4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Deposit::Status::kProcessing}; - Deposit deposit5{"id5", tp3, MonetaryAmount("69204866.9", "DOGE"), Deposit::Status::kSuccess}; + Deposit deposit1{"id1", tp2, MonetaryAmount("0.045", "BTC"), Deposit::Status::success}; + Deposit deposit2{"id2", tp4, MonetaryAmount(37, "XRP"), Deposit::Status::success}; + Deposit deposit3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Deposit::Status::failed}; + Deposit deposit4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Deposit::Status::processing}; + Deposit deposit5{"id5", tp3, MonetaryAmount("69204866.9", "DOGE"), Deposit::Status::success}; vector deposits{deposit1, deposit2, deposit3, deposit4, deposit5}; }; diff --git a/src/api-objects/test/withdraw_test.cpp b/src/api-objects/test/withdraw_test.cpp index 9d59d56c..7d52bf3e 100644 --- a/src/api-objects/test/withdraw_test.cpp +++ b/src/api-objects/test/withdraw_test.cpp @@ -18,14 +18,13 @@ class WithdrawTest : public ::testing::Test { TimePoint tp3{milliseconds{std::numeric_limits::max() / 8000000}}; TimePoint tp4{milliseconds{std::numeric_limits::max() / 7000000}}; - Withdraw withdraw1{"id1", tp2, MonetaryAmount("0.045", "BTC"), Withdraw::Status::kSuccess, + Withdraw withdraw1{"id1", tp2, MonetaryAmount("0.045", "BTC"), Withdraw::Status::success, MonetaryAmount("0.001", "BTC")}; - Withdraw withdraw2{"id2", tp4, MonetaryAmount(37, "XRP"), Withdraw::Status::kSuccess, MonetaryAmount("0.02 XRP")}; - Withdraw withdraw3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Withdraw::Status::kFailureOrRejected, - MonetaryAmount("0 EUR")}; - Withdraw withdraw4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Withdraw::Status::kProcessing, + Withdraw withdraw2{"id2", tp4, MonetaryAmount(37, "XRP"), Withdraw::Status::success, MonetaryAmount("0.02 XRP")}; + Withdraw withdraw3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Withdraw::Status::failed, MonetaryAmount("0 EUR")}; + Withdraw withdraw4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Withdraw::Status::processing, MonetaryAmount("0.001", "ETH")}; - Withdraw withdraw5{"id5", tp3, MonetaryAmount("69204866.9", "DOGE"), Withdraw::Status::kSuccess, + Withdraw withdraw5{"id5", tp3, MonetaryAmount("69204866.9", "DOGE"), Withdraw::Status::success, MonetaryAmount("1 DOGE")}; vector withdraws{withdraw1, withdraw2, withdraw3, withdraw4, withdraw5}; diff --git a/src/api/common/src/commonapi.cpp b/src/api/common/src/commonapi.cpp index 082dd05f..6cae86a7 100644 --- a/src/api/common/src/commonapi.cpp +++ b/src/api/common/src/commonapi.cpp @@ -8,7 +8,7 @@ #include "cachedresult.hpp" #include "cct_const.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_string.hpp" #include "cct_vector.hpp" diff --git a/src/api/common/src/exchangeprivateapi.cpp b/src/api/common/src/exchangeprivateapi.cpp index c5a48c01..f2b82047 100644 --- a/src/api/common/src/exchangeprivateapi.cpp +++ b/src/api/common/src/exchangeprivateapi.cpp @@ -139,7 +139,7 @@ TradedAmounts ExchangePrivate::marketTrade(MonetaryAmount from, const TradeOptio const UserRefInt userRef = static_cast(TimestampToSecondsSinceEpoch(timerStart) % static_cast(std::numeric_limits::max())); - const TradeSide side = fromCurrency == mk.base() ? TradeSide::kSell : TradeSide::kBuy; + const TradeSide side = fromCurrency == mk.base() ? TradeSide::sell : TradeSide::buy; TradeContext tradeContext(mk, side, userRef); TradeInfo tradeInfo(tradeContext, tradeOptions); TradeOptions &options = tradeInfo.options; @@ -183,7 +183,7 @@ TradedAmounts ExchangePrivate::marketTrade(MonetaryAmount from, const TradeOptio orderId = std::move(placeOrderInfo.orderId); - if (placeOrderInfo.isClosed() || tradeOptions.tradeSyncPolicy() == TradeSyncPolicy::kAsynchronous) { + if (placeOrderInfo.isClosed() || tradeOptions.tradeSyncPolicy() == TradeSyncPolicy::asynchronous) { totalTradedAmounts += placeOrderInfo.tradedAmounts(); if (placeOrderInfo.isClosed()) { log::debug("Order {} immediately closed with last traded amounts {}", orderId, @@ -223,7 +223,7 @@ TradedAmounts ExchangePrivate::marketTrade(MonetaryAmount from, const TradeOptio if (optLimitPrice) { price = *optLimitPrice; updatePriceNeeded = - (side == TradeSide::kSell && price < lastPrice) || (side == TradeSide::kBuy && price > lastPrice); + (side == TradeSide::sell && price < lastPrice) || (side == TradeSide::buy && price > lastPrice); } } if (reachedEmergencyTime || updatePriceNeeded) { @@ -262,9 +262,9 @@ enum class NextAction : int8_t { kCheckSender, kCheckReceiver, kTerminate }; NextAction InitializeNextAction(WithdrawSyncPolicy withdrawSyncPolicy) { switch (withdrawSyncPolicy) { - case WithdrawSyncPolicy::kSynchronous: + case WithdrawSyncPolicy::synchronous: return NextAction::kCheckSender; - case WithdrawSyncPolicy::kAsynchronous: + case WithdrawSyncPolicy::asynchronous: log::info("Asynchronous mode, exit after withdraw initiated"); return NextAction::kTerminate; default: @@ -321,7 +321,7 @@ DeliveredWithdrawInfo ExchangePrivate::withdraw(MonetaryAmount grossAmount, Exch sentWithdrawInfo.netEmittedAmount(), sentWithdrawInfo.fee(), initiatedWithdrawInfo.grossEmittedAmount()); log::info("Maybe because actual withdraw fee is different"); } - if (sentWithdrawInfo.withdrawStatus() == Withdraw::Status::kSuccess || isSimulatedMode) { + if (sentWithdrawInfo.withdrawStatus() == Withdraw::Status::success || isSimulatedMode) { nextAction = NextAction::kCheckReceiver; continue; // to skip the sleep and immediately check receiver } @@ -554,7 +554,7 @@ TradedAmountsVectorWithFinalAmount ExchangePrivate::queryDustSweeper(CurrencyCod PlaceOrderInfo ExchangePrivate::placeOrderProcess(MonetaryAmount &from, MonetaryAmount price, const TradeInfo &tradeInfo) { const Market mk = tradeInfo.tradeContext.market; - const bool isSell = tradeInfo.tradeContext.side == TradeSide::kSell; + const bool isSell = tradeInfo.tradeContext.side == TradeSide::sell; const MonetaryAmount volume(isSell ? from : MonetaryAmount(from / price, mk.base())); if (tradeInfo.options.isSimulation() && !isSimulatedOrderSupported()) { @@ -584,7 +584,7 @@ PlaceOrderInfo ExchangePrivate::computeSimulatedMatchedPlacedOrderInfo(MonetaryA const TradeInfo &tradeInfo) const { const bool placeSimulatedRealOrder = exchangeConfig().query.placeSimulateRealOrder; const bool isTakerStrategy = tradeInfo.options.isTakerStrategy(placeSimulatedRealOrder); - const bool isSell = tradeInfo.tradeContext.side == TradeSide::kSell; + const bool isSell = tradeInfo.tradeContext.side == TradeSide::sell; MonetaryAmount toAmount = isSell ? volume.convertTo(price) : volume; auto feeType = isTakerStrategy ? schema::ExchangeTradeFeesConfig::FeeType::Taker diff --git a/src/api/common/test/exchangeprivateapi_test.cpp b/src/api/common/test/exchangeprivateapi_test.cpp index ed301215..9ab121d7 100644 --- a/src/api/common/test/exchangeprivateapi_test.cpp +++ b/src/api/common/test/exchangeprivateapi_test.cpp @@ -128,7 +128,7 @@ TEST_F(ExchangePrivateTest, TakerTradeBaseToQuote) { PriceOptions priceOptions(PriceStrategy::taker); TradeOptions tradeOptions(priceOptions); - TradeContext tradeContext(market, TradeSide::kSell); + TradeContext tradeContext(market, TradeSide::sell); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); MonetaryAmount tradedTo("23004 EUR"); @@ -151,7 +151,7 @@ TEST_F(ExchangePrivateTest, TakerTradeQuoteToBase) { MonetaryAmount vol(from / pri, market.base()); PriceOptions priceOptions(PriceStrategy::taker); TradeOptions tradeOptions(priceOptions); - TradeContext tradeContext(market, TradeSide::kBuy); + TradeContext tradeContext(market, TradeSide::buy); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); MonetaryAmount tradedTo = vol * pri.toNeutral(); @@ -173,9 +173,9 @@ TEST_F(ExchangePrivateTest, TradeAsyncPolicyTaker) { MonetaryAmount vol(from / pri, market.base()); PriceOptions priceOptions(PriceStrategy::taker); - TradeOptions tradeOptions(priceOptions, TradeTimeoutAction::kCancel, TradeMode::kReal, seconds(10), seconds(5), - TradeTypePolicy::kDefault, TradeSyncPolicy::kAsynchronous); - TradeContext tradeContext(market, TradeSide::kBuy); + TradeOptions tradeOptions(priceOptions, TradeTimeoutAction::cancel, TradeMode::real, seconds(10), seconds(5), + TradeTypePolicy::kDefault, TradeSyncPolicy::asynchronous); + TradeContext tradeContext(market, TradeSide::buy); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); MonetaryAmount tradedTo = vol * pri.toNeutral(); @@ -196,12 +196,12 @@ TEST_F(ExchangePrivateTest, TradeAsyncPolicyMaker) { MonetaryAmount vol(from); MonetaryAmount pri(askPrice1); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; TradeContext tradeContext(market, side); PriceOptions priceOptions(PriceStrategy::maker); - TradeOptions tradeOptions(priceOptions, TradeTimeoutAction::kCancel, TradeMode::kReal, seconds(10), seconds(5), - TradeTypePolicy::kDefault, TradeSyncPolicy::kAsynchronous); + TradeOptions tradeOptions(priceOptions, TradeTimeoutAction::cancel, TradeMode::real, seconds(10), seconds(5), + TradeTypePolicy::kDefault, TradeSyncPolicy::asynchronous); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); EXPECT_CALL(exchangePublic, queryOrderBook(market, testing::_)).WillOnce(testing::Return(marketOrderBook1)); @@ -222,7 +222,7 @@ TEST_F(ExchangePrivateTest, MakerTradeBaseToQuote) { MonetaryAmount vol(from); MonetaryAmount pri(askPrice1); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; TradeContext tradeContext(market, side); PriceOptions priceOptions(PriceStrategy::maker); @@ -255,13 +255,13 @@ TEST_F(ExchangePrivateTest, MakerTradeQuoteToBase) { MonetaryAmount from(10000, market.quote()); MonetaryAmount pri1(bidPrice1); MonetaryAmount pri2(bidPrice2); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; TradeContext tradeContext(market, side); MonetaryAmount vol1(from / pri1, market.base()); MonetaryAmount vol2(from / pri2, market.base()); - TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::kCancel, TradeMode::kReal, Duration::max(), + TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::cancel, TradeMode::real, Duration::max(), Duration::zero(), TradeTypePolicy::kForceMultiTrade); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); @@ -336,8 +336,8 @@ TEST_F(ExchangePrivateTest, SimulatedOrderShouldNotCallPlaceOrder) { MonetaryAmount vol(from); MonetaryAmount pri(askPrice1); - TradeSide side = TradeSide::kSell; - TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::kCancel, TradeMode::kSimulation, Duration::max(), + TradeSide side = TradeSide::sell; + TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::cancel, TradeMode::simulation, Duration::max(), Duration::zero(), TradeTypePolicy::kForceMultiTrade); TradeContext tradeContext(market, side); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); @@ -358,12 +358,12 @@ TEST_F(ExchangePrivateTest, MakerTradeQuoteToBaseEmergencyTakerTrade) { MonetaryAmount from(10000, market.quote()); MonetaryAmount pri1(bidPrice1); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; TradeContext tradeContext(market, side); MonetaryAmount vol1(from / pri1, market.base()); - TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::kMatch, TradeMode::kReal, Duration::zero(), + TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::match, TradeMode::real, Duration::zero(), Duration::zero(), TradeTypePolicy::kForceMultiTrade); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); @@ -405,12 +405,12 @@ TEST_F(ExchangePrivateTest, MakerTradeQuoteToBaseTimeout) { MonetaryAmount from(5000, market.quote()); MonetaryAmount pri1(bidPrice1); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; TradeContext tradeContext(market, side); MonetaryAmount vol1(from / pri1, market.base()); - TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::kCancel, TradeMode::kReal, Duration::zero(), + TradeOptions tradeOptions(PriceOptions{}, TradeTimeoutAction::cancel, TradeMode::real, Duration::zero(), Duration::zero(), TradeTypePolicy::kForceMultiTrade); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); @@ -471,8 +471,8 @@ class ExchangePrivateWithdrawTest : public ExchangePrivateTest { ReceivedWithdrawInfo receivedWithdrawInfo{"deposit-id", netEmittedAmount}; SentWithdrawInfo defaultWithdrawInfo{currencyCode}; - SentWithdrawInfo unsentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::kProcessing}; - SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::kSuccess}; + SentWithdrawInfo unsentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::processing}; + SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::success}; }; class ExchangePrivateWithdrawRealTest : public ExchangePrivateWithdrawTest { @@ -483,7 +483,7 @@ class ExchangePrivateWithdrawRealTest : public ExchangePrivateWithdrawTest { .WillOnce(testing::Return(initiatedWithdrawInfo)); } - WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::kSynchronous, WithdrawOptions::Mode::kReal}; + WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::synchronous, WithdrawOptions::Mode::kReal}; }; TEST_F(ExchangePrivateWithdrawRealTest, WithdrawSynchronousReceivedAfterSent) { @@ -496,13 +496,13 @@ TEST_F(ExchangePrivateWithdrawRealTest, WithdrawSynchronousReceivedAfterSent) { EXPECT_CALL(exchangePrivate, queryRecentWithdraws(testing::_)) .WillOnce(testing::Return(WithdrawsSet{ - Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::kProcessing, fee}})); + Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::processing, fee}})); EXPECT_CALL(destinationExchangePrivate, queryWithdrawDelivery(initiatedWithdrawInfo, unsentWithdrawInfo)) .WillOnce(testing::Return(ReceivedWithdrawInfo{})); EXPECT_CALL(exchangePrivate, queryRecentWithdraws(testing::_)) .WillOnce(testing::Return( - WithdrawsSet{Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::kSuccess, fee}})); + WithdrawsSet{Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::success, fee}})); EXPECT_CALL(destinationExchangePrivate, queryWithdrawDelivery(initiatedWithdrawInfo, sentWithdrawInfo)) .Times(2) .WillRepeatedly(testing::Return(ReceivedWithdrawInfo{})); @@ -533,7 +533,7 @@ TEST_F(ExchangePrivateWithdrawRealTest, WithdrawSynchronousReceivedBeforeSent) { class ExchangePrivateWithdrawSimulationTest : public ExchangePrivateWithdrawTest { protected: - WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::kSynchronous, WithdrawOptions::Mode::kSimulation}; + WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::synchronous, WithdrawOptions::Mode::kSimulation}; }; TEST_F(ExchangePrivateWithdrawSimulationTest, SimulatedWithdrawalShouldNotCallLaunchWithdraw) { @@ -560,7 +560,7 @@ TEST_F(ExchangePrivateTest, WithdrawAsynchronous) { EXPECT_EQ(exchangePrivate.withdraw( grossAmount, destinationExchangePrivate, - WithdrawOptions(Duration{}, WithdrawSyncPolicy::kAsynchronous, WithdrawOptions::Mode::kReal)), + WithdrawOptions(Duration{}, WithdrawSyncPolicy::asynchronous, WithdrawOptions::Mode::kReal)), deliveredWithdrawInfo); } @@ -593,7 +593,7 @@ class ExchangePrivateDustSweeperTest : public ExchangePrivateTest { MonetaryAmount vol(from); Market mk{from.currencyCode(), pri.currencyCode()}; - TradeContext tradeContext(mk, TradeSide::kSell); + TradeContext tradeContext(mk, TradeSide::sell); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); MonetaryAmount tradedTo = vol.toNeutral() * pri; @@ -619,7 +619,7 @@ class ExchangePrivateDustSweeperTest : public ExchangePrivateTest { MonetaryAmount from = to.toNeutral() * bidPri; MonetaryAmount vol(from / askPri, mk.base()); - TradeContext tradeContext(mk, TradeSide::kBuy); + TradeContext tradeContext(mk, TradeSide::buy); TradeInfo tradeInfo = computeTradeInfo(tradeContext, tradeOptions); TradedAmounts tradedAmounts(MonetaryAmount{success ? from : MonetaryAmount(0), askPri.currencyCode()}, diff --git a/src/api/exchanges/src/binanceprivateapi.cpp b/src/api/exchanges/src/binanceprivateapi.cpp index 4fcc8910..9f33a4d9 100644 --- a/src/api/exchanges/src/binanceprivateapi.cpp +++ b/src/api/exchanges/src/binanceprivateapi.cpp @@ -24,7 +24,7 @@ #include "binancepublicapi.hpp" #include "cachedresult.hpp" #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_smallvector.hpp" #include "cct_string.hpp" @@ -376,7 +376,7 @@ void FillOrders(const OrdersConstraints& ordersConstraints, std::span().begin())>; @@ -496,15 +496,15 @@ namespace { Deposit::Status DepositStatusFromCode(int statusInt) { switch (statusInt) { case kDepositPendingCode: - return Deposit::Status::kProcessing; + return Deposit::Status::processing; case kDepositSuccessCode: [[fallthrough]]; case kDepositCreditedButCannotWithdrawCode: - return Deposit::Status::kSuccess; + return Deposit::Status::success; case kDepositWrongDepositCode: - return Deposit::Status::kFailureOrRejected; + return Deposit::Status::failed; case kDepositWaitingUserConfirmCode: - return Deposit::Status::kProcessing; + return Deposit::Status::processing; default: throw exception("Unknown deposit status code {} from Binance", statusInt); } @@ -561,37 +561,37 @@ Withdraw::Status WithdrawStatusFromStatusStr(int statusInt, bool logStatus) { if (logStatus) { log::warn("Awaiting Approval"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; case kWithdrawProcessingCode: if (logStatus) { log::info("Processing withdraw..."); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; case kWithdrawEmailSentCode: if (logStatus) { log::warn("Email was sent"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; case kWithdrawCancelledCode: // NOLINT(bugprone-branch-clone) if (logStatus) { log::warn("Withdraw cancelled"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; case kWithdrawRejectedCode: if (logStatus) { log::error("Withdraw rejected"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; case kWithdrawFailureCode: if (logStatus) { log::error("Withdraw failed"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; case kWithdrawCompletedCode: if (logStatus) { log::info("Withdraw completed!"); } - return Withdraw::Status::kSuccess; + return Withdraw::Status::success; default: throw exception("Unknown withdraw status code {}", statusInt); } @@ -796,8 +796,8 @@ PlaceOrderInfo BinancePrivate::placeOrder(MonetaryAmount from, MonetaryAmount vo OrderInfo BinancePrivate::queryOrder(OrderIdView orderId, const TradeContext& tradeContext, HttpRequestType requestType) { const Market mk = tradeContext.market; - const CurrencyCode fromCurrencyCode = tradeContext.side == TradeSide::kSell ? mk.base() : mk.quote(); - const CurrencyCode toCurrencyCode = tradeContext.side == TradeSide::kBuy ? mk.base() : mk.quote(); + const CurrencyCode fromCurrencyCode = tradeContext.side == TradeSide::sell ? mk.base() : mk.quote(); + const CurrencyCode toCurrencyCode = tradeContext.side == TradeSide::buy ? mk.base() : mk.quote(); const string assetsStr = mk.assetsPairStrUpper(); const std::string_view assets(assetsStr); const auto result = PrivateQuery( diff --git a/src/api/exchanges/src/binancepublicapi.cpp b/src/api/exchanges/src/binancepublicapi.cpp index 1fd90c79..4712790c 100644 --- a/src/api/exchanges/src/binancepublicapi.cpp +++ b/src/api/exchanges/src/binancepublicapi.cpp @@ -19,7 +19,7 @@ #include "cachedresult.hpp" #include "cct_const.hpp" #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_string.hpp" #include "coincenterinfo.hpp" @@ -431,7 +431,7 @@ PublicTradeVector BinancePublic::queryLastTrades(Market mk, int nbTrades) { MonetaryAmount price(elem.price, mk.quote()); MonetaryAmount amount(elem.qty, mk.base()); int64_t millisecondsSinceEpoch = elem.time; - TradeSide tradeSide = elem.isBuyerMaker ? TradeSide::kSell : TradeSide::kBuy; + TradeSide tradeSide = elem.isBuyerMaker ? TradeSide::sell : TradeSide::buy; ret.emplace_back(tradeSide, amount, price, TimePoint(milliseconds(millisecondsSinceEpoch))); } diff --git a/src/api/exchanges/src/bithumbprivateapi.cpp b/src/api/exchanges/src/bithumbprivateapi.cpp index c01d96cb..52a9949f 100644 --- a/src/api/exchanges/src/bithumbprivateapi.cpp +++ b/src/api/exchanges/src/bithumbprivateapi.cpp @@ -24,7 +24,7 @@ #include "cachedresult.hpp" #include "cct_exception.hpp" #include "cct_fixedcapacityvector.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_smallvector.hpp" #include "cct_string.hpp" @@ -480,7 +480,7 @@ OrderVectorType QueryOrders(const OrdersConstraints& ordersConstraints, Exchange MonetaryAmount matchedVolume = originalVolume - remainingVolume; MonetaryAmount price(orderDetails.price, priceCur); TradeSide side = - orderDetails.type == schema::bithumb::TransactionTypeEnum::bid ? TradeSide::kBuy : TradeSide::kSell; + orderDetails.type == schema::bithumb::TransactionTypeEnum::bid ? TradeSide::buy : TradeSide::sell; if constexpr (std::is_same_v) { if (remainingVolume == 0) { @@ -563,7 +563,7 @@ MonetaryAmount RetrieveNetEmittedAmountFromTrxJson(const schema::bithumb::UserTr Withdraw::Status RetrieveWithdrawStatusFromTrxJson(const schema::bithumb::UserTransactions::UserTransaction& trx) { const auto searchGb = StringToIntegral(trx.search); - return searchGb == kSearchGbOnGoingWithdrawals ? Withdraw::Status::kProcessing : Withdraw::Status::kSuccess; + return searchGb == kSearchGbOnGoingWithdrawals ? Withdraw::Status::processing : Withdraw::Status::success; } enum class UserTransactionEnum : int8_t { @@ -705,7 +705,7 @@ ClosedOrderVector BithumbPrivate::queryClosedOrders(const OrdersConstraints& clo const auto searchGb = StringToIntegral(trx.search); - TradeSide side = searchGb == kSearchGbBuy ? TradeSide::kBuy : TradeSide::kSell; + TradeSide side = searchGb == kSearchGbBuy ? TradeSide::buy : TradeSide::sell; closedOrders.emplace_back(std::move(id), matchedVolume, price, timestamp, timestamp, side); } @@ -738,7 +738,7 @@ DepositsSet BithumbPrivate::queryRecentDeposits(const DepositsConstraints& depos string id = GenerateDepositIdFromTrx(timestamp, trx); // No status information returned by Bithumb. Defaulting to Success - deposits.emplace_back(std::move(id), timestamp, RetrieveAmountFromTrxJson(trx), Deposit::Status::kSuccess); + deposits.emplace_back(std::move(id), timestamp, RetrieveAmountFromTrxJson(trx), Deposit::Status::success); } DepositsSet depositsSet(std::move(deposits)); log::info("Retrieved {} recent deposits for {}", depositsSet.size(), exchangeName()); @@ -943,7 +943,7 @@ CurlPostData OrderInfoPostData(Market mk, TradeSide side, OrderIdView orderId) { ret.emplace_back(kOrderCurrencyParamStr, baseStr); ret.emplace_back(kPaymentCurParamStr, quoteStr); - ret.emplace_back(kTypeParamStr, side == TradeSide::kSell ? "ask" : "bid"); + ret.emplace_back(kTypeParamStr, side == TradeSide::sell ? "ask" : "bid"); ret.emplace_back(kOrderIdParamStr, orderId); return ret; diff --git a/src/api/exchanges/src/bithumbpublicapi.cpp b/src/api/exchanges/src/bithumbpublicapi.cpp index 5cac7492..87530da9 100644 --- a/src/api/exchanges/src/bithumbpublicapi.cpp +++ b/src/api/exchanges/src/bithumbpublicapi.cpp @@ -346,7 +346,7 @@ PublicTradeVector BithumbPublic::queryLastTrades(Market mk, int nbTrades) { MonetaryAmount amount(detail.units_traded, mk.base()); MonetaryAmount price(detail.price, mk.quote()); // Korea time (UTC+9) in this format: "2021-11-29 03:29:35" - TradeSide tradeSide = detail.type == schema::bithumb::TransactionTypeEnum::bid ? TradeSide::kBuy : TradeSide::kSell; + TradeSide tradeSide = detail.type == schema::bithumb::TransactionTypeEnum::bid ? TradeSide::buy : TradeSide::sell; ret.emplace_back(tradeSide, amount, price, EpochTime(detail.transaction_date)); } diff --git a/src/api/exchanges/src/huobiprivateapi.cpp b/src/api/exchanges/src/huobiprivateapi.cpp index c1ccb9c6..75ba9772 100644 --- a/src/api/exchanges/src/huobiprivateapi.cpp +++ b/src/api/exchanges/src/huobiprivateapi.cpp @@ -234,10 +234,10 @@ Wallet HuobiPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { namespace { TradeSide TradeSideFromTypeStr(std::string_view typeSide) { if (typeSide.starts_with("buy")) { - return TradeSide::kBuy; + return TradeSide::buy; } if (typeSide.starts_with("sell")) { - return TradeSide::kSell; + return TradeSide::sell; } throw exception("Unable to detect order side for type '{}'", typeSide); } @@ -367,7 +367,7 @@ OpenedOrderVector HuobiPrivate::queryOpenedOrders(const OrdersConstraints& opene MonetaryAmount matchedVolume(orderDetails.filledAmount, volumeCur); MonetaryAmount remainingVolume = originalVolume - matchedVolume; MonetaryAmount price(orderDetails.price, priceCur); - TradeSide side = orderDetails.type.starts_with("buy") ? TradeSide::kBuy : TradeSide::kSell; + TradeSide side = orderDetails.type.starts_with("buy") ? TradeSide::buy : TradeSide::sell; openedOrders.emplace_back(std::move(id), matchedVolume, remainingVolume, price, placedTime, side); } @@ -393,13 +393,13 @@ int HuobiPrivate::cancelOpenedOrders(const OrdersConstraints& openedOrdersConstr namespace { Deposit::Status DepositStatusFromStatusStr(std::string_view statusStr) { if (statusStr == "unknown") { - return Deposit::Status::kInitial; + return Deposit::Status::initial; } if (statusStr == "confirming") { - return Deposit::Status::kProcessing; + return Deposit::Status::processing; } if (statusStr == "confirmed" || statusStr == "safe" || statusStr == "orphan") { - return Deposit::Status::kSuccess; + return Deposit::Status::success; } throw exception("Unexpected deposit status '{}' from Huobi", statusStr); } @@ -450,80 +450,80 @@ Withdraw::Status WithdrawStatusFromStatusStr(std::string_view statusStr, bool lo if (logStatus) { log::debug("Awaiting verification"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "failed") { if (logStatus) { log::error("Verification failed"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } if (statusStr == "submitted") { if (logStatus) { log::debug("Withdraw request submitted successfully"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "reexamine") { if (logStatus) { log::warn("Under examination for withdraw validation"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } // Let's also check without typo error ('canceled' with the typo is from the official documentation) if (statusStr == "canceled" || statusStr == "cancelled") { if (logStatus) { log::error("Withdraw canceled"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } if (statusStr == "pass") { if (logStatus) { log::debug("Withdraw validation passed"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "reject") { if (logStatus) { log::error("Withdraw validation rejected"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } if (statusStr == "pre-transfer") { if (logStatus) { log::debug("Withdraw is about to be released"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "wallet-transfer") { if (logStatus) { log::debug("On-chain transfer initiated"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "wallet-reject") { if (logStatus) { log::error("Transfer rejected by chain"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } if (statusStr == "confirmed") { if (logStatus) { log::debug("On-chain transfer completed with one confirmation"); } - return Withdraw::Status::kSuccess; + return Withdraw::Status::success; } if (statusStr == "confirm-error") { if (logStatus) { log::error("On-chain transfer failed to get confirmation"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } if (statusStr == "repealed") { if (logStatus) { log::error("Withdraw terminated by system"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } throw exception("unknown status value '{}'", statusStr); } diff --git a/src/api/exchanges/src/huobipublicapi.cpp b/src/api/exchanges/src/huobipublicapi.cpp index 2bdd8771..af9f57ca 100644 --- a/src/api/exchanges/src/huobipublicapi.cpp +++ b/src/api/exchanges/src/huobipublicapi.cpp @@ -478,8 +478,8 @@ PublicTradeVector HuobiPublic::queryLastTrades(Market mk, int nbTrades) { const MonetaryAmount price(detail2.price, mk.quote()); const int64_t millisecondsSinceEpoch = detail2.ts; const TradeSide tradeSide = - detail2.direction == schema::huobi::MarketHistoryTrade::Trade::TradeData::Direction::buy ? TradeSide::kBuy - : TradeSide::kSell; + detail2.direction == schema::huobi::MarketHistoryTrade::Trade::TradeData::Direction::buy ? TradeSide::buy + : TradeSide::sell; ret.emplace_back(tradeSide, amount, price, TimePoint(milliseconds(millisecondsSinceEpoch))); diff --git a/src/api/exchanges/src/krakenprivateapi.cpp b/src/api/exchanges/src/krakenprivateapi.cpp index 18779aaf..dfb6d0de 100644 --- a/src/api/exchanges/src/krakenprivateapi.cpp +++ b/src/api/exchanges/src/krakenprivateapi.cpp @@ -167,7 +167,7 @@ BalancePortfolio KrakenPrivate::queryAccountBalance(const BalanceOptions& balanc for (const OpenedOrder& order : queryOpenedOrders()) { MonetaryAmount remVolume = order.remainingVolume(); switch (order.side()) { - case TradeSide::kBuy: { + case TradeSide::buy: { MonetaryAmount price = order.price(); auto lb = std::ranges::lower_bound(balanceAmounts, price, compByCurrency); if (lb != balanceAmounts.end() && lb->currencyCode() == price.currencyCode()) { @@ -177,7 +177,7 @@ BalancePortfolio KrakenPrivate::queryAccountBalance(const BalanceOptions& balanc } break; } - case TradeSide::kSell: { + case TradeSide::sell: { auto lb = std::ranges::lower_bound(balanceAmounts, remVolume, compByCurrency); if (lb != balanceAmounts.end() && lb->currencyCode() == remVolume.currencyCode()) { *lb -= remVolume; @@ -343,7 +343,7 @@ ClosedOrderVector KrakenPrivate::queryClosedOrders(const OrdersConstraints& clos TimePoint matchedTime = TimePointFromKrakenTime(orderDetails.closetm); - TradeSide side = descrPart.type == "buy" ? TradeSide::kBuy : TradeSide::kSell; + TradeSide side = descrPart.type == "buy" ? TradeSide::buy : TradeSide::sell; closedOrders.emplace_back(orderId, matchedVolume, price, placedTime, matchedTime, side); } @@ -390,7 +390,7 @@ OpenedOrderVector KrakenPrivate::queryOpenedOrders(const OrdersConstraints& open MonetaryAmount matchedVolume(orderDetails.vol_exec, volumeCur); MonetaryAmount remainingVolume = originalVolume - matchedVolume; MonetaryAmount price(descrPart.price, priceCur); - TradeSide side = descrPart.type == "buy" ? TradeSide::kBuy : TradeSide::kSell; + TradeSide side = descrPart.type == "buy" ? TradeSide::buy : TradeSide::sell; TimePoint placedTime = TimePointFromKrakenTime(orderDetails.opentm); if (!openedOrdersConstraints.validatePlacedTime(placedTime)) { @@ -420,12 +420,12 @@ int KrakenPrivate::cancelOpenedOrders(const OrdersConstraints& openedOrdersConst namespace { Deposit::Status DepositStatusFromStatus(schema::kraken::DepositStatus::Deposit::Status depositStatus) { if (depositStatus == schema::kraken::DepositStatus::Deposit::Status::Settled) { - return Deposit::Status::kProcessing; + return Deposit::Status::processing; } if (depositStatus == schema::kraken::DepositStatus::Deposit::Status::Success) { - return Deposit::Status::kSuccess; + return Deposit::Status::success; } - return Deposit::Status::kFailureOrRejected; + return Deposit::Status::failed; } } // namespace @@ -467,16 +467,16 @@ DepositsSet KrakenPrivate::queryRecentDeposits(const DepositsConstraints& deposi namespace { Withdraw::Status WithdrawStatusFromStatusStr(std::string_view statusStr) { if (statusStr == "Initial" || statusStr == "Pending") { - return Withdraw::Status::kInitial; + return Withdraw::Status::initial; } if (statusStr == "Settled" || statusStr == "On hold") { - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (statusStr == "Success") { - return Withdraw::Status::kSuccess; + return Withdraw::Status::success; } if (statusStr == "Failure") { - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } throw exception("Unrecognized withdraw status '{}' from Kraken", statusStr); } diff --git a/src/api/exchanges/src/krakenpublicapi.cpp b/src/api/exchanges/src/krakenpublicapi.cpp index 64ae1785..9d352c6e 100644 --- a/src/api/exchanges/src/krakenpublicapi.cpp +++ b/src/api/exchanges/src/krakenpublicapi.cpp @@ -344,7 +344,7 @@ PublicTradeVector KrakenPublic::queryLastTrades(Market mk, int nbLastTrades) { const MonetaryAmount price(std::get(det[0]), mk.quote()); const MonetaryAmount amount(std::get(det[1]), mk.base()); const auto millisecondsSinceEpoch = static_cast(std::get(det[2]) * 1000); - const TradeSide tradeSide = std::get(det[3]) == "b" ? TradeSide::kBuy : TradeSide::kSell; + const TradeSide tradeSide = std::get(det[3]) == "b" ? TradeSide::buy : TradeSide::sell; ret.emplace_back(tradeSide, amount, price, TimePoint(milliseconds(millisecondsSinceEpoch))); } diff --git a/src/api/exchanges/src/kucoinprivateapi.cpp b/src/api/exchanges/src/kucoinprivateapi.cpp index d09e5dc6..afee8aae 100644 --- a/src/api/exchanges/src/kucoinprivateapi.cpp +++ b/src/api/exchanges/src/kucoinprivateapi.cpp @@ -328,7 +328,7 @@ void FillOrders(const OrdersConstraints& ordersConstraints, CurlHandle& curlHand const MonetaryAmount matchedVolume(orderDetails.dealSize, volumeCur); const MonetaryAmount price(orderDetails.price, priceCur); - const TradeSide side = orderDetails.side == "buy" ? TradeSide::kBuy : TradeSide::kSell; + const TradeSide side = orderDetails.side == "buy" ? TradeSide::buy : TradeSide::sell; if constexpr (std::is_same_v) { const MonetaryAmount originalVolume(orderDetails.size, volumeCur); @@ -383,13 +383,13 @@ int KucoinPrivate::cancelOpenedOrders(const OrdersConstraints& openedOrdersConst namespace { Deposit::Status DepositStatusFromStatus(schema::kucoin::V1Deposits::Data::Item::Status depositStatus) { if (depositStatus == schema::kucoin::V1Deposits::Data::Item::Status::SUCCESS) { - return Deposit::Status::kSuccess; + return Deposit::Status::success; } if (depositStatus == schema::kucoin::V1Deposits::Data::Item::Status::PROCESSING) { - return Deposit::Status::kProcessing; + return Deposit::Status::processing; } if (depositStatus == schema::kucoin::V1Deposits::Data::Item::Status::FAILURE) { - return Deposit::Status::kFailureOrRejected; + return Deposit::Status::failed; } throw exception("Unrecognized deposit status '{}' from Kucoin", static_cast(depositStatus)); } @@ -450,25 +450,25 @@ Withdraw::Status WithdrawStatusFromStatus(schema::kucoin::V1Withdrawals::Data::I if (logStatus) { log::debug("Processing"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (status == schema::kucoin::V1Withdrawals::Data::Item::Status::WALLET_PROCESSING) { if (logStatus) { log::debug("Wallet processing"); } - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; } if (status == schema::kucoin::V1Withdrawals::Data::Item::Status::SUCCESS) { if (logStatus) { log::debug("Success"); } - return Withdraw::Status::kSuccess; + return Withdraw::Status::success; } if (status == schema::kucoin::V1Withdrawals::Data::Item::Status::FAILURE) { if (logStatus) { log::warn("Failure"); } - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; } throw exception("unknown status value '{}' returned by Kucoin", static_cast(status)); } diff --git a/src/api/exchanges/src/kucoinpublicapi.cpp b/src/api/exchanges/src/kucoinpublicapi.cpp index 29766bf9..8078e094 100644 --- a/src/api/exchanges/src/kucoinpublicapi.cpp +++ b/src/api/exchanges/src/kucoinpublicapi.cpp @@ -381,9 +381,8 @@ PublicTradeVector KucoinPublic::queryLastTrades(Market mk, int nbTrades) { const MonetaryAmount price(detail.price, mk.quote()); // time is in nanoseconds const int64_t millisecondsSinceEpoch = static_cast(detail.time / 1000000UL); - const TradeSide tradeSide = detail.side == schema::kucoin::V1MarketHistories::V1MarketHistory::Side::buy - ? TradeSide::kBuy - : TradeSide::kSell; + const TradeSide tradeSide = + detail.side == schema::kucoin::V1MarketHistories::V1MarketHistory::Side::buy ? TradeSide::buy : TradeSide::sell; ret.emplace_back(tradeSide, amount, price, TimePoint(milliseconds(millisecondsSinceEpoch))); } diff --git a/src/api/exchanges/src/upbitprivateapi.cpp b/src/api/exchanges/src/upbitprivateapi.cpp index acc4016a..fc4e87d0 100644 --- a/src/api/exchanges/src/upbitprivateapi.cpp +++ b/src/api/exchanges/src/upbitprivateapi.cpp @@ -345,7 +345,7 @@ void FillOrders(const OrdersConstraints& ordersConstraints, CurlHandle& curlHand const MonetaryAmount matchedVolume(orderDetails.executed_volume, volumeCur); const MonetaryAmount price(orderDetails.price, priceCur); - const TradeSide side = orderDetails.side == "bid" ? TradeSide::kBuy : TradeSide::kSell; + const TradeSide side = orderDetails.side == "bid" ? TradeSide::buy : TradeSide::sell; if constexpr (kIsOpenedOrder) { const MonetaryAmount remainingVolume(orderDetails.remaining_volume, volumeCur); @@ -401,7 +401,7 @@ namespace { Deposit::Status DepositStatusFromStatus(schema::upbit::V1Deposit::State state) { switch (state) { case schema::upbit::V1Deposit::State::ACCEPTED: - return Deposit::Status::kSuccess; + return Deposit::Status::success; case schema::upbit::V1Deposit::State::CANCELLED: [[fallthrough]]; case schema::upbit::V1Deposit::State::REJECTED: @@ -409,11 +409,11 @@ Deposit::Status DepositStatusFromStatus(schema::upbit::V1Deposit::State state) { case schema::upbit::V1Deposit::State::TRAVEL_RULE_SUSPECTED: [[fallthrough]]; case schema::upbit::V1Deposit::State::REFUNDED: - return Deposit::Status::kFailureOrRejected; + return Deposit::Status::failed; case schema::upbit::V1Deposit::State::PROCESSING: [[fallthrough]]; case schema::upbit::V1Deposit::State::REFUNDING: - return Deposit::Status::kProcessing; + return Deposit::Status::processing; default: throw exception("Unrecognized deposit status '{}' from Upbit", static_cast(state)); } @@ -475,11 +475,11 @@ namespace { Withdraw::Status WithdrawStatusFromStatus(schema::upbit::V1Withdraw::State status) { switch (status) { case schema::upbit::V1Withdraw::State::WAITING: - return Withdraw::Status::kInitial; + return Withdraw::Status::initial; case schema::upbit::V1Withdraw::State::PROCESSING: - return Withdraw::Status::kProcessing; + return Withdraw::Status::processing; case schema::upbit::V1Withdraw::State::DONE: - return Withdraw::Status::kSuccess; + return Withdraw::Status::success; case schema::upbit::V1Withdraw::State::FAILED: [[fallthrough]]; case schema::upbit::V1Withdraw::State::CANCELLED: @@ -487,7 +487,7 @@ Withdraw::Status WithdrawStatusFromStatus(schema::upbit::V1Withdraw::State statu case schema::upbit::V1Withdraw::State::CANCELED: [[fallthrough]]; case schema::upbit::V1Withdraw::State::REJECTED: - return Withdraw::Status::kFailureOrRejected; + return Withdraw::Status::failed; default: throw exception("Unrecognized withdraw status '{}' from Upbit", static_cast(status)); } diff --git a/src/api/exchanges/src/upbitpublicapi.cpp b/src/api/exchanges/src/upbitpublicapi.cpp index c4459e8e..098c0a06 100644 --- a/src/api/exchanges/src/upbitpublicapi.cpp +++ b/src/api/exchanges/src/upbitpublicapi.cpp @@ -270,8 +270,7 @@ PublicTradeVector UpbitPublic::queryLastTrades(Market mk, int nbTrades) { MonetaryAmount amount(detail.trade_volume, mk.base()); MonetaryAmount price(detail.trade_price, mk.quote()); int64_t millisecondsSinceEpoch = detail.timestamp; - TradeSide tradeSide = - detail.ask_bid == schema::upbit::V1TradesTick::AskBid::BID ? TradeSide::kBuy : TradeSide::kSell; + TradeSide tradeSide = detail.ask_bid == schema::upbit::V1TradesTick::AskBid::BID ? TradeSide::buy : TradeSide::sell; ret.emplace_back(tradeSide, amount, price, TimePoint(milliseconds(millisecondsSinceEpoch))); } diff --git a/src/api/exchanges/test/bithumb_place_order_test.cpp b/src/api/exchanges/test/bithumb_place_order_test.cpp index 398000de..297830da 100644 --- a/src/api/exchanges/test/bithumb_place_order_test.cpp +++ b/src/api/exchanges/test/bithumb_place_order_test.cpp @@ -66,8 +66,7 @@ TEST_F(BithumbPrivateAPIPlaceOrderTest, PlaceOrderShortenDecimals) { {"/info/orders?endpoint=%2Finfo%2Forders&order_currency=ETH&payment_currency=EUR&type=ask&order_id=ID0001", R"({"status":"0000","data":[{"order_id":"ID0001"}]})"}}); - PlaceOrderInfo placeOrderInfo = - placeOrder(MonetaryAmount("2.000001ETH"), MonetaryAmount("1500EUR"), TradeSide::kSell); + PlaceOrderInfo placeOrderInfo = placeOrder(MonetaryAmount("2.000001ETH"), MonetaryAmount("1500EUR"), TradeSide::sell); EXPECT_EQ(placeOrderInfo.orderId, "ID0001"); } @@ -78,8 +77,7 @@ TEST_F(BithumbPrivateAPIPlaceOrderTest, NoPlaceOrderTooSmallAmount) { "place?endpoint=%2Ftrade%2Fplace&order_currency=ETH&payment_currency=EUR&type=ask&price=1500&units=0.000001", R"({"status":"5600","message":"수량은 소수점 4자"})"}}); - PlaceOrderInfo placeOrderInfo = - placeOrder(MonetaryAmount("0.000001ETH"), MonetaryAmount("1500EUR"), TradeSide::kSell); + PlaceOrderInfo placeOrderInfo = placeOrder(MonetaryAmount("0.000001ETH"), MonetaryAmount("1500EUR"), TradeSide::sell); EXPECT_EQ(placeOrderInfo.orderId, "UndefinedId"); } } // namespace cct::api \ No newline at end of file diff --git a/src/api/exchanges/test/exchangecommonapi_test.hpp b/src/api/exchanges/test/exchangecommonapi_test.hpp index f6a91ac3..d1e48317 100644 --- a/src/api/exchanges/test/exchangecommonapi_test.hpp +++ b/src/api/exchanges/test/exchangecommonapi_test.hpp @@ -289,7 +289,7 @@ class TestAPI { }; auto [smallAmountIt, bigAmountIt] = std::ranges::minmax_element(lastTrades, compareTradedVolume); - TradeOptions tradeOptions(TradeMode::kSimulation); + TradeOptions tradeOptions(TradeMode::simulation); MonetaryAmount smallFrom = smallAmountIt->amount() / 100; MonetaryAmount bigFrom = bigAmountIt->amount().toNeutral() * bigAmountIt->price() * 100; EXPECT_GT(exchangePrivateOpt->trade(smallFrom, mk.quote(), tradeOptions).to, 0); diff --git a/src/basic-objects/include/apioutputtype.hpp b/src/basic-objects/include/apioutputtype.hpp index 4e35bcd1..93aba0d2 100644 --- a/src/basic-objects/include/apioutputtype.hpp +++ b/src/basic-objects/include/apioutputtype.hpp @@ -3,7 +3,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct { diff --git a/src/basic-objects/include/apiquerytypeenum.hpp b/src/basic-objects/include/apiquerytypeenum.hpp index 3c5db4e5..c5a40e17 100644 --- a/src/basic-objects/include/apiquerytypeenum.hpp +++ b/src/basic-objects/include/apiquerytypeenum.hpp @@ -2,7 +2,7 @@ #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct { diff --git a/src/basic-objects/include/cct_const.hpp b/src/basic-objects/include/cct_const.hpp index 9f69c136..ebdf131c 100644 --- a/src/basic-objects/include/cct_const.hpp +++ b/src/basic-objects/include/cct_const.hpp @@ -3,7 +3,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct { diff --git a/src/basic-objects/include/currencycode.hpp b/src/basic-objects/include/currencycode.hpp index b1e4ae40..1786cc2e 100644 --- a/src/basic-objects/include/currencycode.hpp +++ b/src/basic-objects/include/currencycode.hpp @@ -13,7 +13,7 @@ #include "cct_format.hpp" #include "cct_hash.hpp" #include "cct_invalid_argument_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" #include "generic-object-json.hpp" #include "toupperlower.hpp" diff --git a/src/basic-objects/include/generic-object-json.hpp b/src/basic-objects/include/generic-object-json.hpp index 63bd79b3..cc2a2499 100644 --- a/src/basic-objects/include/generic-object-json.hpp +++ b/src/basic-objects/include/generic-object-json.hpp @@ -3,7 +3,7 @@ #include #include "cct_cctype.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct::details { diff --git a/src/basic-objects/include/market.hpp b/src/basic-objects/include/market.hpp index 3f843d5b..0d2ffbf9 100644 --- a/src/basic-objects/include/market.hpp +++ b/src/basic-objects/include/market.hpp @@ -7,7 +7,7 @@ #include #include "cct_format.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" #include "currencycode.hpp" #include "generic-object-json.hpp" diff --git a/src/basic-objects/include/monetaryamount.hpp b/src/basic-objects/include/monetaryamount.hpp index da954cd5..2d2ab54e 100644 --- a/src/basic-objects/include/monetaryamount.hpp +++ b/src/basic-objects/include/monetaryamount.hpp @@ -13,7 +13,7 @@ #include "cct_format.hpp" #include "cct_hash.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_string.hpp" #include "currencycode.hpp" diff --git a/src/basic-objects/include/priceoptionsdef.hpp b/src/basic-objects/include/priceoptionsdef.hpp index 9129fed6..bce455e4 100644 --- a/src/basic-objects/include/priceoptionsdef.hpp +++ b/src/basic-objects/include/priceoptionsdef.hpp @@ -4,7 +4,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct { enum class PriceStrategy : int8_t { diff --git a/src/basic-objects/src/coincentercommandtype.cpp b/src/basic-objects/src/coincentercommandtype.cpp index 70d5454c..9bf9f861 100644 --- a/src/basic-objects/src/coincentercommandtype.cpp +++ b/src/basic-objects/src/coincentercommandtype.cpp @@ -3,7 +3,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" namespace cct { diff --git a/src/basic-objects/test/currencycode_test.cpp b/src/basic-objects/test/currencycode_test.cpp index d447b7d1..43bb3377 100644 --- a/src/basic-objects/test/currencycode_test.cpp +++ b/src/basic-objects/test/currencycode_test.cpp @@ -7,7 +7,7 @@ #include #include "cct_invalid_argument_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" #include "cct_vector.hpp" diff --git a/src/basic-objects/test/market_test.cpp b/src/basic-objects/test/market_test.cpp index 2c7a36f0..ad34ec07 100644 --- a/src/basic-objects/test/market_test.cpp +++ b/src/basic-objects/test/market_test.cpp @@ -5,7 +5,7 @@ #include #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" #include "cct_vector.hpp" #include "currencycode.hpp" diff --git a/src/basic-objects/test/monetaryamount_test.cpp b/src/basic-objects/test/monetaryamount_test.cpp index 35e5f832..49c55a7e 100644 --- a/src/basic-objects/test/monetaryamount_test.cpp +++ b/src/basic-objects/test/monetaryamount_test.cpp @@ -9,7 +9,7 @@ #include "cct_exception.hpp" #include "cct_invalid_argument_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" #include "cct_vector.hpp" #include "currencycode.hpp" diff --git a/src/engine/include/balanceperexchangeportfolio.hpp b/src/engine/include/balanceperexchangeportfolio.hpp index a028bdeb..7ccad39d 100644 --- a/src/engine/include/balanceperexchangeportfolio.hpp +++ b/src/engine/include/balanceperexchangeportfolio.hpp @@ -1,6 +1,5 @@ #pragma once -#include "cct_json-container.hpp" #include "queryresulttypes.hpp" #include "simpletable.hpp" @@ -14,9 +13,6 @@ class BalancePerExchangePortfolio { /// @param wide if true, all exchange amount will be printed as well SimpleTable getTable(bool wide) const; - /// Print in json format. - json::container printJson(CurrencyCode equiCurrency) const; - private: BalancePortfolio computeTotal() const; diff --git a/src/engine/include/queryresultprinter.hpp b/src/engine/include/queryresultprinter.hpp index 6d69fd76..7870bfc4 100644 --- a/src/engine/include/queryresultprinter.hpp +++ b/src/engine/include/queryresultprinter.hpp @@ -6,22 +6,23 @@ #include #include "apioutputtype.hpp" -#include "cct_json-container.hpp" #include "cct_log.hpp" #include "coincentercommandtype.hpp" #include "currencycode.hpp" #include "depositsconstraints.hpp" +#include "file.hpp" +#include "logginginfo.hpp" #include "market.hpp" #include "ordersconstraints.hpp" #include "queryresulttypes.hpp" #include "simpletable.hpp" #include "time-window.hpp" #include "withdrawsconstraints.hpp" +#include "write-json.hpp" namespace cct { class DeliveredWithdrawInfo; -class LoggingInfo; class TradeOptions; class WithdrawOptions; @@ -118,9 +119,21 @@ class QueryResultPrinter { void printTable(const SimpleTable &table) const; - void printJson(const json::container &jsonData) const; + void printJson(const auto &jsonObj) const { + if (_pOs != nullptr) { + *_pOs << WriteMiniJsonOrThrow(jsonObj) << '\n'; + } else { + _outputLogger->info(WriteMiniJsonOrThrow(jsonObj)); + } + } - void logActivity(CoincenterCommandType commandType, const json::container &data, bool isSimulationMode = false) const; + void logActivity(CoincenterCommandType commandType, const auto &jsonObj, bool isSimulationMode = false) const { + if (_loggingInfo.isCommandTypeTracked(commandType) && + (!isSimulationMode || _loggingInfo.alsoLogActivityForSimulatedCommands())) { + File activityFile = _loggingInfo.getActivityFile(); + activityFile.write(WriteMiniJsonOrThrow(jsonObj), Writer::Mode::Append); + } + } const LoggingInfo &_loggingInfo; std::ostream *_pOs = nullptr; diff --git a/src/engine/include/traderesult.hpp b/src/engine/include/traderesult.hpp index c5fd8498..b2dacde2 100644 --- a/src/engine/include/traderesult.hpp +++ b/src/engine/include/traderesult.hpp @@ -1,15 +1,15 @@ #pragma once #include -#include +#include "cct_json.hpp" #include "monetaryamount.hpp" #include "tradedamounts.hpp" namespace cct { class TradeResult { public: - enum class State : int8_t { kComplete, kPartial, kUntouched }; + enum class State : int8_t { complete, partial, untouched }; TradeResult() noexcept = default; @@ -19,12 +19,10 @@ class TradeResult { MonetaryAmount from() const { return _from; } - bool isComplete() const { return state() == State::kComplete; } + bool isComplete() const { return state() == State::complete; } State state() const; - std::string_view stateStr() const; - constexpr bool operator==(const TradeResult &) const noexcept = default; private: @@ -33,3 +31,10 @@ class TradeResult { }; } // namespace cct + +template <> +struct glz::meta<::cct::TradeResult::State> { + using enum ::cct::TradeResult::State; + + static constexpr auto value = enumerate(complete, partial, untouched); +}; \ No newline at end of file diff --git a/src/engine/src/balanceperexchangeportfolio.cpp b/src/engine/src/balanceperexchangeportfolio.cpp index fabf185b..c3a89dc2 100644 --- a/src/engine/src/balanceperexchangeportfolio.cpp +++ b/src/engine/src/balanceperexchangeportfolio.cpp @@ -3,7 +3,6 @@ #include #include "balanceportfolio.hpp" -#include "cct_json-container.hpp" #include "cct_string.hpp" #include "currencycode.hpp" #include "exchange.hpp" @@ -75,46 +74,6 @@ SimpleTable BalancePerExchangePortfolio::getTable(bool wide) const { return balanceTable; } -namespace { -json::container JsonForBalancePortfolio(const BalancePortfolio &balancePortfolio, CurrencyCode equiCurrency) { - json::container ret = json::container::object(); - for (const auto &[amount, equiAmount] : balancePortfolio) { - json::container curData; - curData.emplace("a", amount.amountStr()); - if (!equiCurrency.isNeutral()) { - curData.emplace("eq", equiAmount.amountStr()); - } - ret.emplace(amount.currencyStr(), std::move(curData)); - } - return ret; -} -} // namespace - -json::container BalancePerExchangePortfolio::printJson(CurrencyCode equiCurrency) const { - json::container exchangePart = json::container::object(); - for (const auto &[exchangePtr, balancePortfolio] : _balancePerExchange) { - auto it = exchangePart.find(exchangePtr->name()); - if (it == exchangePart.end()) { - json::container balancePerExchangeData; - balancePerExchangeData.emplace(exchangePtr->keyName(), JsonForBalancePortfolio(balancePortfolio, equiCurrency)); - exchangePart.emplace(exchangePtr->name(), std::move(balancePerExchangeData)); - } else { - it->emplace(exchangePtr->keyName(), JsonForBalancePortfolio(balancePortfolio, equiCurrency)); - } - } - - BalancePortfolio total = computeTotal(); - json::container totalPart; - totalPart.emplace("cur", JsonForBalancePortfolio(total, equiCurrency)); - if (!equiCurrency.isNeutral()) { - totalPart.emplace("eq", ComputeTotalSum(total).amountStr()); - } - json::container out; - out.emplace("exchange", std::move(exchangePart)); - out.emplace("total", std::move(totalPart)); - return out; -} - BalancePortfolio BalancePerExchangePortfolio::computeTotal() const { BalancePortfolio total; for (const auto &[exchangePtr, balancePortfolio] : _balancePerExchange) { diff --git a/src/engine/src/coincenter-commands-processor.cpp b/src/engine/src/coincenter-commands-processor.cpp index 52052792..6fa31152 100644 --- a/src/engine/src/coincenter-commands-processor.cpp +++ b/src/engine/src/coincenter-commands-processor.cpp @@ -193,6 +193,9 @@ TransferableCommandResultVector CoincenterCommandsProcessor::processGroupedComma const auto tradedVolumePerExchange = _coincenter.getLast24hTradedVolumePerExchange(firstCmd.market(), firstCmd.exchangeNames()); _queryResultPrinter.printLast24hTradedVolume(firstCmd.market(), tradedVolumePerExchange); + for (const auto &[exchangePtr, tradedVolume] : tradedVolumePerExchange) { + transferableResults.emplace_back(exchangePtr->createExchangeName(), tradedVolume); + } break; } case CoincenterCommandType::WithdrawFees: { diff --git a/src/engine/src/coincentercommands.cpp b/src/engine/src/coincentercommands.cpp index 36ced623..1b7defb3 100644 --- a/src/engine/src/coincentercommands.cpp +++ b/src/engine/src/coincentercommands.cpp @@ -90,9 +90,14 @@ void CoincenterCommands::addOption(const CoincenterCmdLineOptions &cmdLineOption CurrencyCode to; if (amountType == StringOptionParser::AmountType::kNotPresent) { - Market market = optionParser.parseMarket(); - amount = MonetaryAmount(1, market.base()); - to = market.quote(); + Market market = optionParser.parseMarket(StringOptionParser::FieldIs::kOptional); + if (market.isNeutral()) { + amount = MonetaryAmount{}; + to = optionParser.parseCurrency(); + } else { + amount = MonetaryAmount(1, market.base()); + to = market.quote(); + } } else { to = optionParser.parseCurrency(); } diff --git a/src/engine/src/coincenteroptions.cpp b/src/engine/src/coincenteroptions.cpp index 3d3c6cd7..17561464 100644 --- a/src/engine/src/coincenteroptions.cpp +++ b/src/engine/src/coincenteroptions.cpp @@ -76,8 +76,8 @@ void CoincenterCmdLineOptions::mergeGlobalWith(const CoincenterCmdLineOptions& r TradeOptions CoincenterCmdLineOptions::computeTradeOptions() const { const TradeTypePolicy tradeTypePolicy = computeTradeTypePolicy(); const TradeTimeoutAction timeoutAction = computeTradeTimeoutAction(); - const TradeMode tradeMode = isSimulation ? TradeMode::kSimulation : TradeMode::kReal; - const TradeSyncPolicy tradeSyncPolicy = async ? TradeSyncPolicy::kAsynchronous : TradeSyncPolicy::kSynchronous; + const TradeMode tradeMode = isSimulation ? TradeMode::simulation : TradeMode::real; + const TradeSyncPolicy tradeSyncPolicy = async ? TradeSyncPolicy::asynchronous : TradeSyncPolicy::synchronous; if (!tradeStrategy.empty()) { PriceOptions priceOptions(tradeStrategy); @@ -124,16 +124,16 @@ TradeTimeoutAction CoincenterCmdLineOptions::computeTradeTimeoutAction() const { if (tradeTimeoutMatch) { throw invalid_argument("Only one trade timeout action may be chosen"); } - return TradeTimeoutAction::kCancel; + return TradeTimeoutAction::cancel; } if (tradeTimeoutMatch) { - return TradeTimeoutAction::kMatch; + return TradeTimeoutAction::match; } - return TradeTimeoutAction::kDefault; + return TradeTimeoutAction::exchange_default; } WithdrawOptions CoincenterCmdLineOptions::computeWithdrawOptions() const { - const auto withdrawSyncPolicy = async ? WithdrawSyncPolicy::kAsynchronous : WithdrawSyncPolicy::kSynchronous; + const auto withdrawSyncPolicy = async ? WithdrawSyncPolicy::asynchronous : WithdrawSyncPolicy::synchronous; const auto mode = isSimulation ? WithdrawOptions::Mode::kSimulation : WithdrawOptions::Mode::kReal; return {withdrawRefreshTime, withdrawSyncPolicy, mode}; } diff --git a/src/engine/src/metricsexporter.cpp b/src/engine/src/metricsexporter.cpp index a7fd932a..5fc9c83d 100644 --- a/src/engine/src/metricsexporter.cpp +++ b/src/engine/src/metricsexporter.cpp @@ -131,7 +131,7 @@ void MetricsExporter::exportLastTradesMetrics(const TradesPerExchange &lastTrade std::array totalPrices{MonetaryAmount(0, mk.quote()), MonetaryAmount(0, mk.quote())}; std::array nb{}; for (const PublicTrade &trade : lastTrades) { - const int buyOrSell = trade.side() == TradeSide::kBuy ? 0 : 1; + const int buyOrSell = trade.side() == TradeSide::buy ? 0 : 1; totalAmounts[buyOrSell] += trade.amount(); ++nb[buyOrSell]; diff --git a/src/engine/src/query-result-schema.hpp b/src/engine/src/query-result-schema.hpp new file mode 100644 index 00000000..d23838f8 --- /dev/null +++ b/src/engine/src/query-result-schema.hpp @@ -0,0 +1,531 @@ +#pragma once + +#include +#include +#include + +#include "cct_const.hpp" +#include "cct_fixedcapacityvector.hpp" +#include "coincentercommandtype.hpp" +#include "currencycode.hpp" +#include "duration-schema.hpp" +#include "exchangepublicapitypes.hpp" +#include "market.hpp" +#include "monetaryamount.hpp" +#include "time-window.hpp" +#include "timepoint-schema.hpp" +#include "tradedamounts.hpp" +#include "withdrawoptions.hpp" + +namespace cct::schema::queryresult { + +struct HealthCheck { + struct In { + CoincenterCommandType req = CoincenterCommandType::HealthCheck; + } in; + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct CurrenciesPerExchange { + struct In { + CoincenterCommandType req = CoincenterCommandType::Currencies; + } in; + + struct Currency { + CurrencyCode code; + CurrencyCode exchangeCode; + CurrencyCode altCode; + bool canDeposit; + bool canWithdraw; + bool isFiat; + }; + + FixedCapacityVector>, kNbSupportedExchanges> out; +}; + +struct Markets { + struct In { + CoincenterCommandType req = CoincenterCommandType::Markets; + struct Opt { + std::optional cur1; + std::optional cur2; + } opt; + } in; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct MarketsForReplay { + struct In { + CoincenterCommandType req = CoincenterCommandType::ReplayMarkets; + struct Opt { + std::optional timeWindow; + } opt; + } in; + + struct ExchangePart { + struct Elem { + using trivially_relocatable = is_trivially_relocatable::type; + + auto operator<=>(const Elem &) const = default; + + Market market; + string lastTimestamp; + }; + + vector orderBooks; + vector trades; + }; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct TickerInformation { + struct In { + CoincenterCommandType req = CoincenterCommandType::Ticker; + } in; + + struct Ticker { + Market pair; + + struct Elem { + MonetaryAmount a; + MonetaryAmount p; + }; + + Elem ask; + Elem bid; + }; + + FixedCapacityVector>, kNbSupportedExchanges> out; +}; + +struct MarketOrderBooks { + struct In { + CoincenterCommandType req = CoincenterCommandType::Orderbook; + struct Opt { + Market pair; + std::optional equiCurrency; + std::optional depth; + } opt; + } in; + + struct ExchangePart { + struct AskOrBid { + auto operator<=>(const AskOrBid &) const = default; + + MonetaryAmount a; + MonetaryAmount p; + std::optional eq; + }; + + vector ask; + vector bid; + TimePoint time; + }; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Balance { + struct In { + CoincenterCommandType req = CoincenterCommandType::Balance; + struct Opt { + std::optional equiCurrency; + } opt; + } in; + + struct Out { + struct CurrencyPart { + auto operator<=>(const CurrencyPart &) const = default; + + MonetaryAmount a; + std::optional eq; + }; + + using ExchangeKeyPart = vector>; + using ExchangePart = SmallVector, 1>; + + FixedCapacityVector, kNbSupportedExchanges> exchange; + + struct TotalPart { + ExchangeKeyPart cur; + std::optional eq; + } total; + } out; +}; + +struct DepositInfo { + struct In { + CoincenterCommandType req = CoincenterCommandType::DepositInfo; + struct Opt { + CurrencyCode cur; + } opt; + } in; + + struct ExchangeKeyPart { + std::string_view address; + std::optional tag; + }; + + using ExchangePart = SmallVector, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Trades { + struct In { + CoincenterCommandType req{}; + struct Opt { + struct FromTo { + std::optional amount; + CurrencyCode currency; + std::optional isPercentage; + }; + + std::optional from; + std::optional to; + + struct Options { + struct Price { + PriceStrategy strategy; + std::optional fixedPrice; + std::optional relativePrice; + } price; + Duration maxTradeTime; + Duration minTimeBetweenPriceUpdates; + TradeMode mode; + TradeSyncPolicy syncPolicy; + TradeTimeoutAction timeoutAction; + } options; + + } opt; + } in; + + struct ExchangeKeyPart { + MonetaryAmount from; + TradeResult::State status; + MonetaryAmount tradedFrom; + MonetaryAmount tradedTo; + }; + + using ExchangePart = SmallVector, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Orders { + struct In { + CoincenterCommandType req{}; + struct Opt { + std::optional cur1; + std::optional cur2; + std::optional placedBefore; + std::optional placedAfter; + std::optional> matchIds; + }; + + std::optional opt; + } in; + + struct Order { + auto operator<=>(const Order &) const = default; + + std::string_view id; + Market pair; + TimePoint placedTime; + std::optional matchedTime; + TradeSide side; + MonetaryAmount price; + MonetaryAmount matched; + std::optional remaining; + }; + + using ExchangePart = SmallVector>, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct OrdersCancelled { + Orders::In in; + + struct Elem { + int nb; + }; + + using ExchangePart = SmallVector, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct RecentDeposits { + struct In { + CoincenterCommandType req = CoincenterCommandType::RecentDeposits; + struct Opt { + std::optional cur; + std::optional receivedBefore; + std::optional sentBefore; + std::optional receivedAfter; + std::optional sentAfter; + std::optional> matchIds; + }; + + std::optional opt; + } in; + + struct Elem { + std::string_view id; + CurrencyCode cur; + TimePoint receivedTime; + MonetaryAmount amount; + WithdrawOrDeposit::Status status; + }; + + using ExchangePart = SmallVector>, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct RecentWithdraws { + struct In { + CoincenterCommandType req = CoincenterCommandType::RecentWithdraws; + + std::optional opt; + } in; + + struct Elem { + std::string_view id; + CurrencyCode cur; + TimePoint sentTime; + MonetaryAmount netEmittedAmount; + MonetaryAmount fee; + WithdrawOrDeposit::Status status; + }; + + using ExchangePart = SmallVector>, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Conversion1 { + struct In { + CoincenterCommandType req = CoincenterCommandType::Conversion; + struct Opt { + MonetaryAmount fromAmount; + CurrencyCode fromCurrency; + CurrencyCode toCurrency; + }; + + Opt opt; + } in; + + struct ExchangePart { + MonetaryAmount convertedAmount; + }; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Conversion2 { + struct In { + CoincenterCommandType req = CoincenterCommandType::Conversion; + struct Opt { + struct ExchangePart { + auto operator<=>(const ExchangePart &) const = default; + + MonetaryAmount amount; + CurrencyCode cur; + }; + FixedCapacityVector, kNbSupportedExchanges> fromAmount; + CurrencyCode toCurrency; + }; + + Opt opt; + } in; + + struct ExchangePart { + MonetaryAmount convertedAmount; + }; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct ConversionPath { + struct In { + CoincenterCommandType req = CoincenterCommandType::ConversionPath; + struct Opt { + Market market; + }; + + Opt opt; + } in; + + FixedCapacityVector>, kNbSupportedExchanges> out; +}; + +struct WithdrawFees { + struct In { + CoincenterCommandType req = CoincenterCommandType::WithdrawFees; + struct Opt { + std::optional cur; + }; + + Opt opt; + } in; + + FixedCapacityVector>, kNbSupportedExchanges> out; +}; + +struct Last24hTradedVolume { + struct In { + CoincenterCommandType req = CoincenterCommandType::Last24hTradedVolume; + struct Opt { + Market market; + }; + + Opt opt; + } in; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct LastTrades { + struct In { + CoincenterCommandType req = CoincenterCommandType::LastTrades; + struct Opt { + Market market; + std::optional nb; + }; + + Opt opt; + } in; + + struct Elem { + MonetaryAmount a; + MonetaryAmount p; + TimePoint time; + TradeSide side; + }; + + FixedCapacityVector>, kNbSupportedExchanges> out; +}; + +struct LastPrice { + struct In { + CoincenterCommandType req = CoincenterCommandType::LastPrice; + struct Opt { + Market market; + }; + + Opt opt; + } in; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct Withdraw { + struct In { + CoincenterCommandType req = CoincenterCommandType::Withdraw; + struct Opt { + CurrencyCode cur; + bool isPercentage; + WithdrawSyncPolicy syncPolicy; + }; + + Opt opt; + } in; + + struct Out { + struct From { + ExchangeNameEnum exchange; + std::string_view account; + std::string_view id; + MonetaryAmount amount; + TimePoint time; + } from; + struct To { + ExchangeNameEnum exchange; + std::string_view account; + std::string_view id; + MonetaryAmount amount; + std::string_view address; + std::optional tag; + TimePoint time; + } to; + } out; +}; + +struct DustSweeper { + struct In { + CoincenterCommandType req = CoincenterCommandType::DustSweeper; + struct Opt { + CurrencyCode cur; + }; + + Opt opt; + } in; + + struct ExchangeKeyPart { + struct TradedAmounts { + auto operator<=>(const TradedAmounts &) const = default; + + MonetaryAmount from; + MonetaryAmount to; + }; + vector trades; + MonetaryAmount finalAmount; + }; + + using ExchangePart = SmallVector, 1>; + + FixedCapacityVector, kNbSupportedExchanges> out; +}; + +struct MarketTradingResults { + struct In { + CoincenterCommandType req{}; + struct Opt { + struct Time { + TimePoint from; + TimePoint to; + } time; + }; + + Opt opt; + } in; + + struct MarketTradingResult { + std::string_view algorithm; + Market market; + struct StartAmounts { + MonetaryAmount base; + MonetaryAmount quote; + } startAmounts; + MonetaryAmount profitAndLoss; + struct Stats { + struct TradeRangeResultsStats { + int nbError; + int nbSuccessful; + struct Time { + TimePoint from; + TimePoint to; + } time; + }; + TradeRangeResultsStats orderBooks; + TradeRangeResultsStats trades; + } stats; + + vector matchedOrders; + }; + + using ExchangeMarketResults = + FixedCapacityVector, kNbSupportedExchanges>; + + using AllResults = vector; + + using AlgorithmNameResults = vector; + + vector> out; +}; + +} // namespace cct::schema::queryresult \ No newline at end of file diff --git a/src/engine/src/queryresultprinter.cpp b/src/engine/src/queryresultprinter.cpp index 0b46bf2c..2c126f49 100644 --- a/src/engine/src/queryresultprinter.cpp +++ b/src/engine/src/queryresultprinter.cpp @@ -13,7 +13,6 @@ #include "apioutputtype.hpp" #include "balanceperexchangeportfolio.hpp" #include "cct_const.hpp" -#include "cct_json-container.hpp" #include "cct_log.hpp" #include "cct_string.hpp" #include "closed-order.hpp" @@ -38,6 +37,7 @@ #include "priceoptions.hpp" #include "priceoptionsdef.hpp" #include "publictrade.hpp" +#include "query-result-schema.hpp" #include "query-result-type-helpers.hpp" #include "queryresulttypes.hpp" #include "simpletable.hpp" @@ -54,802 +54,700 @@ #include "withdrawoptions.hpp" #include "withdrawsconstraints.hpp" #include "withdrawsordepositsconstraints.hpp" +#include "write-json.hpp" #include "writer.hpp" namespace cct { namespace { -json::container ToJson(CoincenterCommandType commandType, json::container &&in, json::container &&out) { - in.emplace("req", CoincenterCommandTypeToString(commandType)); +auto HealthCheckJson(const ExchangeHealthCheckStatus &healthCheckPerExchange) { + schema::queryresult::HealthCheck obj; - json::container ret; - - ret.emplace("in", std::move(in)); - ret.emplace("out", std::move(out)); - - return ret; -} - -json::container HealthCheckJson(const ExchangeHealthCheckStatus &healthCheckPerExchange) { - json::container in; - json::container out = json::container::object(); + obj.out.reserve(healthCheckPerExchange.size()); for (const auto &[e, healthCheckValue] : healthCheckPerExchange) { - out.emplace(e->name(), healthCheckValue); + obj.out.emplace_back(e->exchangeNameEnum(), healthCheckValue); } - return ToJson(CoincenterCommandType::HealthCheck, std::move(in), std::move(out)); + return obj; } -json::container CurrenciesJson(const CurrenciesPerExchange ¤ciesPerExchange) { - json::container in; - json::container inOpt; - in.emplace("opt", std::move(inOpt)); +auto CurrenciesJson(const CurrenciesPerExchange ¤ciesPerExchange) { + schema::queryresult::CurrenciesPerExchange obj; - json::container out = json::container::object(); for (const auto &[e, currencies] : currenciesPerExchange) { - json::container currenciesForExchange; - for (const CurrencyExchange &cur : currencies) { - json::container curExchangeJson; + using ExchangePartType = decltype(obj.out)::value_type::second_type; + auto &p = obj.out.emplace_back(e->exchangeNameEnum(), ExchangePartType{}); - curExchangeJson.emplace("code", cur.standardCode().str()); - curExchangeJson.emplace("exchangeCode", cur.exchangeCode().str()); - curExchangeJson.emplace("altCode", cur.altCode().str()); - - curExchangeJson.emplace("canDeposit", cur.canDeposit()); - curExchangeJson.emplace("canWithdraw", cur.canWithdraw()); - - curExchangeJson.emplace("isFiat", cur.isFiat()); - - currenciesForExchange.emplace_back(std::move(curExchangeJson)); + p.second.reserve(currencies.size()); + for (const CurrencyExchange &cur : currencies) { + auto ¤cy = p.second.emplace_back(); + + currency.code = cur.standardCode(); + currency.exchangeCode = cur.exchangeCode(); + currency.altCode = cur.altCode(); + currency.canDeposit = cur.canDeposit(); + currency.canWithdraw = cur.canWithdraw(); + currency.isFiat = cur.isFiat(); } - out.emplace(e->name(), std::move(currenciesForExchange)); } - return ToJson(CoincenterCommandType::Currencies, std::move(in), std::move(out)); + return obj; } -json::container MarketsJson(CurrencyCode cur1, CurrencyCode cur2, const MarketsPerExchange &marketsPerExchange) { - json::container in; - json::container inOpt = json::container::object(); +auto MarketsJson(CurrencyCode cur1, CurrencyCode cur2, const MarketsPerExchange &marketsPerExchange) { + schema::queryresult::Markets obj; + if (!cur1.isNeutral()) { - inOpt.emplace("cur1", cur1.str()); + obj.in.opt.cur1 = cur1; } if (!cur2.isNeutral()) { - inOpt.emplace("cur2", cur2.str()); + obj.in.opt.cur2 = cur2; } - in.emplace("opt", std::move(inOpt)); - - json::container out = json::container::object(); + obj.out.reserve(marketsPerExchange.size()); for (const auto &[e, markets] : marketsPerExchange) { - json::container marketsForExchange; - for (const Market &mk : markets) { - marketsForExchange.emplace_back(mk.str()); - } - out.emplace(e->name(), std::move(marketsForExchange)); + obj.out.emplace_back(e->exchangeNameEnum(), markets); } - return ToJson(CoincenterCommandType::Markets, std::move(in), std::move(out)); + return obj; } -json::container MarketsForReplayJson(TimeWindow timeWindow, - const MarketTimestampSetsPerExchange &marketTimestampSetsPerExchange) { - json::container in; - json::container inOpt = json::container::object(); +auto MarketsForReplayJson(TimeWindow timeWindow, const MarketTimestampSetsPerExchange &marketTimestampSetsPerExchange) { + schema::queryresult::MarketsForReplay obj; + if (timeWindow != TimeWindow{}) { - inOpt.emplace("timeWindow", timeWindow.str()); + obj.in.opt.timeWindow = timeWindow; } - in.emplace("opt", std::move(inOpt)); - json::container out = json::container::object(); for (const auto &[e, marketTimestampSets] : marketTimestampSetsPerExchange) { - json::container orderBookMarketsPerExchange; - for (const MarketTimestamp &marketTimestamp : marketTimestampSets.orderBooksMarkets) { - json::container marketTimestampJson; - - marketTimestampJson.emplace("market", marketTimestamp.market.str()); - marketTimestampJson.emplace("lastTimestamp", TimeToString(marketTimestamp.timePoint)); + using ExchangePartType = decltype(obj.out)::value_type::second_type; + auto &exchangePart = obj.out.emplace_back(e->exchangeNameEnum(), ExchangePartType{}).second; - orderBookMarketsPerExchange.emplace_back(std::move(marketTimestampJson)); + exchangePart.orderBooks.reserve(marketTimestampSets.orderBooksMarkets.size()); + for (const MarketTimestamp &marketTimestamp : marketTimestampSets.orderBooksMarkets) { + exchangePart.orderBooks.emplace_back(marketTimestamp.market, TimeToString(marketTimestamp.timePoint)); } - json::container tradesMarketsPerExchange; + exchangePart.trades.reserve(marketTimestampSets.tradesMarkets.size()); for (const MarketTimestamp &marketTimestamp : marketTimestampSets.tradesMarkets) { - json::container marketTimestampJson; - - marketTimestampJson.emplace("market", marketTimestamp.market.str()); - marketTimestampJson.emplace("lastTimestamp", TimeToString(marketTimestamp.timePoint)); - - tradesMarketsPerExchange.emplace_back(std::move(marketTimestampJson)); + exchangePart.trades.emplace_back(marketTimestamp.market, TimeToString(marketTimestamp.timePoint)); } - - json::container exchangePart; - - exchangePart.emplace("orderBooks", std::move(orderBookMarketsPerExchange)); - exchangePart.emplace("trades", std::move(tradesMarketsPerExchange)); - - out.emplace(e->name(), std::move(exchangePart)); } - return ToJson(CoincenterCommandType::ReplayMarkets, std::move(in), std::move(out)); + return obj; } -json::container TickerInformationJson(const ExchangeTickerMaps &exchangeTickerMaps) { - json::container in; - json::container out = json::container::object(); +auto TickerInformationJson(const ExchangeTickerMaps &exchangeTickerMaps) { + schema::queryresult::TickerInformation obj; for (const auto &[e, marketOrderBookMap] : exchangeTickerMaps) { - json::container allTickerForExchange; + using ExchangePartType = decltype(obj.out)::value_type::second_type; + auto &exchangePart = obj.out.emplace_back(e->exchangeNameEnum(), ExchangePartType{}).second; + + exchangePart.reserve(marketOrderBookMap.size()); for (const auto &[mk, marketOrderBook] : marketOrderBookMap) { - json::container tickerForExchange; - tickerForExchange.emplace("pair", mk.str()); - json::container ask; - json::container bid; - ask.emplace("a", marketOrderBook.amountAtAskPrice().amountStr()); - ask.emplace("p", marketOrderBook.lowestAskPrice().amountStr()); - bid.emplace("a", marketOrderBook.amountAtBidPrice().amountStr()); - bid.emplace("p", marketOrderBook.highestBidPrice().amountStr()); - tickerForExchange.emplace("ask", std::move(ask)); - tickerForExchange.emplace("bid", std::move(bid)); - allTickerForExchange.emplace_back(tickerForExchange); + auto &ticker = exchangePart.emplace_back(); + + ticker.pair = mk; + + ticker.ask.a = marketOrderBook.amountAtAskPrice().toNeutral(); + ticker.ask.p = marketOrderBook.lowestAskPrice().toNeutral(); + ticker.bid.a = marketOrderBook.amountAtBidPrice().toNeutral(); + ticker.bid.p = marketOrderBook.highestBidPrice().toNeutral(); } // Sort rows by market pair for consistent output - std::sort(allTickerForExchange.begin(), allTickerForExchange.end(), - [](const json::container &lhs, const json::container &rhs) { - return lhs["pair"].get() < rhs["pair"].get(); - }); - out.emplace(e->name(), std::move(allTickerForExchange)); + std::ranges::sort(exchangePart, [](const auto &lhs, const auto &rhs) { return lhs.pair < rhs.pair; }); } - return ToJson(CoincenterCommandType::Ticker, std::move(in), std::move(out)); + return obj; } void AppendOrderbookLine(const MarketOrderBook &marketOrderBook, int pos, - std::optional optConversionRate, json::container &data) { + std::optional optConversionRate, auto &data) { auto [amount, price] = marketOrderBook[pos]; - json::container &line = data.emplace_back(); - line.emplace("a", amount.amountStr()); - line.emplace("p", price.amountStr()); + auto &line = data.emplace_back(); + line.a = amount.toNeutral(); + line.p = price.toNeutral(); + if (optConversionRate) { - line.emplace("eq", optConversionRate->amountStr()); + line.eq = optConversionRate->toNeutral(); } } -json::container MarketOrderBooksJson(Market mk, CurrencyCode equiCurrencyCode, std::optional depth, - const MarketOrderBookConversionRates &marketOrderBooksConversionRates) { - json::container in; - json::container inOpt; - inOpt.emplace("pair", mk.str()); +auto MarketOrderBooksJson(Market mk, CurrencyCode equiCurrencyCode, std::optional depth, + const MarketOrderBookConversionRates &marketOrderBooksConversionRates) { + schema::queryresult::MarketOrderBooks obj; + + obj.in.opt.pair = mk; if (!equiCurrencyCode.isNeutral()) { - inOpt.emplace("equiCurrency", equiCurrencyCode.str()); + obj.in.opt.equiCurrency = equiCurrencyCode; } - if (depth) { - inOpt.emplace("depth", *depth); - } - in.emplace("opt", std::move(inOpt)); + obj.in.opt.depth = depth; - json::container out = json::container::object(); + obj.out.reserve(marketOrderBooksConversionRates.size()); for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { - json::container marketOrderBookForExchange; - json::container bidsForExchange; - json::container asksForExchange; + using ExchangePartType = decltype(obj.out)::value_type::second_type; + auto &exchangePart = obj.out.emplace_back(exchangeNameEnum, ExchangePartType{}).second; - marketOrderBookForExchange.emplace("time", TimeToString(marketOrderBook.time())); + exchangePart.time.ts = marketOrderBook.time(); for (int bidPos = 1; bidPos <= marketOrderBook.nbBidPrices(); ++bidPos) { - AppendOrderbookLine(marketOrderBook, -bidPos, optConversionRate, bidsForExchange); + AppendOrderbookLine(marketOrderBook, -bidPos, optConversionRate, exchangePart.bid); } - marketOrderBookForExchange.emplace("bid", std::move(bidsForExchange)); for (int askPos = 1; askPos <= marketOrderBook.nbAskPrices(); ++askPos) { - AppendOrderbookLine(marketOrderBook, askPos, optConversionRate, asksForExchange); + AppendOrderbookLine(marketOrderBook, askPos, optConversionRate, exchangePart.ask); } - marketOrderBookForExchange.emplace("ask", std::move(asksForExchange)); - out.emplace(kSupportedExchanges[static_cast(exchangeNameEnum)], std::move(marketOrderBookForExchange)); } - return ToJson(CoincenterCommandType::Orderbook, std::move(in), std::move(out)); + return obj; } -json::container BalanceJson(const BalancePerExchange &balancePerExchange, CurrencyCode equiCurrency) { - json::container in; - json::container inOpt = json::container::object(); - if (!equiCurrency.isNeutral()) { - inOpt.emplace("equiCurrency", equiCurrency.str()); +auto &GetExchangePart(const Exchange *e, auto &out) { + using ExchangePart = std::remove_cvref_t::value_type::second_type; + auto it = + std::ranges::find_if(out, [e](const auto &exchangePart) { return exchangePart.first == e->exchangeNameEnum(); }); + if (it == out.end()) { + return out.emplace_back(e->exchangeNameEnum(), ExchangePart{}).second; } - in.emplace("opt", std::move(inOpt)); + return it->second; +} - BalancePerExchangePortfolio totalBalance(balancePerExchange); +auto BalanceJson(const BalancePerExchange &balancePerExchange, CurrencyCode equiCurrency) { + schema::queryresult::Balance obj; - return ToJson(CoincenterCommandType::Balance, std::move(in), totalBalance.printJson(equiCurrency)); -} + BalancePortfolio totalBalance; -json::container DepositInfoJson(CurrencyCode depositCurrencyCode, const WalletPerExchange &walletPerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("cur", depositCurrencyCode.str()); - in.emplace("opt", std::move(inOpt)); + using ExchangePart = decltype(obj.out.exchange)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + using CurrencyPart = ExchangeKeyPart::value_type::second_type; - json::container out = json::container::object(); - for (const auto &[exchangePtr, wallet] : walletPerExchange) { - json::container depositPerExchangeData; + const bool hasEquiCurrency = !equiCurrency.isNeutral(); - depositPerExchangeData.emplace("address", wallet.address()); - if (wallet.hasTag()) { - depositPerExchangeData.emplace("tag", wallet.tag()); + if (hasEquiCurrency) { + obj.in.opt.equiCurrency = equiCurrency; + } + + for (const auto &[e, balance] : balancePerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out.exchange); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + for (const auto &[amount, equiAmount] : balance) { + auto ¤cyPart = exchangeKeyPart.emplace_back(amount.currencyCode(), CurrencyPart{}).second; + currencyPart.a = amount.toNeutral(); + if (hasEquiCurrency) { + currencyPart.eq = equiAmount.toNeutral(); + } } - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container depositInfoForExchangeUser; - depositInfoForExchangeUser.emplace(exchangePtr->keyName(), std::move(depositPerExchangeData)); - out.emplace(exchangePtr->name(), std::move(depositInfoForExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(depositPerExchangeData)); + totalBalance += balance; + } + + MonetaryAmount totalEq(0, equiCurrency); + for (const auto &[amount, equiAmount] : totalBalance) { + auto ¤cyPart = obj.out.total.cur.emplace_back(amount.currencyCode(), CurrencyPart{}).second; + currencyPart.a = amount.toNeutral(); + if (hasEquiCurrency) { + currencyPart.eq = equiAmount.toNeutral(); + totalEq += equiAmount; } } - return ToJson(CoincenterCommandType::DepositInfo, std::move(in), std::move(out)); + if (hasEquiCurrency) { + obj.out.total.eq = totalEq.toNeutral(); + } + + return obj; } -inline const char *TradeModeToStr(TradeMode tradeMode) { return tradeMode == TradeMode::kReal ? "real" : "simulation"; } +auto DepositInfoJson(CurrencyCode depositCurrencyCode, const WalletPerExchange &walletPerExchange) { + schema::queryresult::DepositInfo obj; -json::container TradeOptionsToJson(const TradeOptions &tradeOptions) { - json::container priceOptionsJson; - const PriceOptions &priceOptions = tradeOptions.priceOptions(); - priceOptionsJson.emplace("strategy", PriceStrategyStr(priceOptions.priceStrategy(), false)); - if (priceOptions.isFixedPrice()) { - priceOptionsJson.emplace("fixedPrice", priceOptions.fixedPrice().str()); + obj.in.opt.cur = depositCurrencyCode; + + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + + for (const auto &[e, wallet] : walletPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + exchangeKeyPart.address = wallet.address(); + if (wallet.hasTag()) { + exchangeKeyPart.tag = wallet.tag(); + } } - if (priceOptions.isRelativePrice()) { - priceOptionsJson.emplace("relativePrice", priceOptions.relativePrice()); - } - json::container ret; - ret.emplace("price", std::move(priceOptionsJson)); - ret.emplace("maxTradeTime", DurationToString(tradeOptions.maxTradeTime())); - ret.emplace("minTimeBetweenPriceUpdates", DurationToString(tradeOptions.minTimeBetweenPriceUpdates())); - ret.emplace("mode", TradeModeToStr(tradeOptions.tradeMode())); - ret.emplace("timeoutAction", tradeOptions.timeoutActionStr()); - ret.emplace("syncPolicy", tradeOptions.tradeSyncPolicyStr()); - return ret; + + return obj; } -json::container TradesJson(const TradeResultPerExchange &tradeResultPerExchange, MonetaryAmount amount, - bool isPercentageTrade, CurrencyCode toCurrency, const TradeOptions &tradeOptions, - CoincenterCommandType commandType) { - json::container in; - json::container fromJson; - fromJson.emplace("amount", amount.amountStr()); - fromJson.emplace("currency", amount.currencyStr()); - fromJson.emplace("isPercentage", isPercentageTrade); +auto TradesJson(const TradeResultPerExchange &tradeResultPerExchange, MonetaryAmount amount, bool isPercentageTrade, + CurrencyCode toCurrency, const TradeOptions &tradeOptions, CoincenterCommandType commandType) { + schema::queryresult::Trades obj; + + obj.in.req = commandType; + + auto &from = obj.in.opt.from.emplace(); + + from.amount = amount.toNeutral(); + + from.currency = amount.currencyCode(); + from.isPercentage = isPercentageTrade; - json::container inOpt; switch (commandType) { case CoincenterCommandType::Buy: - inOpt.emplace("to", std::move(fromJson)); + std::swap(obj.in.opt.from, obj.in.opt.to); break; case CoincenterCommandType::Sell: - inOpt.emplace("from", std::move(fromJson)); break; case CoincenterCommandType::Trade: { - json::container toJson; - toJson.emplace("currency", toCurrency.str()); - - inOpt.emplace("from", std::move(fromJson)); - inOpt.emplace("to", std::move(toJson)); + obj.in.opt.to.emplace().currency = toCurrency; break; } default: unreachable(); } - inOpt.emplace("options", TradeOptionsToJson(tradeOptions)); - in.emplace("opt", std::move(inOpt)); + auto &opts = obj.in.opt.options; - json::container out = json::container::object(); - for (const auto &[exchangePtr, tradeResult] : tradeResultPerExchange) { - json::container tradedAmountPerExchangeJson; - tradedAmountPerExchangeJson.emplace("from", tradeResult.from().amountStr()); - tradedAmountPerExchangeJson.emplace("status", tradeResult.stateStr()); - tradedAmountPerExchangeJson.emplace("tradedFrom", tradeResult.tradedAmounts().from.amountStr()); - tradedAmountPerExchangeJson.emplace("tradedTo", tradeResult.tradedAmounts().to.amountStr()); + const auto &priceOptions = tradeOptions.priceOptions(); - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container tradedAmountPerExchangeUser; - tradedAmountPerExchangeUser.emplace(exchangePtr->keyName(), std::move(tradedAmountPerExchangeJson)); - out.emplace(exchangePtr->name(), std::move(tradedAmountPerExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(tradedAmountPerExchangeJson)); - } + opts.price.strategy = priceOptions.priceStrategy(); + if (priceOptions.isFixedPrice()) { + opts.price.fixedPrice = priceOptions.fixedPrice(); } + if (priceOptions.isRelativePrice()) { + opts.price.relativePrice = priceOptions.relativePrice(); + } + opts.maxTradeTime.duration = tradeOptions.maxTradeTime(); + opts.minTimeBetweenPriceUpdates.duration = tradeOptions.minTimeBetweenPriceUpdates(); + opts.mode = tradeOptions.tradeMode(); + opts.syncPolicy = tradeOptions.tradeSyncPolicy(); + opts.timeoutAction = tradeOptions.timeoutAction(); + + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; - return ToJson(commandType, std::move(in), std::move(out)); + for (const auto &[e, tradeResult] : tradeResultPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + exchangeKeyPart.from = tradeResult.from().toNeutral(); + exchangeKeyPart.status = tradeResult.state(); + exchangeKeyPart.tradedFrom = tradeResult.tradedAmounts().from.toNeutral(); + exchangeKeyPart.tradedTo = tradeResult.tradedAmounts().to.toNeutral(); + } + + return obj; } -json::container OrdersConstraintsToJson(const OrdersConstraints &ordersConstraints) { - json::container ret; +void SetOrdersConstraints(std::optional &opt, + const OrdersConstraints &ordersConstraints) { + auto &initializedOpt = opt.emplace(); + bool reset = true; if (ordersConstraints.isCurDefined()) { - ret.emplace("cur1", ordersConstraints.curStr1()); + initializedOpt.cur1 = ordersConstraints.cur1(); + reset = false; } if (ordersConstraints.isCur2Defined()) { - ret.emplace("cur2", ordersConstraints.curStr2()); + initializedOpt.cur2 = ordersConstraints.cur2(); + reset = false; } if (ordersConstraints.isPlacedTimeBeforeDefined()) { - ret.emplace("placedBefore", TimeToString(ordersConstraints.placedBefore())); + initializedOpt.placedBefore.emplace(ordersConstraints.placedBefore()); + reset = false; } if (ordersConstraints.isPlacedTimeAfterDefined()) { - ret.emplace("placedAfter", TimeToString(ordersConstraints.placedAfter())); + initializedOpt.placedAfter.emplace(ordersConstraints.placedAfter()); + reset = false; } if (ordersConstraints.isOrderIdDefined()) { - json::container orderIds = json::container::array(); - for (const OrderId &orderId : ordersConstraints.orderIdSet()) { - orderIds.emplace_back(orderId); - } - ret.emplace("matchIds", std::move(orderIds)); + initializedOpt.matchIds = ordersConstraints.orderIdSet(); + reset = false; + } + if (reset) { + opt.reset(); } - return ret; } -template -json::container OrderJson(const OrderType &orderData) { - static_assert(std::is_same_v || std::is_same_v); +void SetOrder(const auto &orderData, auto &order) { + using OrderType = std::remove_cvref_t; - json::container order; - order.emplace("id", orderData.id()); - order.emplace("pair", orderData.market().str()); - order.emplace("placedTime", orderData.placedTimeStr()); + order.id = orderData.id(); + order.pair = orderData.market(); + order.placedTime.ts = orderData.placedTime(); if constexpr (std::is_same_v) { - order.emplace("matchedTime", orderData.matchedTimeStr()); + order.matchedTime.emplace(orderData.matchedTime()); } - order.emplace("side", orderData.sideStr()); - order.emplace("price", orderData.price().amountStr()); - order.emplace("matched", orderData.matchedVolume().amountStr()); + order.side = orderData.side(); + order.price = orderData.price().toNeutral(); + order.matched = orderData.matchedVolume().toNeutral(); if constexpr (std::is_same_v) { - order.emplace("remaining", orderData.remainingVolume().amountStr()); + order.remaining = orderData.remainingVolume().toNeutral(); } - return order; } template -json::container OrdersJson(CoincenterCommandType coincenterCommandType, const OrdersPerExchangeType &ordersPerExchange, - const OrdersConstraints &ordersConstraints) { - json::container in; - json::container inOpt = OrdersConstraintsToJson(ordersConstraints); +auto OrdersJson(CoincenterCommandType coincenterCommandType, const OrdersPerExchangeType &ordersPerExchange, + const OrdersConstraints &ordersConstraints) { + schema::queryresult::Orders obj; - if (!inOpt.empty()) { - in.emplace("opt", std::move(inOpt)); - } + obj.in.req = coincenterCommandType; - json::container out = json::container::object(); - for (const auto &[exchangePtr, ordersData] : ordersPerExchange) { - json::container orders = json::container::array(); - for (const auto &orderData : ordersData) { - orders.emplace_back(OrderJson(orderData)); - } + SetOrdersConstraints(obj.in.opt, ordersConstraints); - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container ordersPerExchangeUser; - ordersPerExchangeUser.emplace(exchangePtr->keyName(), std::move(orders)); - out.emplace(exchangePtr->name(), std::move(ordersPerExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(orders)); + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + + for (const auto &[e, ordersData] : ordersPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + exchangeKeyPart.reserve(ordersData.size()); + for (const auto &orderData : ordersData) { + SetOrder(orderData, exchangeKeyPart.emplace_back()); } } - return ToJson(coincenterCommandType, std::move(in), std::move(out)); + return obj; } -json::container OrdersCancelledJson(const NbCancelledOrdersPerExchange &nbCancelledOrdersPerExchange, - const OrdersConstraints &ordersConstraints) { - json::container in; - json::container inOpt = OrdersConstraintsToJson(ordersConstraints); +auto OrdersCancelledJson(const NbCancelledOrdersPerExchange &nbCancelledOrdersPerExchange, + const OrdersConstraints &ordersConstraints) { + schema::queryresult::OrdersCancelled obj; - if (!inOpt.empty()) { - in.emplace("opt", std::move(inOpt)); - } + obj.in.req = CoincenterCommandType::OrdersCancel; - json::container out = json::container::object(); - for (const auto &[exchangePtr, nbCancelledOrders] : nbCancelledOrdersPerExchange) { - json::container cancelledOrdersForAccount; - cancelledOrdersForAccount.emplace("nb", nbCancelledOrders); + SetOrdersConstraints(obj.in.opt, ordersConstraints); - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container cancelledOrdersForExchangeUser; - cancelledOrdersForExchangeUser.emplace(exchangePtr->keyName(), std::move(cancelledOrdersForAccount)); - out.emplace(exchangePtr->name(), std::move(cancelledOrdersForExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(cancelledOrdersForAccount)); - } + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + + for (const auto &[e, nbCancelledOrders] : nbCancelledOrdersPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + exchangeKeyPart.nb = nbCancelledOrders; } - return ToJson(CoincenterCommandType::OrdersCancel, std::move(in), std::move(out)); + return obj; } enum class DepositOrWithdrawEnum : int8_t { kDeposit, kWithdraw }; -json::container DepositsConstraintsToJson(const WithdrawsOrDepositsConstraints &constraints, - DepositOrWithdrawEnum depositOrWithdraw) { - json::container ret; +void SetDepositOrWithdrawConstraints(std::optional &opt, + const WithdrawsOrDepositsConstraints &constraints, + DepositOrWithdrawEnum depositOrWithdraw) { + auto &initializedOpt = opt.emplace(); + bool reset = true; if (constraints.isCurDefined()) { - ret.emplace("cur", constraints.currencyCode().str()); + initializedOpt.cur = constraints.currencyCode(); + reset = false; } + const bool isDeposit = depositOrWithdraw == DepositOrWithdrawEnum::kDeposit; if (constraints.isTimeBeforeDefined()) { - ret.emplace(depositOrWithdraw == DepositOrWithdrawEnum::kDeposit ? "receivedBefore" : "sentBefore", - TimeToString(constraints.timeBefore())); + if (isDeposit) { + initializedOpt.receivedBefore.emplace(constraints.timeBefore()); + } else { + initializedOpt.sentBefore.emplace(constraints.timeBefore()); + } + reset = false; } if (constraints.isTimeAfterDefined()) { - ret.emplace(depositOrWithdraw == DepositOrWithdrawEnum::kDeposit ? "receivedAfter" : "sentAfter", - TimeToString(constraints.timeAfter())); + if (isDeposit) { + initializedOpt.receivedAfter.emplace(constraints.timeAfter()); + } else { + initializedOpt.sentAfter.emplace(constraints.timeAfter()); + } + reset = false; } if (constraints.isIdDefined()) { - json::container depositIds = json::container::array(); - for (const string &depositId : constraints.idSet()) { - depositIds.emplace_back(depositId); - } - ret.emplace("matchIds", std::move(depositIds)); + initializedOpt.matchIds = constraints.idSet(); + reset = false; + } + if (reset) { + opt.reset(); } - return ret; } -json::container RecentDepositsJson(const DepositsPerExchange &depositsPerExchange, - const DepositsConstraints &depositsConstraints) { - json::container in; - json::container inOpt = DepositsConstraintsToJson(depositsConstraints, DepositOrWithdrawEnum::kDeposit); +auto RecentDepositsJson(const DepositsPerExchange &depositsPerExchange, + const DepositsConstraints &depositsConstraints) { + schema::queryresult::RecentDeposits obj; - if (!inOpt.empty()) { - in.emplace("opt", std::move(inOpt)); - } + SetDepositOrWithdrawConstraints(obj.in.opt, depositsConstraints, DepositOrWithdrawEnum::kDeposit); - json::container out = json::container::object(); - for (const auto &[exchangePtr, deposits] : depositsPerExchange) { - json::container depositsJson = json::container::array(); - for (const Deposit &deposit : deposits) { - json::container &depositJson = depositsJson.emplace_back(); - depositJson.emplace("id", deposit.id()); - depositJson.emplace("cur", deposit.amount().currencyStr()); - depositJson.emplace("receivedTime", deposit.timeStr()); - depositJson.emplace("amount", deposit.amount().amountStr()); - depositJson.emplace("status", deposit.statusStr()); - } + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + for (const auto &[e, deposits] : depositsPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container depositsPerExchangeUser; - depositsPerExchangeUser.emplace(exchangePtr->keyName(), std::move(depositsJson)); - out.emplace(exchangePtr->name(), std::move(depositsPerExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(depositsJson)); + exchangeKeyPart.reserve(deposits.size()); + for (const Deposit &deposit : deposits) { + auto &elem = exchangeKeyPart.emplace_back(); + elem.id = deposit.id(); + elem.cur = deposit.amount().currencyCode(); + elem.receivedTime.ts = deposit.time(); + elem.amount = deposit.amount().toNeutral(); + elem.status = deposit.status(); } } - return ToJson(CoincenterCommandType::RecentDeposits, std::move(in), std::move(out)); + return obj; } -json::container RecentWithdrawsJson(const WithdrawsPerExchange &withdrawsPerExchange, - const WithdrawsConstraints &withdrawsConstraints) { - json::container in; - json::container inOpt = DepositsConstraintsToJson(withdrawsConstraints, DepositOrWithdrawEnum::kWithdraw); +auto RecentWithdrawsJson(const WithdrawsPerExchange &withdrawsPerExchange, + const WithdrawsConstraints &withdrawsConstraints) { + schema::queryresult::RecentWithdraws obj; - if (!inOpt.empty()) { - in.emplace("opt", std::move(inOpt)); - } + SetDepositOrWithdrawConstraints(obj.in.opt, withdrawsConstraints, DepositOrWithdrawEnum::kWithdraw); - json::container out = json::container::object(); - for (const auto &[exchangePtr, withdraws] : withdrawsPerExchange) { - json::container withdrawsJson = json::container::array(); - for (const Withdraw &withdraw : withdraws) { - json::container &withdrawJson = withdrawsJson.emplace_back(); - withdrawJson.emplace("id", withdraw.id()); - withdrawJson.emplace("cur", withdraw.amount().currencyStr()); - withdrawJson.emplace("sentTime", withdraw.timeStr()); - withdrawJson.emplace("netEmittedAmount", withdraw.amount().amountStr()); - withdrawJson.emplace("fee", withdraw.withdrawFee().amountStr()); - withdrawJson.emplace("status", withdraw.statusStr()); - } + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + for (const auto &[e, withdraws] : withdrawsPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container withdrawsPerExchangeUser; - withdrawsPerExchangeUser.emplace(exchangePtr->keyName(), std::move(withdrawsJson)); - out.emplace(exchangePtr->name(), std::move(withdrawsPerExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(withdrawsJson)); + exchangeKeyPart.reserve(withdraws.size()); + for (const Withdraw &withdraw : withdraws) { + auto &elem = exchangeKeyPart.emplace_back(); + elem.id = withdraw.id(); + elem.cur = withdraw.amount().currencyCode(); + elem.sentTime.ts = withdraw.time(); + elem.netEmittedAmount = withdraw.amount().toNeutral(); + elem.fee = withdraw.withdrawFee().toNeutral(); + elem.status = withdraw.status(); } } - return ToJson(CoincenterCommandType::RecentWithdraws, std::move(in), std::move(out)); + return obj; } -json::container ConversionJson(MonetaryAmount amount, CurrencyCode targetCurrencyCode, - const MonetaryAmountPerExchange &conversionPerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("amount", amount.str()); - inOpt.emplace("targetCurrency", targetCurrencyCode.str()); - in.emplace("opt", std::move(inOpt)); +auto ConversionJson(MonetaryAmount amount, CurrencyCode targetCurrencyCode, + const MonetaryAmountPerExchange &conversionPerExchange) { + schema::queryresult::Conversion1 obj; + + obj.in.opt.fromAmount = amount.toNeutral(); + obj.in.opt.fromCurrency = amount.currencyCode(); + obj.in.opt.toCurrency = targetCurrencyCode; - json::container out = json::container::object(); for (const auto &[e, convertedAmount] : conversionPerExchange) { if (convertedAmount != 0) { - json::container conversionForExchange; - conversionForExchange.emplace("convertedAmount", convertedAmount.str()); - out.emplace(e->name(), std::move(conversionForExchange)); + using ExchangePart = decltype(obj.out)::value_type::second_type; + + obj.out.emplace_back(e->exchangeNameEnum(), ExchangePart{.convertedAmount = convertedAmount.toNeutral()}); } } - return ToJson(CoincenterCommandType::Conversion, std::move(in), std::move(out)); + return obj; } -json::container ConversionJson(std::span startAmountPerExchangePos, - CurrencyCode targetCurrencyCode, - const MonetaryAmountPerExchange &conversionPerExchange) { - json::container in; - json::container inOpt; +auto ConversionJson(std::span startAmountPerExchangePos, CurrencyCode targetCurrencyCode, + const MonetaryAmountPerExchange &conversionPerExchange) { + schema::queryresult::Conversion2 obj; - json::container fromAmounts; + obj.in.opt.toCurrency = targetCurrencyCode; int publicExchangePos{}; for (MonetaryAmount startAmount : startAmountPerExchangePos) { if (!startAmount.isDefault()) { - fromAmounts.emplace(kSupportedExchanges[publicExchangePos], startAmount.str()); + using ExchangePart = decltype(obj.in.opt.fromAmount)::value_type::second_type; + + obj.in.opt.fromAmount.emplace_back( + static_cast(publicExchangePos), + ExchangePart{.amount = startAmount.toNeutral(), .cur = startAmount.currencyCode()}); } ++publicExchangePos; } - inOpt.emplace("sourceAmount", std::move(fromAmounts)); - inOpt.emplace("targetCurrency", targetCurrencyCode.str()); - in.emplace("opt", std::move(inOpt)); - - json::container out = json::container::object(); for (const auto &[e, convertedAmount] : conversionPerExchange) { if (convertedAmount != 0) { - json::container conversionForExchange; - conversionForExchange.emplace("convertedAmount", convertedAmount.str()); - out.emplace(e->name(), std::move(conversionForExchange)); + using ExchangePart = decltype(obj.out)::value_type::second_type; + + obj.out.emplace_back(e->exchangeNameEnum(), ExchangePart{.convertedAmount = convertedAmount.toNeutral()}); } } - return ToJson(CoincenterCommandType::Conversion, std::move(in), std::move(out)); + return obj; } -json::container ConversionPathJson(Market mk, const ConversionPathPerExchange &conversionPathsPerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("market", mk.str()); - in.emplace("opt", std::move(inOpt)); +auto ConversionPathJson(Market mk, const ConversionPathPerExchange &conversionPathsPerExchange) { + schema::queryresult::ConversionPath obj; + + obj.in.opt.market = mk; - json::container out = json::container::object(); for (const auto &[e, conversionPath] : conversionPathsPerExchange) { if (!conversionPath.empty()) { - json::container conversionPathForExchange; - for (Market market : conversionPath) { - conversionPathForExchange.emplace_back(market.str()); - } - out.emplace(e->name(), std::move(conversionPathForExchange)); + obj.out.emplace_back(e->exchangeNameEnum(), conversionPath); } } - return ToJson(CoincenterCommandType::ConversionPath, std::move(in), std::move(out)); + return obj; } -json::container WithdrawFeesJson(const MonetaryAmountByCurrencySetPerExchange &withdrawFeePerExchange, - CurrencyCode cur) { - json::container in; - json::container inOpt = json::container::object(); +auto WithdrawFeesJson(const MonetaryAmountByCurrencySetPerExchange &withdrawFeePerExchange, CurrencyCode cur) { + schema::queryresult::WithdrawFees obj; + if (!cur.isNeutral()) { - inOpt.emplace("cur", cur.str()); + obj.in.opt.cur = cur; } - in.emplace("opt", std::move(inOpt)); - json::container out = json::container::object(); for (const auto &[e, withdrawFees] : withdrawFeePerExchange) { - json::container amountsPerExchange = json::container::array(); - for (MonetaryAmount ma : withdrawFees) { - amountsPerExchange.emplace_back(ma.str()); - } - out.emplace(e->name(), std::move(amountsPerExchange)); + obj.out.emplace_back(e->exchangeNameEnum(), withdrawFees); } - return ToJson(CoincenterCommandType::WithdrawFees, std::move(in), std::move(out)); + return obj; } -json::container Last24hTradedVolumeJson(Market mk, const MonetaryAmountPerExchange &tradedVolumePerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("market", mk.str()); - in.emplace("opt", std::move(inOpt)); +auto Last24hTradedVolumeJson(Market mk, const MonetaryAmountPerExchange &tradedVolumePerExchange) { + schema::queryresult::Last24hTradedVolume obj; + obj.in.opt.market = mk; - json::container out = json::container::object(); for (const auto &[e, tradedVolume] : tradedVolumePerExchange) { - out.emplace(e->name(), tradedVolume.amountStr()); + obj.out.emplace_back(e->exchangeNameEnum(), tradedVolume.toNeutral()); } - return ToJson(CoincenterCommandType::Last24hTradedVolume, std::move(in), std::move(out)); + return obj; } -json::container LastTradesJson(Market mk, std::optional nbLastTrades, - const TradesPerExchange &lastTradesPerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("market", mk.str()); - if (nbLastTrades) { - inOpt.emplace("nb", *nbLastTrades); - } - in.emplace("opt", std::move(inOpt)); +auto LastTradesJson(Market mk, std::optional nbLastTrades, const TradesPerExchange &lastTradesPerExchange) { + schema::queryresult::LastTrades obj; + + obj.in.opt.market = mk; + obj.in.opt.nb = nbLastTrades; - json::container out = json::container::object(); - for (const auto &[exchangePtr, lastTrades] : lastTradesPerExchange) { - json::container lastTradesJson = json::container::array(); + for (const auto &[e, lastTrades] : lastTradesPerExchange) { + using ExchangePart = decltype(obj.out)::value_type::second_type; + + auto &exchangePart = obj.out.emplace_back(e->exchangeNameEnum(), ExchangePart{}).second; + + exchangePart.reserve(lastTrades.size()); for (const PublicTrade &trade : lastTrades) { - json::container &lastTrade = lastTradesJson.emplace_back(); - lastTrade.emplace("a", trade.amount().amountStr()); - lastTrade.emplace("p", trade.price().amountStr()); - lastTrade.emplace("time", trade.timeStr()); - lastTrade.emplace("side", SideStr(trade.side())); + auto &lastTrade = exchangePart.emplace_back(); + + lastTrade.a = trade.amount().toNeutral(); + lastTrade.p = trade.price().toNeutral(); + lastTrade.time.ts = trade.time(); + lastTrade.side = trade.side(); } - out.emplace(exchangePtr->name(), std::move(lastTradesJson)); } - return ToJson(CoincenterCommandType::LastTrades, std::move(in), std::move(out)); + return obj; } -json::container LastPriceJson(Market mk, const MonetaryAmountPerExchange &pricePerExchange) { - json::container in; - json::container inOpt; - inOpt.emplace("market", mk.str()); - in.emplace("opt", std::move(inOpt)); +auto LastPriceJson(Market mk, const MonetaryAmountPerExchange &pricePerExchange) { + schema::queryresult::LastPrice obj; + + obj.in.opt.market = mk; - json::container out = json::container::object(); for (const auto &[e, lastPrice] : pricePerExchange) { - out.emplace(e->name(), lastPrice.amountStr()); + obj.out.emplace_back(e->exchangeNameEnum(), lastPrice.toNeutral()); } - return ToJson(CoincenterCommandType::LastPrice, std::move(in), std::move(out)); + return obj; } -json::container WithdrawJson(const DeliveredWithdrawInfo &deliveredWithdrawInfo, MonetaryAmount grossAmount, - bool isPercentageWithdraw, const Exchange &fromExchange, const Exchange &toExchange, - const WithdrawOptions &withdrawOptions) { - json::container in; - json::container inOpt; - inOpt.emplace("cur", grossAmount.currencyStr()); - inOpt.emplace("isPercentage", isPercentageWithdraw); - inOpt.emplace("syncPolicy", withdrawOptions.withdrawSyncPolicyStr()); - in.emplace("opt", std::move(inOpt)); - - json::container from; - from.emplace("exchange", fromExchange.name()); - from.emplace("account", fromExchange.keyName()); - from.emplace("id", deliveredWithdrawInfo.withdrawId()); - from.emplace("amount", grossAmount.amountStr()); - from.emplace("time", TimeToString(deliveredWithdrawInfo.initiatedTime())); - - json::container to; - to.emplace("exchange", toExchange.name()); - to.emplace("account", toExchange.keyName()); - to.emplace("id", deliveredWithdrawInfo.depositId()); - to.emplace("amount", deliveredWithdrawInfo.receivedAmount().amountStr()); - to.emplace("address", deliveredWithdrawInfo.receivingWallet().address()); +auto WithdrawJson(const DeliveredWithdrawInfo &deliveredWithdrawInfo, MonetaryAmount grossAmount, + bool isPercentageWithdraw, const Exchange &fromExchange, const Exchange &toExchange, + const WithdrawOptions &withdrawOptions) { + schema::queryresult::Withdraw obj; + + obj.in.opt.cur = grossAmount.currencyCode(); + obj.in.opt.isPercentage = isPercentageWithdraw; + obj.in.opt.syncPolicy = withdrawOptions.withdrawSyncPolicy(); + + obj.out.from.exchange = fromExchange.exchangeNameEnum(); + obj.out.from.account = fromExchange.keyName(); + obj.out.from.id = deliveredWithdrawInfo.withdrawId(); + obj.out.from.amount = grossAmount.toNeutral(); + obj.out.from.time.ts = deliveredWithdrawInfo.initiatedTime(); + + obj.out.to.exchange = toExchange.exchangeNameEnum(); + obj.out.to.account = toExchange.keyName(); + obj.out.to.id = deliveredWithdrawInfo.depositId(); + obj.out.to.amount = deliveredWithdrawInfo.receivedAmount().toNeutral(); + obj.out.to.address = deliveredWithdrawInfo.receivingWallet().address(); if (deliveredWithdrawInfo.receivingWallet().hasTag()) { - to.emplace("tag", deliveredWithdrawInfo.receivingWallet().tag()); + obj.out.to.tag = deliveredWithdrawInfo.receivingWallet().tag(); } - to.emplace("time", TimeToString(deliveredWithdrawInfo.receivedTime())); - - json::container out; - out.emplace("from", std::move(from)); - out.emplace("to", std::move(to)); + obj.out.to.time.ts = deliveredWithdrawInfo.receivedTime(); - return ToJson(CoincenterCommandType::Withdraw, std::move(in), std::move(out)); + return obj; } -json::container DustSweeperJson( - const TradedAmountsVectorWithFinalAmountPerExchange &tradedAmountsVectorWithFinalAmountPerExchange, - CurrencyCode currencyCode) { - json::container in; - json::container inOpt; - inOpt.emplace("cur", currencyCode.str()); - in.emplace("opt", std::move(inOpt)); - - json::container out = json::container::object(); - for (const auto &[exchangePtr, tradedAmountsVectorWithFinalAmount] : tradedAmountsVectorWithFinalAmountPerExchange) { - json::container tradedAmountsArray = json::container::array_t(); - for (const auto &tradedAmounts : tradedAmountsVectorWithFinalAmount.tradedAmountsVector) { - json::container tradedAmountsData; - tradedAmountsData.emplace("from", tradedAmounts.from.str()); - tradedAmountsData.emplace("to", tradedAmounts.to.str()); - tradedAmountsArray.push_back(std::move(tradedAmountsData)); - } +auto DustSweeperJson(const TradedAmountsVectorWithFinalAmountPerExchange &tradedAmountsVectorWithFinalAmountPerExchange, + CurrencyCode currencyCode) { + schema::queryresult::DustSweeper obj; - json::container tradedInfoPerExchangeData; - tradedInfoPerExchangeData.emplace("trades", std::move(tradedAmountsArray)); - tradedInfoPerExchangeData.emplace("finalAmount", tradedAmountsVectorWithFinalAmount.finalAmount.str()); + obj.in.opt.cur = currencyCode; - auto it = out.find(exchangePtr->name()); - if (it == out.end()) { - json::container dataForExchangeUser; - dataForExchangeUser.emplace(exchangePtr->keyName(), std::move(tradedInfoPerExchangeData)); - out.emplace(exchangePtr->name(), std::move(dataForExchangeUser)); - } else { - it->emplace(exchangePtr->keyName(), std::move(tradedInfoPerExchangeData)); + using ExchangePart = decltype(obj.out)::value_type::second_type; + using ExchangeKeyPart = ExchangePart::value_type::second_type; + + for (const auto &[e, tradedAmountsVectorWithFinalAmount] : tradedAmountsVectorWithFinalAmountPerExchange) { + auto &exchangePart = GetExchangePart(e, obj.out); + auto &exchangeKeyPart = exchangePart.emplace_back(e->keyName(), ExchangeKeyPart{}).second; + + exchangeKeyPart.trades.reserve(tradedAmountsVectorWithFinalAmount.tradedAmountsVector.size()); + for (const auto &tradedAmounts : tradedAmountsVectorWithFinalAmount.tradedAmountsVector) { + exchangeKeyPart.trades.emplace_back(tradedAmounts.from, tradedAmounts.to); } + exchangeKeyPart.finalAmount = tradedAmountsVectorWithFinalAmount.finalAmount; } - return ToJson(CoincenterCommandType::DustSweeper, std::move(in), std::move(out)); + return obj; } -json::container MarketTradingResultsJson(TimeWindow inputTimeWindow, const ReplayResults &replayResults, - CoincenterCommandType commandType) { - json::container inOpt; - - const auto createTimeStats = [](TimeWindow timeWindow) { - json::container ret; - ret.emplace("from", TimeToString(timeWindow.from())); - ret.emplace("to", TimeToString(timeWindow.to())); - return ret; - }; +auto MarketTradingResultsJson(TimeWindow inputTimeWindow, const ReplayResults &replayResults, + CoincenterCommandType commandType) { + schema::queryresult::MarketTradingResults obj; - inOpt.emplace("time", createTimeStats(inputTimeWindow)); + obj.in.req = commandType; - json::container in; - in.emplace("opt", std::move(inOpt)); - - json::container out = json::container::object(); + obj.in.opt.time.from.ts = inputTimeWindow.from(); + obj.in.opt.time.to.ts = inputTimeWindow.to(); + obj.out.reserve(replayResults.size()); for (const auto &[algorithmName, marketTradingResultPerExchangeVector] : replayResults) { - json::container algorithmNameResults = json::container::array_t(); - for (const auto &marketTradingResultPerExchange : marketTradingResultPerExchangeVector) { - json::container allResults = json::container::array_t(); - for (const auto &[exchangePtr, marketGlobalTradingResult] : marketTradingResultPerExchange) { - const auto &marketTradingResult = marketGlobalTradingResult.result; - const auto &stats = marketGlobalTradingResult.stats; + using AlgorithmNameResults = decltype(obj.out)::value_type::second_type; + auto &algorithmNameResults = obj.out.emplace_back(algorithmName, AlgorithmNameResults{}).second; - const auto computeTradeRangeResultsStats = - [&createTimeStats](const TradeRangeResultsStats &tradeRangeResultsStats) { - json::container ret; - ret.emplace("nb-successful", tradeRangeResultsStats.nbSuccessful); - ret.emplace("nb-error", tradeRangeResultsStats.nbError); - - ret.emplace("time", createTimeStats(tradeRangeResultsStats.timeWindow)); - return ret; - }; + algorithmNameResults.reserve(marketTradingResultPerExchangeVector.size()); + for (const auto &marketTradingResultPerExchange : marketTradingResultPerExchangeVector) { + using AllResults = AlgorithmNameResults::value_type; - json::container startAmounts; - startAmounts.emplace("base", marketTradingResult.startBaseAmount().str()); - startAmounts.emplace("quote", marketTradingResult.startQuoteAmount().str()); + auto &allResults = algorithmNameResults.emplace_back(); - json::container orderBookStats = computeTradeRangeResultsStats(stats.marketOrderBookStats); + allResults.reserve(marketTradingResultPerExchange.size()); + for (const auto &[e, marketGlobalTradingResult] : marketTradingResultPerExchange) { + const auto &marketTradingResult = marketGlobalTradingResult.result; + const auto &stats = marketGlobalTradingResult.stats; - json::container tradeStats = computeTradeRangeResultsStats(stats.publicTradeStats); + auto &exchangeMarketResults = allResults.emplace_back(); - json::container jsonStats; - jsonStats.emplace("order-books", std::move(orderBookStats)); - jsonStats.emplace("trades", std::move(tradeStats)); + using MarketTradingResult = AllResults::value_type::value_type::second_type; - json::container marketTradingResultJson; - marketTradingResultJson.emplace("algorithm", marketTradingResult.algorithmName()); - marketTradingResultJson.emplace("market", marketTradingResult.market().str()); - marketTradingResultJson.emplace("start-amounts", std::move(startAmounts)); - marketTradingResultJson.emplace("profit-and-loss", marketTradingResult.quoteAmountDelta().str()); - marketTradingResultJson.emplace("stats", std::move(jsonStats)); + auto &marketTradingResultPart = + exchangeMarketResults.emplace_back(e->exchangeNameEnum(), MarketTradingResult{}).second; - json::container closedOrdersArray = json::container::array_t(); + marketTradingResultPart.algorithm = marketTradingResult.algorithmName(); + marketTradingResultPart.market = marketTradingResult.market(); + marketTradingResultPart.startAmounts.base = marketTradingResult.startBaseAmount(); + marketTradingResultPart.startAmounts.quote = marketTradingResult.startQuoteAmount(); + marketTradingResultPart.profitAndLoss = marketTradingResult.quoteAmountDelta(); + marketTradingResultPart.stats.orderBooks.nbSuccessful = stats.marketOrderBookStats.nbSuccessful; + marketTradingResultPart.stats.orderBooks.nbError = stats.marketOrderBookStats.nbError; + marketTradingResultPart.stats.orderBooks.time.from.ts = stats.marketOrderBookStats.timeWindow.from(); + marketTradingResultPart.stats.orderBooks.time.to.ts = stats.marketOrderBookStats.timeWindow.to(); + marketTradingResultPart.stats.trades.nbSuccessful = stats.publicTradeStats.nbSuccessful; + marketTradingResultPart.stats.trades.nbError = stats.publicTradeStats.nbError; + marketTradingResultPart.stats.trades.time.from.ts = stats.publicTradeStats.timeWindow.from(); + marketTradingResultPart.stats.trades.time.to.ts = stats.publicTradeStats.timeWindow.to(); + marketTradingResultPart.matchedOrders.reserve(marketTradingResult.matchedOrders().size()); for (const ClosedOrder &closedOrder : marketTradingResult.matchedOrders()) { - closedOrdersArray.push_back(OrderJson(closedOrder)); + SetOrder(closedOrder, marketTradingResultPart.matchedOrders.emplace_back()); } - - marketTradingResultJson.emplace("matched-orders", std::move(closedOrdersArray)); - - json::container exchangeMarketResults; - exchangeMarketResults.emplace(exchangePtr->name(), std::move(marketTradingResultJson)); - - allResults.push_back(std::move(exchangeMarketResults)); } - algorithmNameResults.push_back(std::move(allResults)); } - - out.emplace(algorithmName, std::move(algorithmNameResults)); } - return ToJson(commandType, std::move(in), std::move(out)); + return obj; } template @@ -872,7 +770,7 @@ QueryResultPrinter::QueryResultPrinter(std::ostream &os, ApiOutputType apiOutput _apiOutputType(apiOutputType) {} void QueryResultPrinter::printHealthCheck(const ExchangeHealthCheckStatus &healthCheckPerExchange) const { - json::container jsonData = HealthCheckJson(healthCheckPerExchange); + auto jsonObj = HealthCheckJson(healthCheckPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -885,12 +783,12 @@ void QueryResultPrinter::printHealthCheck(const ExchangeHealthCheckStatus &healt break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::HealthCheck, jsonData); + logActivity(CoincenterCommandType::HealthCheck, jsonObj); } namespace { @@ -913,7 +811,7 @@ void Append(string &str, std::string_view exchangeName) { } // namespace void QueryResultPrinter::printCurrencies(const CurrenciesPerExchange ¤ciesPerExchange) const { - json::container jsonData = CurrenciesJson(currenciesPerExchange); + auto jsonObj = CurrenciesJson(currenciesPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { // Compute all currencies for all exchanges @@ -975,18 +873,18 @@ void QueryResultPrinter::printCurrencies(const CurrenciesPerExchange ¤cies break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Currencies, jsonData); + logActivity(CoincenterCommandType::Currencies, jsonObj); } void QueryResultPrinter::printMarkets(CurrencyCode cur1, CurrencyCode cur2, const MarketsPerExchange &marketsPerExchange, CoincenterCommandType coincenterCommandType) const { - json::container jsonData = MarketsJson(cur1, cur2, marketsPerExchange); + auto jsonObj = MarketsJson(cur1, cur2, marketsPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string marketsCol("Markets"); @@ -1009,16 +907,16 @@ void QueryResultPrinter::printMarkets(CurrencyCode cur1, CurrencyCode cur2, break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(coincenterCommandType, jsonData); + logActivity(coincenterCommandType, jsonObj); } void QueryResultPrinter::printTickerInformation(const ExchangeTickerMaps &exchangeTickerMaps) const { - json::container jsonData = TickerInformationJson(exchangeTickerMaps); + auto jsonObj = TickerInformationJson(exchangeTickerMaps); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1036,18 +934,18 @@ void QueryResultPrinter::printTickerInformation(const ExchangeTickerMaps &exchan break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Ticker, jsonData); + logActivity(CoincenterCommandType::Ticker, jsonObj); } void QueryResultPrinter::printMarketOrderBooks( Market mk, CurrencyCode equiCurrencyCode, std::optional depth, const MarketOrderBookConversionRates &marketOrderBooksConversionRates) const { - const json::container jsonData = MarketOrderBooksJson(mk, equiCurrencyCode, depth, marketOrderBooksConversionRates); + const auto jsonObj = MarketOrderBooksJson(mk, equiCurrencyCode, depth, marketOrderBooksConversionRates); switch (_apiOutputType) { case ApiOutputType::table: { for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { @@ -1056,16 +954,16 @@ void QueryResultPrinter::printMarketOrderBooks( break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Orderbook, jsonData); + logActivity(CoincenterCommandType::Orderbook, jsonObj); } void QueryResultPrinter::printBalance(const BalancePerExchange &balancePerExchange, CurrencyCode equiCurrency) const { - json::container jsonData = BalanceJson(balancePerExchange, equiCurrency); + auto jsonObj = BalanceJson(balancePerExchange, equiCurrency); switch (_apiOutputType) { case ApiOutputType::table: { BalancePerExchangePortfolio totalBalance(balancePerExchange); @@ -1073,17 +971,17 @@ void QueryResultPrinter::printBalance(const BalancePerExchange &balancePerExchan break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Balance, jsonData); + logActivity(CoincenterCommandType::Balance, jsonObj); } void QueryResultPrinter::printDepositInfo(CurrencyCode depositCurrencyCode, const WalletPerExchange &walletPerExchange) const { - json::container jsonData = DepositInfoJson(depositCurrencyCode, walletPerExchange); + auto jsonObj = DepositInfoJson(depositCurrencyCode, walletPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string walletStr(depositCurrencyCode.str()); @@ -1098,26 +996,26 @@ void QueryResultPrinter::printDepositInfo(CurrencyCode depositCurrencyCode, break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::DepositInfo, jsonData); + logActivity(CoincenterCommandType::DepositInfo, jsonObj); } void QueryResultPrinter::printTrades(const TradeResultPerExchange &tradeResultPerExchange, MonetaryAmount amount, bool isPercentageTrade, CurrencyCode toCurrency, const TradeOptions &tradeOptions, CoincenterCommandType commandType) const { - json::container jsonData = - TradesJson(tradeResultPerExchange, amount, isPercentageTrade, toCurrency, tradeOptions, commandType); + auto jsonObj = TradesJson(tradeResultPerExchange, amount, isPercentageTrade, toCurrency, tradeOptions, commandType); switch (_apiOutputType) { case ApiOutputType::table: { string tradedFromStr("Traded from amount ("); - tradedFromStr.append(TradeModeToStr(tradeOptions.tradeMode())); + auto tradeModeStr = WriteSingleObjectJsonNoQuotes(tradeOptions.tradeMode()); + tradedFromStr.append(tradeModeStr); tradedFromStr.push_back(')'); string tradedToStr("Traded to amount ("); - tradedToStr.append(TradeModeToStr(tradeOptions.tradeMode())); + tradedToStr.append(tradeModeStr); tradedToStr.push_back(')'); SimpleTable table; @@ -1128,24 +1026,24 @@ void QueryResultPrinter::printTrades(const TradeResultPerExchange &tradeResultPe const TradedAmounts &tradedAmounts = tradeResult.tradedAmounts(); table.emplace_back(exchangePtr->name(), exchangePtr->keyName(), tradeResult.from().str(), - tradedAmounts.from.str(), tradedAmounts.to.str(), tradeResult.stateStr()); + tradedAmounts.from.str(), tradedAmounts.to.str(), + WriteSingleObjectJsonNoQuotes(tradeResult.state())); } printTable(table); break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(commandType, jsonData, tradeOptions.isSimulation()); + logActivity(commandType, jsonObj, tradeOptions.isSimulation()); } void QueryResultPrinter::printClosedOrders(const ClosedOrdersPerExchange &closedOrdersPerExchange, const OrdersConstraints &ordersConstraints) const { - json::container jsonData = - OrdersJson(CoincenterCommandType::OrdersClosed, closedOrdersPerExchange, ordersConstraints); + auto jsonObj = OrdersJson(CoincenterCommandType::OrdersClosed, closedOrdersPerExchange, ordersConstraints); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1153,8 +1051,9 @@ void QueryResultPrinter::printClosedOrders(const ClosedOrdersPerExchange &closed "Matched Amount"); for (const auto &[exchangePtr, closedOrders] : closedOrdersPerExchange) { for (const ClosedOrder &closedOrder : closedOrders) { - table.emplace_back(exchangePtr->name(), exchangePtr->keyName(), closedOrder.id(), closedOrder.placedTimeStr(), - closedOrder.matchedTimeStr(), closedOrder.sideStr(), closedOrder.price().str(), + table.emplace_back(exchangePtr->name(), exchangePtr->keyName(), closedOrder.id(), + TimeToString(closedOrder.placedTime()), TimeToString(closedOrder.matchedTime()), + WriteSingleObjectJsonNoQuotes(closedOrder.side()), closedOrder.price().str(), closedOrder.matchedVolume().str()); } } @@ -1162,18 +1061,17 @@ void QueryResultPrinter::printClosedOrders(const ClosedOrdersPerExchange &closed break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::OrdersClosed, jsonData); + logActivity(CoincenterCommandType::OrdersClosed, jsonObj); } void QueryResultPrinter::printOpenedOrders(const OpenedOrdersPerExchange &openedOrdersPerExchange, const OrdersConstraints &ordersConstraints) const { - json::container jsonData = - OrdersJson(CoincenterCommandType::OrdersOpened, openedOrdersPerExchange, ordersConstraints); + auto jsonObj = OrdersJson(CoincenterCommandType::OrdersOpened, openedOrdersPerExchange, ordersConstraints); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1181,8 +1079,9 @@ void QueryResultPrinter::printOpenedOrders(const OpenedOrdersPerExchange &opened "Remaining Amount"); for (const auto &[exchangePtr, openedOrders] : openedOrdersPerExchange) { for (const OpenedOrder &openedOrder : openedOrders) { - table.emplace_back(exchangePtr->name(), exchangePtr->keyName(), openedOrder.id(), openedOrder.placedTimeStr(), - openedOrder.sideStr(), openedOrder.price().str(), openedOrder.matchedVolume().str(), + table.emplace_back(exchangePtr->name(), exchangePtr->keyName(), openedOrder.id(), + TimeToString(openedOrder.placedTime()), WriteSingleObjectJsonNoQuotes(openedOrder.side()), + openedOrder.price().str(), openedOrder.matchedVolume().str(), openedOrder.remainingVolume().str()); } } @@ -1190,17 +1089,17 @@ void QueryResultPrinter::printOpenedOrders(const OpenedOrdersPerExchange &opened break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::OrdersOpened, jsonData); + logActivity(CoincenterCommandType::OrdersOpened, jsonObj); } void QueryResultPrinter::printCancelledOrders(const NbCancelledOrdersPerExchange &nbCancelledOrdersPerExchange, const OrdersConstraints &ordersConstraints) const { - json::container jsonData = OrdersCancelledJson(nbCancelledOrdersPerExchange, ordersConstraints); + auto jsonObj = OrdersCancelledJson(nbCancelledOrdersPerExchange, ordersConstraints); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1213,17 +1112,17 @@ void QueryResultPrinter::printCancelledOrders(const NbCancelledOrdersPerExchange break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::OrdersCancel, jsonData); + logActivity(CoincenterCommandType::OrdersCancel, jsonObj); } void QueryResultPrinter::printRecentDeposits(const DepositsPerExchange &depositsPerExchange, const DepositsConstraints &depositsConstraints) const { - json::container jsonData = RecentDepositsJson(depositsPerExchange, depositsConstraints); + auto jsonObj = RecentDepositsJson(depositsPerExchange, depositsConstraints); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1238,17 +1137,17 @@ void QueryResultPrinter::printRecentDeposits(const DepositsPerExchange &deposits break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::RecentDeposits, jsonData); + logActivity(CoincenterCommandType::RecentDeposits, jsonObj); } void QueryResultPrinter::printRecentWithdraws(const WithdrawsPerExchange &withdrawsPerExchange, const WithdrawsConstraints &withdrawsConstraints) const { - json::container jsonData = RecentWithdrawsJson(withdrawsPerExchange, withdrawsConstraints); + auto jsonObj = RecentWithdrawsJson(withdrawsPerExchange, withdrawsConstraints); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1263,17 +1162,17 @@ void QueryResultPrinter::printRecentWithdraws(const WithdrawsPerExchange &withdr break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::RecentWithdraws, jsonData); + logActivity(CoincenterCommandType::RecentWithdraws, jsonObj); } void QueryResultPrinter::printConversion(MonetaryAmount amount, CurrencyCode targetCurrencyCode, const MonetaryAmountPerExchange &conversionPerExchange) const { - json::container jsonData = ConversionJson(amount, targetCurrencyCode, conversionPerExchange); + auto jsonObj = ConversionJson(amount, targetCurrencyCode, conversionPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string conversionStrHeader = amount.str(); @@ -1292,18 +1191,18 @@ void QueryResultPrinter::printConversion(MonetaryAmount amount, CurrencyCode tar break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Conversion, jsonData); + logActivity(CoincenterCommandType::Conversion, jsonObj); } void QueryResultPrinter::printConversion(std::span startAmountPerExchangePos, CurrencyCode targetCurrencyCode, const MonetaryAmountPerExchange &conversionPerExchange) const { - json::container jsonData = ConversionJson(startAmountPerExchangePos, targetCurrencyCode, conversionPerExchange); + auto jsonObj = ConversionJson(startAmountPerExchangePos, targetCurrencyCode, conversionPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1318,17 +1217,17 @@ void QueryResultPrinter::printConversion(std::span startAm break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Conversion, jsonData); + logActivity(CoincenterCommandType::Conversion, jsonObj); } void QueryResultPrinter::printConversionPath(Market mk, const ConversionPathPerExchange &conversionPathsPerExchange) const { - json::container jsonData = ConversionPathJson(mk, conversionPathsPerExchange); + auto jsonObj = ConversionPathJson(mk, conversionPathsPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string conversionPathStrHeader("Fastest conversion path for "); @@ -1353,17 +1252,17 @@ void QueryResultPrinter::printConversionPath(Market mk, break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::ConversionPath, jsonData); + logActivity(CoincenterCommandType::ConversionPath, jsonObj); } void QueryResultPrinter::printWithdrawFees(const MonetaryAmountByCurrencySetPerExchange &withdrawFeesPerExchange, CurrencyCode currencyCode) const { - json::container jsonData = WithdrawFeesJson(withdrawFeesPerExchange, currencyCode); + auto jsonObj = WithdrawFeesJson(withdrawFeesPerExchange, currencyCode); switch (_apiOutputType) { case ApiOutputType::table: { table::Row header("Withdraw fee currency"); @@ -1396,17 +1295,17 @@ void QueryResultPrinter::printWithdrawFees(const MonetaryAmountByCurrencySetPerE break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::WithdrawFees, jsonData); + logActivity(CoincenterCommandType::WithdrawFees, jsonObj); } void QueryResultPrinter::printLast24hTradedVolume(Market mk, const MonetaryAmountPerExchange &tradedVolumePerExchange) const { - json::container jsonData = Last24hTradedVolumeJson(mk, tradedVolumePerExchange); + auto jsonObj = Last24hTradedVolumeJson(mk, tradedVolumePerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string headerTradedVolume("Last 24h "); @@ -1422,17 +1321,17 @@ void QueryResultPrinter::printLast24hTradedVolume(Market mk, break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Last24hTradedVolume, jsonData); + logActivity(CoincenterCommandType::Last24hTradedVolume, jsonObj); } void QueryResultPrinter::printLastTrades(Market mk, std::optional nbLastTrades, const TradesPerExchange &lastTradesPerExchange) const { - json::container jsonData = LastTradesJson(mk, nbLastTrades, lastTradesPerExchange); + auto jsonObj = LastTradesJson(mk, nbLastTrades, lastTradesPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { for (const auto &[exchangePtr, lastTrades] : lastTradesPerExchange) { @@ -1453,7 +1352,7 @@ void QueryResultPrinter::printLastTrades(Market mk, std::optional nbLastTra MonetaryAmount totalPrice(0, mk.quote()); std::array nb{}; for (const PublicTrade &trade : lastTrades) { - if (trade.side() == TradeSide::kBuy) { + if (trade.side() == TradeSide::buy) { table.emplace_back(trade.timeStr(), trade.amount().amountStr(), trade.price().amountStr(), ""); totalAmounts[0] += trade.amount(); ++nb[0]; @@ -1485,16 +1384,16 @@ void QueryResultPrinter::printLastTrades(Market mk, std::optional nbLastTra break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::LastTrades, jsonData); + logActivity(CoincenterCommandType::LastTrades, jsonObj); } void QueryResultPrinter::printLastPrice(Market mk, const MonetaryAmountPerExchange &pricePerExchange) const { - json::container jsonData = LastPriceJson(mk, pricePerExchange); + auto jsonObj = LastPriceJson(mk, pricePerExchange); switch (_apiOutputType) { case ApiOutputType::table: { string headerLastPrice(mk.str()); @@ -1509,12 +1408,12 @@ void QueryResultPrinter::printLastPrice(Market mk, const MonetaryAmountPerExchan break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::LastPrice, jsonData); + logActivity(CoincenterCommandType::LastPrice, jsonObj); } void QueryResultPrinter::printWithdraw(const DeliveredWithdrawInfoWithExchanges &deliveredWithdrawInfoWithExchanges, @@ -1523,7 +1422,7 @@ void QueryResultPrinter::printWithdraw(const DeliveredWithdrawInfoWithExchanges MonetaryAmount grossAmount = deliveredWithdrawInfo.grossAmount(); const Exchange &fromExchange = *deliveredWithdrawInfoWithExchanges.first.front(); const Exchange &toExchange = *deliveredWithdrawInfoWithExchanges.first.back(); - json::container jsonData = + auto jsonObj = WithdrawJson(deliveredWithdrawInfo, grossAmount, isPercentageWithdraw, fromExchange, toExchange, withdrawOptions); switch (_apiOutputType) { case ApiOutputType::table: { @@ -1542,18 +1441,18 @@ void QueryResultPrinter::printWithdraw(const DeliveredWithdrawInfoWithExchanges break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::Withdraw, jsonData, withdrawOptions.mode() == WithdrawOptions::Mode::kSimulation); + logActivity(CoincenterCommandType::Withdraw, jsonObj, withdrawOptions.mode() == WithdrawOptions::Mode::kSimulation); } void QueryResultPrinter::printDustSweeper( const TradedAmountsVectorWithFinalAmountPerExchange &tradedAmountsVectorWithFinalAmountPerExchange, CurrencyCode currencyCode) const { - json::container jsonData = DustSweeperJson(tradedAmountsVectorWithFinalAmountPerExchange, currencyCode); + auto jsonObj = DustSweeperJson(tradedAmountsVectorWithFinalAmountPerExchange, currencyCode); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1576,17 +1475,17 @@ void QueryResultPrinter::printDustSweeper( break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::DustSweeper, jsonData); + logActivity(CoincenterCommandType::DustSweeper, jsonObj); } void QueryResultPrinter::printMarketsForReplay(TimeWindow timeWindow, const MarketTimestampSetsPerExchange &marketTimestampSetsPerExchange) { - json::container jsonData = MarketsForReplayJson(timeWindow, marketTimestampSetsPerExchange); + auto jsonObj = MarketsForReplayJson(timeWindow, marketTimestampSetsPerExchange); switch (_apiOutputType) { case ApiOutputType::table: { MarketSet allMarkets = ComputeAllMarkets(marketTimestampSetsPerExchange); @@ -1630,17 +1529,17 @@ void QueryResultPrinter::printMarketsForReplay(TimeWindow timeWindow, break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(CoincenterCommandType::ReplayMarkets, jsonData); + logActivity(CoincenterCommandType::ReplayMarkets, jsonObj); } void QueryResultPrinter::printMarketTradingResults(TimeWindow inputTimeWindow, const ReplayResults &replayResults, CoincenterCommandType commandType) const { - json::container jsonData = MarketTradingResultsJson(inputTimeWindow, replayResults, commandType); + auto jsonObj = MarketTradingResultsJson(inputTimeWindow, replayResults, commandType); switch (_apiOutputType) { case ApiOutputType::table: { SimpleTable table; @@ -1654,9 +1553,9 @@ void QueryResultPrinter::printMarketTradingResults(TimeWindow inputTimeWindow, c table::Cell trades; for (const ClosedOrder &closedOrder : marketTradingResults.matchedOrders()) { - string orderStr = closedOrder.placedTimeStr(); + string orderStr = TimeToString(closedOrder.placedTime()); orderStr.append(" - "); - orderStr.append(closedOrder.sideStr()); + orderStr.append(WriteSingleObjectJsonNoQuotes(closedOrder.side())); orderStr.append(" - "); orderStr.append(closedOrder.matchedVolume().str()); orderStr.append(" @ "); @@ -1698,12 +1597,12 @@ void QueryResultPrinter::printMarketTradingResults(TimeWindow inputTimeWindow, c break; } case ApiOutputType::json: - printJson(jsonData); + printJson(jsonObj); break; case ApiOutputType::off: break; } - logActivity(commandType, jsonData); + logActivity(commandType, jsonObj); } void QueryResultPrinter::printTable(const SimpleTable &table) const { @@ -1720,22 +1619,4 @@ void QueryResultPrinter::printTable(const SimpleTable &table) const { } } -void QueryResultPrinter::printJson(const json::container &jsonData) const { - string jsonStr = jsonData.dump(); - if (_pOs != nullptr) { - *_pOs << jsonStr << '\n'; - } else { - _outputLogger->info(jsonStr); - } -} - -void QueryResultPrinter::logActivity(CoincenterCommandType commandType, const json::container &jsonData, - bool isSimulationMode) const { - if (_loggingInfo.isCommandTypeTracked(commandType) && - (!isSimulationMode || _loggingInfo.alsoLogActivityForSimulatedCommands())) { - File activityFile = _loggingInfo.getActivityFile(); - activityFile.write(jsonData.dump(), Writer::Mode::Append); - } -} - } // namespace cct diff --git a/src/engine/src/traderesult.cpp b/src/engine/src/traderesult.cpp index f680ce38..23bdfdf8 100644 --- a/src/engine/src/traderesult.cpp +++ b/src/engine/src/traderesult.cpp @@ -8,24 +8,11 @@ namespace cct { TradeResult::State TradeResult::state() const { // from could be lower than actually traded from amount if rounding issues if (_from <= _tradedAmounts.from) { - return TradeResult::State::kComplete; + return TradeResult::State::complete; } if (_tradedAmounts.from > 0) { - return TradeResult::State::kPartial; - } - return TradeResult::State::kUntouched; -} - -std::string_view TradeResult::stateStr() const { - switch (state()) { - case State::kComplete: - return "Complete"; - case State::kPartial: - return "Partial"; - case State::kUntouched: - return "Untouched"; - default: - throw exception("Invalid state {}", static_cast(state())); + return TradeResult::State::partial; } + return TradeResult::State::untouched; } } // namespace cct diff --git a/src/engine/test/coincenteroptions_test.cpp b/src/engine/test/coincenteroptions_test.cpp index 52726a97..4d31d5dd 100644 --- a/src/engine/test/coincenteroptions_test.cpp +++ b/src/engine/test/coincenteroptions_test.cpp @@ -96,9 +96,9 @@ TEST_F(CoincenterCmdLineOptionsTest, ComputeTradeOptionsTradeStrategy) { opts.tradeStrategy = "nibble"; opts.tradeTimeoutMatch = true; opts.isSimulation = true; - EXPECT_EQ(opts.computeTradeOptions(), TradeOptions(PriceOptions(opts.tradeStrategy), TradeTimeoutAction::kMatch, - TradeMode::kSimulation, opts.tradeTimeout, opts.tradeUpdatePrice, - TradeTypePolicy::kDefault, TradeSyncPolicy::kSynchronous)); + EXPECT_EQ(opts.computeTradeOptions(), TradeOptions(PriceOptions(opts.tradeStrategy), TradeTimeoutAction::match, + TradeMode::simulation, opts.tradeTimeout, opts.tradeUpdatePrice, + TradeTypePolicy::kDefault, TradeSyncPolicy::synchronous)); } TEST_F(CoincenterCmdLineOptionsTest, ComputeTradeOptionsTradeInvalidTradePrice) { @@ -116,10 +116,10 @@ TEST_F(CoincenterCmdLineOptionsTest, ComputeTradeOptionsTradePrice) { opts.tradePrice = "4XRP"; opts.tradeTimeout = seconds(100); opts.async = true; - EXPECT_EQ( - opts.computeTradeOptions(), - TradeOptions(PriceOptions(MonetaryAmount(4, "XRP")), TradeTimeoutAction::kDefault, TradeMode::kReal, seconds(100), - opts.tradeUpdatePrice, TradeTypePolicy::kForceSingleTrade, TradeSyncPolicy::kAsynchronous)); + EXPECT_EQ(opts.computeTradeOptions(), + TradeOptions(PriceOptions(MonetaryAmount(4, "XRP")), TradeTimeoutAction::exchange_default, TradeMode::real, + seconds(100), opts.tradeUpdatePrice, TradeTypePolicy::kForceSingleTrade, + TradeSyncPolicy::asynchronous)); } TEST_F(CoincenterCmdLineOptionsTest, ComputeTradeArgStrDefault) { EXPECT_TRUE(opts.getTradeArgStr().first.empty()); } diff --git a/src/engine/test/exchangesorchestrator_private_test.cpp b/src/engine/test/exchangesorchestrator_private_test.cpp index d072d1d1..5cfcc614 100644 --- a/src/engine/test/exchangesorchestrator_private_test.cpp +++ b/src/engine/test/exchangesorchestrator_private_test.cpp @@ -37,7 +37,7 @@ class ExchangeOrchestratorTest : public ExchangesBaseTest { protected: ExchangesOrchestrator exchangesOrchestrator{schema::RequestsConfig{}, std::span(&this->exchange1, 8)}; BalanceOptions balanceOptions; - WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::kSynchronous, WithdrawOptions::Mode::kReal}; + WithdrawOptions withdrawOptions{Duration{}, WithdrawSyncPolicy::synchronous, WithdrawOptions::Mode::kReal}; }; TEST_F(ExchangeOrchestratorTest, BalanceNoEquivalentCurrencyUniqueExchange) { @@ -137,18 +137,18 @@ TEST_F(ExchangeOrchestratorTest, GetOpenedOrders) { ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; OpenedOrderVector openedOrders2{OpenedOrder("Id1", MonetaryAmount("0.1ETH"), MonetaryAmount("0.9ETH"), - MonetaryAmount("0.14BTC"), Clock::now(), TradeSide::kBuy), + MonetaryAmount("0.14BTC"), Clock::now(), TradeSide::buy), OpenedOrder("Id2", MonetaryAmount("15XLM"), MonetaryAmount("76XLM"), - MonetaryAmount("0.5EUR"), Clock::now(), TradeSide::kSell)}; + MonetaryAmount("0.5EUR"), Clock::now(), TradeSide::sell)}; EXPECT_CALL(ExchangePrivate(exchange2), queryOpenedOrders(noConstraints)).WillOnce(testing::Return(openedOrders2)); OpenedOrderVector openedOrders3{}; EXPECT_CALL(ExchangePrivate(exchange3), queryOpenedOrders(noConstraints)).WillOnce(testing::Return(openedOrders3)); OpenedOrderVector openedOrders4{OpenedOrder("Id37", MonetaryAmount("0.7ETH"), MonetaryAmount("0.9ETH"), - MonetaryAmount("0.14BTC"), Clock::now(), TradeSide::kSell), + MonetaryAmount("0.14BTC"), Clock::now(), TradeSide::sell), OpenedOrder("Id2", MonetaryAmount("15XLM"), MonetaryAmount("19XLM"), - MonetaryAmount("0.5EUR"), Clock::now(), TradeSide::kBuy)}; + MonetaryAmount("0.5EUR"), Clock::now(), TradeSide::buy)}; EXPECT_CALL(ExchangePrivate(exchange4), queryOpenedOrders(noConstraints)).WillOnce(testing::Return(openedOrders4)); OpenedOrdersPerExchange ret{{&exchange2, OpenedOrderSet(openedOrders2.begin(), openedOrders2.end())}, @@ -260,10 +260,10 @@ class ExchangeOrchestratorWithdrawTest : public ExchangeOrchestratorTest { EXPECT_CALL(ExchangePrivate(exchange1), launchWithdraw(grossAmount, std::move(receivingWallet))) .WillOnce(testing::Return(initiatedWithdrawInfo)); - api::SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::kSuccess}; + api::SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::success}; EXPECT_CALL(ExchangePrivate(exchange1), queryRecentWithdraws(testing::_)) .WillOnce(testing::Return( - WithdrawsSet{Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::kSuccess, fee}})); + WithdrawsSet{Withdraw{withdrawId, withdrawTimestamp, netEmittedAmount, Withdraw::Status::success, fee}})); api::ReceivedWithdrawInfo receivedWithdrawInfo{"deposit-id", netEmittedAmount}; EXPECT_CALL(ExchangePrivate(exchange2), queryWithdrawDelivery(initiatedWithdrawInfo, sentWithdrawInfo)) diff --git a/src/engine/test/exchangesorchestrator_trade_test.cpp b/src/engine/test/exchangesorchestrator_trade_test.cpp index dcfd5000..e080a2b3 100644 --- a/src/engine/test/exchangesorchestrator_trade_test.cpp +++ b/src/engine/test/exchangesorchestrator_trade_test.cpp @@ -150,7 +150,7 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { TradableMarkets tradableMarketsCall, OrderBook orderBookCall, AllOrderBooks allOrderBooksCall, bool makeMarketAvailable) { Market mk(from.currencyCode(), toCurrency); - if (side == TradeSide::kBuy) { + if (side == TradeSide::buy) { mk = mk.reverse(); } @@ -164,8 +164,8 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { MonetaryAmount tradedTo(from, toCurrency); MonetaryAmount deltaPri(1, pri.currencyCode(), volAndPriDec1.priNbDecimals); - MonetaryAmount askPrice = side == TradeSide::kBuy ? pri : pri + deltaPri; - MonetaryAmount bidPrice = side == TradeSide::kSell ? pri : pri - deltaPri; + MonetaryAmount askPrice = side == TradeSide::buy ? pri : pri + deltaPri; + MonetaryAmount bidPrice = side == TradeSide::sell ? pri : pri - deltaPri; MarketOrderBook marketOrderbook{ time, askPrice, maxVol, bidPrice, maxVol, volAndPriDec1, MarketOrderBook::kDefaultDepth}; @@ -218,7 +218,7 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { CurrencyCode interCur("AAA"); Market market1(from.currencyCode(), interCur); Market market2(interCur, toCurrency); - if (side == TradeSide::kBuy) { + if (side == TradeSide::buy) { market1 = Market(toCurrency, interCur); market2 = Market(interCur, from.currencyCode()); } else { @@ -242,10 +242,10 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { MonetaryAmount deltaPri1(1, pri1.currencyCode(), volAndPriDec1.priNbDecimals); MonetaryAmount deltaPri2(1, pri2.currencyCode(), volAndPriDec1.priNbDecimals); - MonetaryAmount askPri1 = side == TradeSide::kBuy ? pri1 : pri1 + deltaPri1; - MonetaryAmount askPri2 = side == TradeSide::kBuy ? pri2 : pri2 + deltaPri2; - MonetaryAmount bidPri1 = side == TradeSide::kSell ? pri1 : pri1 - deltaPri1; - MonetaryAmount bidPri2 = side == TradeSide::kSell ? pri2 : pri2 - deltaPri2; + MonetaryAmount askPri1 = side == TradeSide::buy ? pri1 : pri1 + deltaPri1; + MonetaryAmount askPri2 = side == TradeSide::buy ? pri2 : pri2 + deltaPri2; + MonetaryAmount bidPri1 = side == TradeSide::sell ? pri1 : pri1 - deltaPri1; + MonetaryAmount bidPri2 = side == TradeSide::sell ? pri2 : pri2 - deltaPri2; MarketOrderBook marketOrderbook1{ time, askPri1, maxVol1, bidPri1, maxVol1, volAndPriDec1, MarketOrderBook::kDefaultDepth}; MarketOrderBook marketOrderbook2{ @@ -308,8 +308,8 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { } PriceOptions priceOptions{PriceStrategy::taker}; - TradeOptions tradeOptions{priceOptions, TradeTimeoutAction::kCancel, TradeMode::kReal, Duration::max(), - Duration::zero(), TradeTypePolicy::kDefault}; + TradeOptions tradeOptions{priceOptions, TradeTimeoutAction::cancel, TradeMode::real, + Duration::max(), Duration::zero(), TradeTypePolicy::kDefault}; bool isPercentageTrade = false; MarketOrderBookMap marketOrderBookMap; MarketSet markets; @@ -318,7 +318,7 @@ class ExchangeOrchestratorTradeTest : public ExchangeOrchestratorTest { TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuy) { MonetaryAmount from(100, "EUR"); CurrencyCode toCurrency("XRP"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; TradedAmounts tradedAmounts = expectSingleTrade(1, from, toCurrency, side, TradableMarkets::kExpectCall, OrderBook::kExpectCall, AllOrderBooks::kExpectNoCall, true); @@ -331,7 +331,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuy) { TEST_F(ExchangeOrchestratorTradeTest, NoAvailableAmountToSell) { MonetaryAmount from(10, "SOL"); CurrencyCode toCurrency("EUR"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName())}; @@ -354,7 +354,7 @@ TEST_F(ExchangeOrchestratorTradeTest, NoAvailableAmountToSell) { TEST_F(ExchangeOrchestratorTradeTest, TwoAccountsSameExchangeSell) { MonetaryAmount from(2, "ETH"); CurrencyCode toCurrency("USDT"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; @@ -383,7 +383,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesBuy) { CurrencyCode fromCurrency("USDT"); MonetaryAmount from(13015, fromCurrency); CurrencyCode toCurrency("LUNA"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); @@ -412,7 +412,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesBuyNotEnoughAmount) { CurrencyCode fromCurrency("USDT"); MonetaryAmount from(13015, fromCurrency); CurrencyCode toCurrency("LUNA"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); @@ -444,7 +444,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ManyAccountsTrade) { CurrencyCode fromCurrency("USDT"); MonetaryAmount from(40000, fromCurrency); CurrencyCode toCurrency("LUNA"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); @@ -493,7 +493,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ManyAccountsTrade) { TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuyAll) { CurrencyCode fromCurrency("EUR"); CurrencyCode toCurrency("XRP"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; @@ -513,7 +513,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuyAll) { TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSellAll) { CurrencyCode fromCurrency("ETH"); CurrencyCode toCurrency("EUR"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), @@ -541,7 +541,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSellAll) { TEST_F(ExchangeOrchestratorTradeTest, AllExchangesBuyAllOneMarketUnavailable) { CurrencyCode fromCurrency("USDT"); CurrencyCode toCurrency("DOT"); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), @@ -580,7 +580,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartBuy) { MonetaryAmount endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee( MonetaryAmount(1000, "XRP"), schema::ExchangeTradeFeesConfig::FeeType::Taker); CurrencyCode toCurrency = endAmount.currencyCode(); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(1000, "USDT"); @@ -602,7 +602,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartBuyTwoSteps) { // Two fees applications endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee(endAmount, feeType); CurrencyCode toCurrency = endAmount.currencyCode(); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(1000, "USDT"); @@ -621,7 +621,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartBuy) { MonetaryAmount endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee( MonetaryAmount(10000, "XLM"), schema::ExchangeTradeFeesConfig::FeeType::Taker); CurrencyCode toCurrency = endAmount.currencyCode(); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(5000, "USDT"); MonetaryAmount from31 = MonetaryAmount(4250, "USDT"); @@ -650,7 +650,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartBuyNoMarketOnOneExchange) MonetaryAmount endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee( MonetaryAmount(10000, "XLM"), schema::ExchangeTradeFeesConfig::FeeType::Taker); CurrencyCode toCurrency = endAmount.currencyCode(); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(0, "USDT"); MonetaryAmount from3 = MonetaryAmount(4250, "USDT"); @@ -674,7 +674,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesSmartBuy) { MonetaryAmount endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee( MonetaryAmount(10000, "XLM"), schema::ExchangeTradeFeesConfig::FeeType::Taker); CurrencyCode toCurrency = endAmount.currencyCode(); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(5000, "USDT"); MonetaryAmount from2 = MonetaryAmount(0, "USDT"); @@ -712,7 +712,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SmartBuyAllExchanges) { CurrencyCode toCurrency("XLM"); MonetaryAmount endAmount = exchangePublic1.exchangeConfig().tradeFees.applyFee( MonetaryAmount(18800, toCurrency), schema::ExchangeTradeFeesConfig::FeeType::Taker); - TradeSide side = TradeSide::kBuy; + TradeSide side = TradeSide::buy; MonetaryAmount from1 = MonetaryAmount(5000, "USDT"); MonetaryAmount from2 = MonetaryAmount(6750, "USDT"); @@ -751,7 +751,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SmartBuyAllExchanges) { TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartSell) { MonetaryAmount startAmount = MonetaryAmount(2, "ETH"); CurrencyCode toCurrency("USDT"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from1 = MonetaryAmount("1.5ETH"); @@ -786,7 +786,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSell) { MonetaryAmount startAmount = MonetaryAmount(16, "BTC"); CurrencyCode fromCurrency = startAmount.currencyCode(); CurrencyCode toCurrency("EUR"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from1 = MonetaryAmount(15, fromCurrency); MonetaryAmount from2 = MonetaryAmount("0.5", fromCurrency); @@ -812,7 +812,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellPercentage) { MonetaryAmount startAmount = MonetaryAmount(25, "ETH"); CurrencyCode fromCurrency = startAmount.currencyCode(); CurrencyCode toCurrency("USDT"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from1 = MonetaryAmount("0.525", fromCurrency); MonetaryAmount from3 = MonetaryAmount(0, fromCurrency); @@ -836,7 +836,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellPercentage) { TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellNoMarketOnOneExchange) { MonetaryAmount startAmount = MonetaryAmount(10000, "SHIB"); CurrencyCode toCurrency("USDT"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from2 = startAmount; MonetaryAmount from3 = MonetaryAmount(0, startAmount.currencyCode()); @@ -860,7 +860,7 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellNoMarketOnOneExchange TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesSmartSellFromAnotherPreferredCurrency) { MonetaryAmount startAmount = MonetaryAmount(2000, "EUR"); CurrencyCode toCurrency("USDT"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from1 = MonetaryAmount(0, startAmount.currencyCode()); MonetaryAmount from3 = MonetaryAmount(1500, startAmount.currencyCode()); @@ -890,7 +890,7 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesSmartSellFromAnotherPreferre TEST_F(ExchangeOrchestratorTradeTest, SmartSellAllExchanges) { MonetaryAmount startAmount = MonetaryAmount(1, "ETH"); CurrencyCode toCurrency("EUR"); - TradeSide side = TradeSide::kSell; + TradeSide side = TradeSide::sell; MonetaryAmount from1 = MonetaryAmount(1, startAmount.currencyCode()); MonetaryAmount from2 = MonetaryAmount(0, startAmount.currencyCode()); diff --git a/src/engine/test/queryresultprinter_base_test.hpp b/src/engine/test/queryresultprinter_base_test.hpp index 84739fbd..8359c8c9 100644 --- a/src/engine/test/queryresultprinter_base_test.hpp +++ b/src/engine/test/queryresultprinter_base_test.hpp @@ -8,7 +8,7 @@ #include #include "apioutputtype.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "exchangedata_test.hpp" #include "queryresultprinter.hpp" #include "timedef.hpp" diff --git a/src/engine/test/queryresultprinter_private_test.cpp b/src/engine/test/queryresultprinter_private_test.cpp index e3494ec9..97b152d5 100644 --- a/src/engine/test/queryresultprinter_private_test.cpp +++ b/src/engine/test/queryresultprinter_private_test.cpp @@ -557,9 +557,9 @@ TEST_F(QueryResultPrinterTradesAmountTest, FormattedTable) { +----------+-----------+---------+---------------------------+-------------------------+-----------+ | Exchange | Account | From | Traded from amount (real) | Traded to amount (real) | Status | +----------+-----------+---------+---------------------------+-------------------------+-----------+ -| binance | testuser1 | 0.1 BTC | 0.1 BTC | 1050 XRP | Complete | -| huobi | testuser1 | 0.6 BTC | 0.3 BTC | 3500.6 XRP | Partial | -| huobi | testuser2 | 1 BTC | 0 BTC | 0 XRP | Untouched | +| binance | testuser1 | 0.1 BTC | 0.1 BTC | 1050 XRP | complete | +| huobi | testuser1 | 0.6 BTC | 0.3 BTC | 3500.6 XRP | partial | +| huobi | testuser2 | 1 BTC | 0 BTC | 0 XRP | untouched | +----------+-----------+---------+---------------------------+-------------------------+-----------+ )"; @@ -631,7 +631,7 @@ TEST_F(QueryResultPrinterTradesAmountTest, Json) { "binance": { "testuser1": { "from": "0.1", - "status": "Complete", + "status": "complete", "tradedFrom": "0.1", "tradedTo": "1050" } @@ -639,13 +639,13 @@ TEST_F(QueryResultPrinterTradesAmountTest, Json) { "huobi": { "testuser1": { "from": "0.6", - "status": "Partial", + "status": "partial", "tradedFrom": "0.3", "tradedTo": "3500.6" }, "testuser2": { "from": "1", - "status": "Untouched", + "status": "untouched", "tradedFrom": "0", "tradedTo": "0" } @@ -679,7 +679,7 @@ TEST_F(QueryResultPrinterTradesPercentageTest, FormattedTable) { +----------+-----------+--------------+---------------------------+-------------------------+---------+ | Exchange | Account | From | Traded from amount (real) | Traded to amount (real) | Status | +----------+-----------+--------------+---------------------------+-------------------------+---------+ -| bithumb | testuser1 | 30001.12 EUR | 15000.56 EUR | 885475102 SHIB | Partial | +| bithumb | testuser1 | 30001.12 EUR | 15000.56 EUR | 885475102 SHIB | partial | +----------+-----------+--------------+---------------------------+-------------------------+---------+ )"; expectStr(kExpected); @@ -750,7 +750,7 @@ TEST_F(QueryResultPrinterTradesPercentageTest, Json) { "bithumb": { "testuser1": { "from": "30001.12", - "status": "Partial", + "status": "partial", "tradedFrom": "15000.56", "tradedTo": "885475102" } @@ -779,7 +779,7 @@ TEST_F(QueryResultPrinterSmartBuyTest, FormattedTable) { +----------+-----------+-------------+---------------------------+-------------------------+----------+ | Exchange | Account | From | Traded from amount (real) | Traded to amount (real) | Status | +----------+-----------+-------------+---------------------------+-------------------------+----------+ -| binance | testuser1 | 4500.67 EUR | 4500.67 EUR | 3 ETH | Complete | +| binance | testuser1 | 4500.67 EUR | 4500.67 EUR | 3 ETH | complete | +----------+-----------+-------------+---------------------------+-------------------------+----------+ )"; expectStr(kExpected); @@ -842,7 +842,7 @@ TEST_F(QueryResultPrinterSmartBuyTest, Json) { "binance": { "testuser1": { "from": "4500.67", - "status": "Complete", + "status": "complete", "tradedFrom": "4500.67", "tradedTo": "3" } @@ -876,9 +876,9 @@ TEST_F(QueryResultPrinterSmartSellTest, FormattedTable) { +----------+-----------+----------+---------------------------+-------------------------+----------+ | Exchange | Account | From | Traded from amount (real) | Traded to amount (real) | Status | +----------+-----------+----------+---------------------------+-------------------------+----------+ -| binance | testuser1 | 0.01 BTC | 0.01 BTC | 1500 USDT | Complete | -| huobi | testuser1 | 0.02 BTC | 0.004 BTC | 350 EUR | Partial | -| huobi | testuser2 | 0.3 BTC | 0.1 BTC | 17 ETH | Partial | +| binance | testuser1 | 0.01 BTC | 0.01 BTC | 1500 USDT | complete | +| huobi | testuser1 | 0.02 BTC | 0.004 BTC | 350 EUR | partial | +| huobi | testuser2 | 0.3 BTC | 0.1 BTC | 17 ETH | partial | +----------+-----------+----------+---------------------------+-------------------------+----------+ )"; @@ -944,7 +944,7 @@ TEST_F(QueryResultPrinterSmartSellTest, Json) { "binance": { "testuser1": { "from": "0.01", - "status": "Complete", + "status": "complete", "tradedFrom": "0.01", "tradedTo": "1500" } @@ -952,13 +952,13 @@ TEST_F(QueryResultPrinterSmartSellTest, Json) { "huobi": { "testuser1": { "from": "0.02", - "status": "Partial", + "status": "partial", "tradedFrom": "0.004", "tradedTo": "350" }, "testuser2": { "from": "0.3", - "status": "Partial", + "status": "partial", "tradedFrom": "0.1", "tradedTo": "17" } @@ -976,12 +976,12 @@ TEST_F(QueryResultPrinterSmartSellTest, NoPrint) { class QueryResultPrinterClosedOrdersBaseTest : public QueryResultPrinterTest { protected: - ClosedOrder order1{"id1", MonetaryAmount(0, "BTC"), MonetaryAmount(50000, "EUR"), tp1, tp1, TradeSide::kBuy}; - ClosedOrder order2{"id2", MonetaryAmount("0.56ETH"), MonetaryAmount("1500.56USDT"), tp2, tp3, TradeSide::kSell}; - ClosedOrder order3{"id3", MonetaryAmount(13, "XRP"), MonetaryAmount("1.31USDT"), tp3, tp1, TradeSide::kBuy}; - ClosedOrder order4{"id4", MonetaryAmount("34.56LTC"), MonetaryAmount("1574564KRW"), tp4, tp2, TradeSide::kSell}; - ClosedOrder order5{"id5", MonetaryAmount("11235435.59SHIB"), MonetaryAmount("0.00000045USDT"), tp2, tp4, - TradeSide::kSell}; + ClosedOrder order1{"id1", MonetaryAmount(0, "BTC"), MonetaryAmount(50000, "EUR"), tp1, tp1, TradeSide::buy}; + ClosedOrder order2{"id2", MonetaryAmount("0.56ETH"), MonetaryAmount("1500.56USDT"), tp2, tp3, TradeSide::sell}; + ClosedOrder order3{"id3", MonetaryAmount(13, "XRP"), MonetaryAmount("1.31USDT"), tp3, tp1, TradeSide::buy}; + ClosedOrder order4{"id4", MonetaryAmount("34.56LTC"), MonetaryAmount("1574564KRW"), tp4, tp2, TradeSide::sell}; + ClosedOrder order5{"id5", MonetaryAmount("11235435.59SHIB"), MonetaryAmount("0.00000045USDT"), tp2, tp4, + TradeSide::sell}; }; class QueryResultPrinterClosedOrdersNoConstraintsTest : public QueryResultPrinterClosedOrdersBaseTest { @@ -999,11 +999,11 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, FormattedTable) { +----------+-----------+-------------+----------------------+----------------------+------+-----------------+------------------+ | Exchange | Account | Exchange Id | Placed time | Matched time | Side | Price | Matched Amount | +----------+-----------+-------------+----------------------+----------------------+------+-----------------+------------------+ -| bithumb | testuser1 | id5 | 2002-06-23T07:58:35Z | 2011-10-03T06:49:36Z | Sell | 0.00000045 USDT | 11235435.59 SHIB | -| bithumb | testuser1 | id3 | 2006-07-14T23:58:24Z | 1999-03-25T04:46:43Z | Buy | 1.31 USDT | 13 XRP | -| huobi | testuser2 | id2 | 2002-06-23T07:58:35Z | 2006-07-14T23:58:24Z | Sell | 1500.56 USDT | 0.56 ETH | -| huobi | testuser1 | id1 | 1999-03-25T04:46:43Z | 1999-03-25T04:46:43Z | Buy | 50000 EUR | 0 BTC | -| huobi | testuser1 | id4 | 2011-10-03T06:49:36Z | 2002-06-23T07:58:35Z | Sell | 1574564 KRW | 34.56 LTC | +| bithumb | testuser1 | id5 | 2002-06-23T07:58:35Z | 2011-10-03T06:49:36Z | sell | 0.00000045 USDT | 11235435.59 SHIB | +| bithumb | testuser1 | id3 | 2006-07-14T23:58:24Z | 1999-03-25T04:46:43Z | buy | 1.31 USDT | 13 XRP | +| huobi | testuser2 | id2 | 2002-06-23T07:58:35Z | 2006-07-14T23:58:24Z | sell | 1500.56 USDT | 0.56 ETH | +| huobi | testuser1 | id1 | 1999-03-25T04:46:43Z | 1999-03-25T04:46:43Z | buy | 50000 EUR | 0 BTC | +| huobi | testuser1 | id4 | 2011-10-03T06:49:36Z | 2002-06-23T07:58:35Z | sell | 1574564 KRW | 34.56 LTC | +----------+-----------+-------------+----------------------+----------------------+------+-----------------+------------------+ )"; expectStr(kExpected); @@ -1041,7 +1041,7 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, Json) { "pair": "SHIB-USDT", "placedTime": "2002-06-23T07:58:35Z", "price": "0.00000045", - "side": "Sell" + "side": "sell" }, { "id": "id3", @@ -1050,7 +1050,7 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, Json) { "pair": "XRP-USDT", "placedTime": "2006-07-14T23:58:24Z", "price": "1.31", - "side": "Buy" + "side": "buy" } ] }, @@ -1063,7 +1063,7 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, Json) { "pair": "BTC-EUR", "placedTime": "1999-03-25T04:46:43Z", "price": "50000", - "side": "Buy" + "side": "buy" }, { "id": "id4", @@ -1072,7 +1072,7 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, Json) { "pair": "LTC-KRW", "placedTime": "2011-10-03T06:49:36Z", "price": "1574564", - "side": "Sell" + "side": "sell" } ], "testuser2": [ @@ -1083,7 +1083,7 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, Json) { "pair": "ETH-USDT", "placedTime": "2002-06-23T07:58:35Z", "price": "1500.56", - "side": "Sell" + "side": "sell" } ] } @@ -1099,20 +1099,20 @@ TEST_F(QueryResultPrinterClosedOrdersNoConstraintsTest, NoPrint) { class QueryResultPrinterOpenedOrdersBaseTest : public QueryResultPrinterTest { protected: - OpenedOrder order1{"id1", MonetaryAmount(0, "BTC"), MonetaryAmount(1, "BTC"), MonetaryAmount(50000, "EUR"), - tp1, TradeSide::kBuy}; - OpenedOrder order2{"id2", MonetaryAmount("0.56ETH"), MonetaryAmount("0.44ETH"), MonetaryAmount("1500.56USDT"), - tp2, TradeSide::kSell}; + OpenedOrder order1{ + "id1", MonetaryAmount(0, "BTC"), MonetaryAmount(1, "BTC"), MonetaryAmount(50000, "EUR"), tp1, TradeSide::buy}; + OpenedOrder order2{ + "id2", MonetaryAmount("0.56ETH"), MonetaryAmount("0.44ETH"), MonetaryAmount("1500.56USDT"), tp2, TradeSide::sell}; OpenedOrder order3{ - "id3", MonetaryAmount(13, "XRP"), MonetaryAmount("500.45XRP"), MonetaryAmount("1.31USDT"), tp3, TradeSide::kBuy}; + "id3", MonetaryAmount(13, "XRP"), MonetaryAmount("500.45XRP"), MonetaryAmount("1.31USDT"), tp3, TradeSide::buy}; OpenedOrder order4{ - "id4", MonetaryAmount("34.56LTC"), MonetaryAmount("0.4LTC"), MonetaryAmount("1574564KRW"), tp4, TradeSide::kSell}; + "id4", MonetaryAmount("34.56LTC"), MonetaryAmount("0.4LTC"), MonetaryAmount("1574564KRW"), tp4, TradeSide::sell}; OpenedOrder order5{"id5", MonetaryAmount("11235435435SHIB"), MonetaryAmount("11235435.59SHIB"), MonetaryAmount("0.00000045USDT"), tp2, - TradeSide::kSell}; + TradeSide::sell}; }; class QueryResultPrinterOpenedOrdersNoConstraintsTest : public QueryResultPrinterOpenedOrdersBaseTest { @@ -1130,11 +1130,11 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, FormattedTable) { +----------+-----------+-------------+----------------------+------+-----------------+------------------+------------------+ | Exchange | Account | Exchange Id | Placed time | Side | Price | Matched Amount | Remaining Amount | +----------+-----------+-------------+----------------------+------+-----------------+------------------+------------------+ -| bithumb | testuser1 | id5 | 2002-06-23T07:58:35Z | Sell | 0.00000045 USDT | 11235435435 SHIB | 11235435.59 SHIB | -| bithumb | testuser1 | id3 | 2006-07-14T23:58:24Z | Buy | 1.31 USDT | 13 XRP | 500.45 XRP | -| huobi | testuser2 | id2 | 2002-06-23T07:58:35Z | Sell | 1500.56 USDT | 0.56 ETH | 0.44 ETH | -| huobi | testuser1 | id1 | 1999-03-25T04:46:43Z | Buy | 50000 EUR | 0 BTC | 1 BTC | -| huobi | testuser1 | id4 | 2011-10-03T06:49:36Z | Sell | 1574564 KRW | 34.56 LTC | 0.4 LTC | +| bithumb | testuser1 | id5 | 2002-06-23T07:58:35Z | sell | 0.00000045 USDT | 11235435435 SHIB | 11235435.59 SHIB | +| bithumb | testuser1 | id3 | 2006-07-14T23:58:24Z | buy | 1.31 USDT | 13 XRP | 500.45 XRP | +| huobi | testuser2 | id2 | 2002-06-23T07:58:35Z | sell | 1500.56 USDT | 0.56 ETH | 0.44 ETH | +| huobi | testuser1 | id1 | 1999-03-25T04:46:43Z | buy | 50000 EUR | 0 BTC | 1 BTC | +| huobi | testuser1 | id4 | 2011-10-03T06:49:36Z | sell | 1574564 KRW | 34.56 LTC | 0.4 LTC | +----------+-----------+-------------+----------------------+------+-----------------+------------------+------------------+ )"; expectStr(kExpected); @@ -1172,7 +1172,7 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, Json) { "placedTime": "2002-06-23T07:58:35Z", "price": "0.00000045", "remaining": "11235435.59", - "side": "Sell" + "side": "sell" }, { "id": "id3", @@ -1181,7 +1181,7 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, Json) { "placedTime": "2006-07-14T23:58:24Z", "price": "1.31", "remaining": "500.45", - "side": "Buy" + "side": "buy" } ] }, @@ -1194,7 +1194,7 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, Json) { "placedTime": "1999-03-25T04:46:43Z", "price": "50000", "remaining": "1", - "side": "Buy" + "side": "buy" }, { "id": "id4", @@ -1203,7 +1203,7 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, Json) { "placedTime": "2011-10-03T06:49:36Z", "price": "1574564", "remaining": "0.4", - "side": "Sell" + "side": "sell" } ], "testuser2": [ @@ -1214,7 +1214,7 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, Json) { "placedTime": "2002-06-23T07:58:35Z", "price": "1500.56", "remaining": "0.44", - "side": "Sell" + "side": "sell" } ] } @@ -1230,11 +1230,11 @@ TEST_F(QueryResultPrinterOpenedOrdersNoConstraintsTest, NoPrint) { class QueryResultPrinterRecentDepositsBaseTest : public QueryResultPrinterTest { protected: - Deposit deposit1{"id1", tp1, MonetaryAmount("0.045", "BTC"), Deposit::Status::kInitial}; - Deposit deposit2{"id2", tp2, MonetaryAmount(37, "XRP"), Deposit::Status::kSuccess}; - Deposit deposit3{"id3", tp3, MonetaryAmount("15020.67", "EUR"), Deposit::Status::kFailureOrRejected}; - Deposit deposit4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Deposit::Status::kProcessing}; - Deposit deposit5{"id5", tp4, MonetaryAmount("69204866.9", "DOGE"), Deposit::Status::kSuccess}; + Deposit deposit1{"id1", tp1, MonetaryAmount("0.045", "BTC"), Deposit::Status::initial}; + Deposit deposit2{"id2", tp2, MonetaryAmount(37, "XRP"), Deposit::Status::success}; + Deposit deposit3{"id3", tp3, MonetaryAmount("15020.67", "EUR"), Deposit::Status::failed}; + Deposit deposit4{"id4", tp4, MonetaryAmount("1.31", "ETH"), Deposit::Status::processing}; + Deposit deposit5{"id5", tp4, MonetaryAmount("69204866.9", "DOGE"), Deposit::Status::success}; }; class QueryResultPrinterRecentDepositsNoConstraintsTest : public QueryResultPrinterRecentDepositsBaseTest { @@ -1342,14 +1342,14 @@ TEST_F(QueryResultPrinterRecentDepositsNoConstraintsTest, NoPrint) { class QueryResultPrinterRecentWithdrawsBaseTest : public QueryResultPrinterTest { protected: - Withdraw withdraw1{"id1", tp3, MonetaryAmount("0.045", "BTC"), Withdraw::Status::kInitial, + Withdraw withdraw1{"id1", tp3, MonetaryAmount("0.045", "BTC"), Withdraw::Status::initial, MonetaryAmount("0.00001", "BTC")}; - Withdraw withdraw2{"id2", tp4, MonetaryAmount(37, "XRP"), Withdraw::Status::kSuccess, MonetaryAmount("0.02", "XRP")}; - Withdraw withdraw3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Withdraw::Status::kFailureOrRejected, + Withdraw withdraw2{"id2", tp4, MonetaryAmount(37, "XRP"), Withdraw::Status::success, MonetaryAmount("0.02", "XRP")}; + Withdraw withdraw3{"id3", tp1, MonetaryAmount("15020.67", "EUR"), Withdraw::Status::failed, MonetaryAmount("0.1", "EUR")}; - Withdraw withdraw4{"id4", tp2, MonetaryAmount("1.31", "ETH"), Withdraw::Status::kProcessing, + Withdraw withdraw4{"id4", tp2, MonetaryAmount("1.31", "ETH"), Withdraw::Status::processing, MonetaryAmount("0.001", "ETH")}; - Withdraw withdraw5{"id5", tp2, MonetaryAmount("69204866.9", "DOGE"), Withdraw::Status::kSuccess, + Withdraw withdraw5{"id5", tp2, MonetaryAmount("69204866.9", "DOGE"), Withdraw::Status::success, MonetaryAmount(2, "DOGE")}; }; @@ -1543,7 +1543,7 @@ class QueryResultPrinterWithdrawTest : public QueryResultPrinterTest { Wallet receivingWallet{toExchange, grossAmount.currencyCode(), "xrpaddress666", "xrptag2", WalletCheck{}, AccountOwner("SmithJohn", "스미스존")}; MonetaryAmount grossEmittedAmount; - api::SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::kSuccess}; + api::SentWithdrawInfo sentWithdrawInfo{netEmittedAmount, fee, Withdraw::Status::success}; DeliveredWithdrawInfoWithExchanges deliveredWithdrawInfoWithExchanges{ {&exchange1, &exchange4}, diff --git a/src/engine/test/queryresultprinter_public_test.cpp b/src/engine/test/queryresultprinter_public_test.cpp index 2b488445..6a7043dc 100644 --- a/src/engine/test/queryresultprinter_public_test.cpp +++ b/src/engine/test/queryresultprinter_public_test.cpp @@ -139,7 +139,6 @@ TEST_F(QueryResultPrinterCurrenciesTest, EmptyJson) { static constexpr std::string_view kExpected = R"( { "in": { - "opt": null, "req": "Currencies" }, "out": {} @@ -153,7 +152,6 @@ TEST_F(QueryResultPrinterCurrenciesTest, Json) { static constexpr std::string_view kExpected = R"( { "in": { - "opt": null, "req": "Currencies" }, "out": { @@ -655,8 +653,9 @@ TEST_F(QueryResultPrinterConversionSingleAmountTest, EmptyJson) { { "in": { "opt": { - "amount": "345.25 SOL", - "targetCurrency": "KRW" + "fromAmount": "345.25", + "fromCurrency": "SOL", + "toCurrency": "KRW" }, "req": "Conversion" }, @@ -672,20 +671,21 @@ TEST_F(QueryResultPrinterConversionSingleAmountTest, Json) { { "in": { "opt": { - "amount": "345.25 SOL", - "targetCurrency": "KRW" + "fromAmount": "345.25", + "fromCurrency": "SOL", + "toCurrency": "KRW" }, "req": "Conversion" }, "out": { "binance": { - "convertedAmount": "41786641 KRW" + "convertedAmount": "41786641" }, "bithumb": { - "convertedAmount": "59000249 KRW" + "convertedAmount": "59000249" }, "huobi": { - "convertedAmount": "44487640 KRW" + "convertedAmount": "44487640" } } })"; @@ -736,12 +736,21 @@ TEST_F(QueryResultPrinterConversionSeveralAmountTest, EmptyJson) { { "in": { "opt": { - "sourceAmount": { - "binance": "1 BTC", - "bithumb": "1.4 BTC", - "huobi": "1.1 BTC" + "fromAmount": { + "binance": { + "amount": "1", + "cur": "BTC" + }, + "bithumb": { + "amount": "1.4", + "cur": "BTC" + }, + "huobi": { + "amount": "1.1", + "cur": "BTC" + } }, - "targetCurrency": "KRW" + "toCurrency": "KRW" }, "req": "Conversion" }, @@ -757,24 +766,33 @@ TEST_F(QueryResultPrinterConversionSeveralAmountTest, Json) { { "in": { "opt": { - "sourceAmount": { - "binance": "1 BTC", - "bithumb": "1.4 BTC", - "huobi": "1.1 BTC" + "fromAmount": { + "binance": { + "amount": "1", + "cur": "BTC" + }, + "bithumb": { + "amount": "1.4", + "cur": "BTC" + }, + "huobi": { + "amount": "1.1", + "cur": "BTC" + } }, - "targetCurrency": "KRW" + "toCurrency": "KRW" }, "req": "Conversion" }, "out": { "binance": { - "convertedAmount": "41786641 KRW" + "convertedAmount": "41786641" }, "bithumb": { - "convertedAmount": "59000249 KRW" + "convertedAmount": "59000249" }, "huobi": { - "convertedAmount": "44487640 KRW" + "convertedAmount": "44487640" } } })"; @@ -983,18 +1001,18 @@ class QueryResultPrinterLastTradesVolumeTest : public QueryResultPrinterTest { TradesPerExchange lastTradesPerExchange{ {&exchange1, PublicTradeVector{ - PublicTrade(TradeSide::kBuy, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp1), - PublicTrade(TradeSide::kSell, MonetaryAmount{"3.7", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp2), - PublicTrade(TradeSide::kBuy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp3)}}, + PublicTrade(TradeSide::buy, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp1), + PublicTrade(TradeSide::sell, MonetaryAmount{"3.7", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp2), + PublicTrade(TradeSide::buy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp3)}}, {&exchange3, PublicTradeVector{ - PublicTrade(TradeSide::kSell, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp4), - PublicTrade(TradeSide::kBuy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp2)}}, + PublicTrade(TradeSide::sell, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp4), + PublicTrade(TradeSide::buy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp2)}}, {&exchange2, PublicTradeVector{ - PublicTrade(TradeSide::kSell, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp4), - PublicTrade(TradeSide::kBuy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp2), - PublicTrade(TradeSide::kBuy, MonetaryAmount{"47.78", "ETH"}, MonetaryAmount{1498, "USDT"}, tp1)}}}; + PublicTrade(TradeSide::sell, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp4), + PublicTrade(TradeSide::buy, MonetaryAmount{"0.004", "ETH"}, MonetaryAmount{1501, "USDT"}, tp2), + PublicTrade(TradeSide::buy, MonetaryAmount{"47.78", "ETH"}, MonetaryAmount{1498, "USDT"}, tp1)}}}; }; TEST_F(QueryResultPrinterLastTradesVolumeTest, FormattedTable) { @@ -1062,19 +1080,19 @@ TEST_F(QueryResultPrinterLastTradesVolumeTest, Json) { { "a": "0.13", "p": "1500.5", - "side": "Buy", + "side": "buy", "time": "1999-03-25T04:46:43Z" }, { "a": "3.7", "p": "1500.5", - "side": "Sell", + "side": "sell", "time": "2002-06-23T07:58:35Z" }, { "a": "0.004", "p": "1501", - "side": "Buy", + "side": "buy", "time": "2006-07-14T23:58:24Z" } ], @@ -1082,19 +1100,19 @@ TEST_F(QueryResultPrinterLastTradesVolumeTest, Json) { { "a": "0.13", "p": "1500.5", - "side": "Sell", + "side": "sell", "time": "2011-10-03T06:49:36Z" }, { "a": "0.004", "p": "1501", - "side": "Buy", + "side": "buy", "time": "2002-06-23T07:58:35Z" }, { "a": "47.78", "p": "1498", - "side": "Buy", + "side": "buy", "time": "1999-03-25T04:46:43Z" } ], @@ -1102,13 +1120,13 @@ TEST_F(QueryResultPrinterLastTradesVolumeTest, Json) { { "a": "0.13", "p": "1500.5", - "side": "Sell", + "side": "sell", "time": "2011-10-03T06:49:36Z" }, { "a": "0.004", "p": "1501", - "side": "Buy", + "side": "buy", "time": "2002-06-23T07:58:35Z" } ] @@ -1243,7 +1261,7 @@ TEST_F(QueryResultPrinterReplayMarketsTest, EmptyJson) { { "in": { "opt": { - "timeWindow": "[1999-03-25 04:46:43 -> 2000-10-07 01:14:27)" + "timeWindow": "[1999-03-25T04:46:43Z -> 2000-10-07T01:14:27Z)" }, "req": "ReplayMarkets" }, @@ -1258,7 +1276,7 @@ TEST_F(QueryResultPrinterReplayMarketsTest, Json) { { "in": { "opt": { - "timeWindow": "[1999-03-25 04:46:43 -> 2000-10-07 01:14:27)" + "timeWindow": "[1999-03-25T04:46:43Z -> 2000-10-07T01:14:27Z)" }, "req": "ReplayMarkets" }, @@ -1308,7 +1326,7 @@ TEST_F(QueryResultPrinterReplayMarketsTest, Json) { ] }, "huobi": { - "orderBooks": null, + "orderBooks": [], "trades": [ { "lastTimestamp": "2000-06-11T23:58:40Z", @@ -1334,11 +1352,11 @@ class QueryResultPrinterReplayTest : public QueryResultPrinterReplayBaseTest { protected: CurrencyCode base{"BTC"}; CurrencyCode quote{"USDT"}; - ClosedOrder closedOrder1{"1", MonetaryAmount(15, base, 1), MonetaryAmount(35000, quote), tp1, tp1, TradeSide::kBuy}; - ClosedOrder closedOrder2{"2", MonetaryAmount(25, base, 1), MonetaryAmount(45000, quote), tp2, tp2, TradeSide::kBuy}; - ClosedOrder closedOrder3{"3", MonetaryAmount(5, base, 2), MonetaryAmount(35000, quote), tp3, tp4, TradeSide::kSell}; - ClosedOrder closedOrder4{"4", MonetaryAmount(17, base, 1), MonetaryAmount(50000, quote), tp3, tp4, TradeSide::kSell}; - ClosedOrder closedOrder5{"5", MonetaryAmount(36, base, 3), MonetaryAmount(47899, quote), tp4, tp5, TradeSide::kSell}; + ClosedOrder closedOrder1{"1", MonetaryAmount(15, base, 1), MonetaryAmount(35000, quote), tp1, tp1, TradeSide::buy}; + ClosedOrder closedOrder2{"2", MonetaryAmount(25, base, 1), MonetaryAmount(45000, quote), tp2, tp2, TradeSide::buy}; + ClosedOrder closedOrder3{"3", MonetaryAmount(5, base, 2), MonetaryAmount(35000, quote), tp3, tp4, TradeSide::sell}; + ClosedOrder closedOrder4{"4", MonetaryAmount(17, base, 1), MonetaryAmount(50000, quote), tp3, tp4, TradeSide::sell}; + ClosedOrder closedOrder5{"5", MonetaryAmount(36, base, 3), MonetaryAmount(47899, quote), tp4, tp5, TradeSide::sell}; MonetaryAmount startBaseAmount{1, base}; MonetaryAmount startQuoteAmount{1000, quote}; @@ -1387,25 +1405,25 @@ TEST_F(QueryResultPrinterReplayTest, FormattedTable) { | first-alg | binance | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 0 USDT | | order books: 42 OK | | | | 1999-03-25T04:46:43Z | | 1000 USDT | | | trades: 3 OK, 10 KO | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| -| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 500 USDT | 1999-03-25T04:46:43Z - Buy - 1.5 BTC @ 35000 USDT | order books: 500000 OK, 2 KO | -| | | 1999-07-11T00:42:21Z | | 1000 USDT | | 2000-06-11T23:58:40Z - Sell - 0.036 BTC @ 47899 USDT | trades: 0 OK | +| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 500 USDT | 1999-03-25T04:46:43Z - buy - 1.5 BTC @ 35000 USDT | order books: 500000 OK, 2 KO | +| | | 1999-07-11T00:42:21Z | | 1000 USDT | | 2000-06-11T23:58:40Z - sell - 0.036 BTC @ 47899 USDT | trades: 0 OK | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| -| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 780 USDT | 1999-07-11T00:42:21Z - Buy - 2.5 BTC @ 45000 USDT | order books: 79009 OK | -| | | 1999-10-29T01:26:51Z | | 1000 USDT | | 1999-10-29T01:26:51Z - Sell - 0.05 BTC @ 35000 USDT | trades: 1555555555 OK, 45 KO | -| | | | | | | 1999-10-29T01:26:51Z - Sell - 1.7 BTC @ 50000 USDT | | +| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 780 USDT | 1999-07-11T00:42:21Z - buy - 2.5 BTC @ 45000 USDT | order books: 79009 OK | +| | | 1999-10-29T01:26:51Z | | 1000 USDT | | 1999-10-29T01:26:51Z - sell - 0.05 BTC @ 35000 USDT | trades: 1555555555 OK, 45 KO | +| | | | | | | 1999-10-29T01:26:51Z - sell - 1.7 BTC @ 50000 USDT | | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| | first-alg | binance | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 0 USDT | | order books: 42 OK | | | | 1999-03-25T04:46:43Z | | 1000 USDT | | | trades: 3 OK, 10 KO | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| -| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 500 USDT | 1999-03-25T04:46:43Z - Buy - 1.5 BTC @ 35000 USDT | order books: 500000 OK, 2 KO | -| | | 1999-07-11T00:42:21Z | | 1000 USDT | | 2000-06-11T23:58:40Z - Sell - 0.036 BTC @ 47899 USDT | trades: 0 OK | +| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 500 USDT | 1999-03-25T04:46:43Z - buy - 1.5 BTC @ 35000 USDT | order books: 500000 OK, 2 KO | +| | | 1999-07-11T00:42:21Z | | 1000 USDT | | 2000-06-11T23:58:40Z - sell - 0.036 BTC @ 47899 USDT | trades: 0 OK | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| -| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 780 USDT | 1999-07-11T00:42:21Z - Buy - 2.5 BTC @ 45000 USDT | order books: 79009 OK | -| | | 1999-10-29T01:26:51Z | | 1000 USDT | | 1999-10-29T01:26:51Z - Sell - 0.05 BTC @ 35000 USDT | trades: 1555555555 OK, 45 KO | -| | | | | | | 1999-10-29T01:26:51Z - Sell - 1.7 BTC @ 50000 USDT | | +| second-alg | huobi | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | 780 USDT | 1999-07-11T00:42:21Z - buy - 2.5 BTC @ 45000 USDT | order books: 79009 OK | +| | | 1999-10-29T01:26:51Z | | 1000 USDT | | 1999-10-29T01:26:51Z - sell - 0.05 BTC @ 35000 USDT | trades: 1555555555 OK, 45 KO | +| | | | | | | 1999-10-29T01:26:51Z - sell - 1.7 BTC @ 50000 USDT | | |~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| -| first-alg | bithumb | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | -334 USDT | 1999-03-25T04:46:43Z - Buy - 1.5 BTC @ 35000 USDT | order books: 23 OK, 1 KO | -| | | 1999-03-25T04:46:43Z | | 1000 USDT | | 1999-10-29T01:26:51Z - Sell - 0.05 BTC @ 35000 USDT | trades: 0 OK, 10 KO | +| first-alg | bithumb | 1999-03-25T04:46:43Z | BTC-USDT | 1 BTC | -334 USDT | 1999-03-25T04:46:43Z - buy - 1.5 BTC @ 35000 USDT | order books: 23 OK, 1 KO | +| | | 1999-03-25T04:46:43Z | | 1000 USDT | | 1999-10-29T01:26:51Z - sell - 0.05 BTC @ 35000 USDT | trades: 0 OK, 10 KO | +------------+----------+----------------------+----------+---------------+---------------+------------------------------------------------------+------------------------------+ )"; expectStr(kExpected); @@ -1450,24 +1468,24 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "binance": { "algorithm": "first-alg", "market": "BTC-USDT", - "matched-orders": [], - "profit-and-loss": "0 USDT", - "start-amounts": { + "matchedOrders": [], + "profitAndLoss": "0 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 0, - "nb-successful": 42, + "orderBooks": { + "nbError": 0, + "nbSuccessful": 42, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-03-25T04:46:43Z" } }, "trades": { - "nb-error": 10, - "nb-successful": 3, + "nbError": 10, + "nbSuccessful": 3, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-07-11T00:42:21Z" @@ -1480,7 +1498,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "huobi": { "algorithm": "second-alg", "market": "BTC-USDT", - "matched-orders": [ + "matchedOrders": [ { "id": "1", "matched": "1.5", @@ -1488,7 +1506,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-03-25T04:46:43Z", "price": "35000", - "side": "Buy" + "side": "buy" }, { "id": "5", @@ -1497,26 +1515,26 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "2000-06-11T23:58:40Z", "price": "47899", - "side": "Sell" + "side": "sell" } ], - "profit-and-loss": "500 USDT", - "start-amounts": { + "profitAndLoss": "500 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 2, - "nb-successful": 500000, + "orderBooks": { + "nbError": 2, + "nbSuccessful": 500000, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-07-11T00:42:21Z" } }, "trades": { - "nb-error": 0, - "nb-successful": 0, + "nbError": 0, + "nbSuccessful": 0, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-10-29T01:26:51Z" @@ -1529,7 +1547,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "huobi": { "algorithm": "second-alg", "market": "BTC-USDT", - "matched-orders": [ + "matchedOrders": [ { "id": "2", "matched": "2.5", @@ -1537,7 +1555,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-07-11T00:42:21Z", "price": "45000", - "side": "Buy" + "side": "buy" }, { "id": "3", @@ -1546,7 +1564,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-10-29T01:26:51Z", "price": "35000", - "side": "Sell" + "side": "sell" }, { "id": "4", @@ -1555,26 +1573,26 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-10-29T01:26:51Z", "price": "50000", - "side": "Sell" + "side": "sell" } ], - "profit-and-loss": "780 USDT", - "start-amounts": { + "profitAndLoss": "780 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 0, - "nb-successful": 79009, + "orderBooks": { + "nbError": 0, + "nbSuccessful": 79009, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-10-29T01:26:51Z" } }, "trades": { - "nb-error": 45, - "nb-successful": 1555555555, + "nbError": 45, + "nbSuccessful": 1555555555, "time": { "from": "1999-07-11T00:42:21Z", "to": "2000-06-11T23:58:40Z" @@ -1591,24 +1609,24 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "binance": { "algorithm": "first-alg", "market": "BTC-USDT", - "matched-orders": [], - "profit-and-loss": "0 USDT", - "start-amounts": { + "matchedOrders": [], + "profitAndLoss": "0 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 0, - "nb-successful": 42, + "orderBooks": { + "nbError": 0, + "nbSuccessful": 42, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-03-25T04:46:43Z" } }, "trades": { - "nb-error": 10, - "nb-successful": 3, + "nbError": 10, + "nbSuccessful": 3, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-07-11T00:42:21Z" @@ -1621,7 +1639,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "huobi": { "algorithm": "second-alg", "market": "BTC-USDT", - "matched-orders": [ + "matchedOrders": [ { "id": "1", "matched": "1.5", @@ -1629,7 +1647,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-03-25T04:46:43Z", "price": "35000", - "side": "Buy" + "side": "buy" }, { "id": "5", @@ -1638,26 +1656,26 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "2000-06-11T23:58:40Z", "price": "47899", - "side": "Sell" + "side": "sell" } ], - "profit-and-loss": "500 USDT", - "start-amounts": { + "profitAndLoss": "500 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 2, - "nb-successful": 500000, + "orderBooks": { + "nbError": 2, + "nbSuccessful": 500000, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-07-11T00:42:21Z" } }, "trades": { - "nb-error": 0, - "nb-successful": 0, + "nbError": 0, + "nbSuccessful": 0, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-10-29T01:26:51Z" @@ -1670,7 +1688,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "huobi": { "algorithm": "second-alg", "market": "BTC-USDT", - "matched-orders": [ + "matchedOrders": [ { "id": "2", "matched": "2.5", @@ -1678,7 +1696,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-07-11T00:42:21Z", "price": "45000", - "side": "Buy" + "side": "buy" }, { "id": "3", @@ -1687,7 +1705,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-10-29T01:26:51Z", "price": "35000", - "side": "Sell" + "side": "sell" }, { "id": "4", @@ -1696,26 +1714,26 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-10-29T01:26:51Z", "price": "50000", - "side": "Sell" + "side": "sell" } ], - "profit-and-loss": "780 USDT", - "start-amounts": { + "profitAndLoss": "780 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 0, - "nb-successful": 79009, + "orderBooks": { + "nbError": 0, + "nbSuccessful": 79009, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-10-29T01:26:51Z" } }, "trades": { - "nb-error": 45, - "nb-successful": 1555555555, + "nbError": 45, + "nbSuccessful": 1555555555, "time": { "from": "1999-07-11T00:42:21Z", "to": "2000-06-11T23:58:40Z" @@ -1730,7 +1748,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "bithumb": { "algorithm": "first-alg", "market": "BTC-USDT", - "matched-orders": [ + "matchedOrders": [ { "id": "1", "matched": "1.5", @@ -1738,7 +1756,7 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-03-25T04:46:43Z", "price": "35000", - "side": "Buy" + "side": "buy" }, { "id": "3", @@ -1747,26 +1765,26 @@ TEST_F(QueryResultPrinterReplayTest, Json) { "pair": "BTC-USDT", "placedTime": "1999-10-29T01:26:51Z", "price": "35000", - "side": "Sell" + "side": "sell" } ], - "profit-and-loss": "-334 USDT", - "start-amounts": { + "profitAndLoss": "-334 USDT", + "startAmounts": { "base": "1 BTC", "quote": "1000 USDT" }, "stats": { - "order-books": { - "nb-error": 1, - "nb-successful": 23, + "orderBooks": { + "nbError": 1, + "nbSuccessful": 23, "time": { "from": "1999-03-25T04:46:43Z", "to": "1999-03-25T04:46:43Z" } }, "trades": { - "nb-error": 10, - "nb-successful": 0, + "nbError": 10, + "nbSuccessful": 0, "time": { "from": "1999-03-25T04:46:43Z", "to": "2000-10-07T01:14:27Z" diff --git a/src/http-request/include/request-retry.hpp b/src/http-request/include/request-retry.hpp index fc09d80c..971c440d 100644 --- a/src/http-request/include/request-retry.hpp +++ b/src/http-request/include/request-retry.hpp @@ -5,7 +5,7 @@ #include #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_type_traits.hpp" #include "curlhandle.hpp" diff --git a/src/objects/include/time-window.hpp b/src/objects/include/time-window.hpp index d524a4ea..437a5025 100644 --- a/src/objects/include/time-window.hpp +++ b/src/objects/include/time-window.hpp @@ -2,10 +2,15 @@ #include #include +#include #include "cct_format.hpp" #include "cct_invalid_argument_exception.hpp" +#include "cct_json.hpp" +#include "cct_string.hpp" +#include "generic-object-json.hpp" #include "timedef.hpp" +#include "timestring.hpp" namespace cct { @@ -13,6 +18,8 @@ namespace cct { /// The beginning time includes the corresponding time point, but the end time excludes it. class TimeWindow { public: + static constexpr auto kTimeFormat = kTimeYearToSecondTSeparatedFormatUTC; + /// Create a zero duration time window starting from the zero-initialized time point. TimeWindow() noexcept = default; @@ -26,6 +33,9 @@ class TimeWindow { /// Create a time window starting at 'from' with 'dur' duration. TimeWindow(TimePoint from, Duration dur) : TimeWindow(from, from + dur) {} + /// Create a time window from a string representation. + explicit TimeWindow(std::string_view timeWindowStr); + TimePoint from() const { return _from; } TimePoint to() const { return _to; } @@ -45,13 +55,30 @@ class TimeWindow { TimeWindow operator+(Duration dur) const { return TimeWindow(_from + dur, _to + dur); } - TimeWindow& operator+=(Duration dur) { return *this = *this + dur; } + TimeWindow &operator+=(Duration dur) { return *this = *this + dur; } string str() const; - bool operator==(const TimeWindow&) const noexcept = default; + char *appendTo(char *buf) const; + + static constexpr size_t strLen() { return kTimeWindowLen; } + + bool operator==(const TimeWindow &) const noexcept = default; private: + static constexpr std::string_view kArrow = " -> "; + static constexpr size_t kYNbChars = 4; + static constexpr size_t kMonthNbChars = 2; + static constexpr size_t kDayNbChars = 2; + static constexpr size_t kHourNbChars = 2; + static constexpr size_t kMinuteNbChars = 2; + static constexpr size_t kSecondNbChars = 2; + + static constexpr size_t kTimeNbChars = kYNbChars + 1U + kMonthNbChars + 1U + kDayNbChars + 1U + kHourNbChars + 1U + + kMinuteNbChars + 1U + kSecondNbChars + 1U; + + static constexpr size_t kTimeWindowLen = 2U + 2U * kTimeNbChars + kArrow.size(); + TimePoint _from; TimePoint _to; }; @@ -60,7 +87,7 @@ class TimeWindow { #ifndef CCT_DISABLE_SPDLOG template <> struct fmt::formatter { - constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { const auto it = ctx.begin(); const auto end = ctx.end(); if (it != end && *it != '}') { @@ -70,8 +97,29 @@ struct fmt::formatter { } template - auto format(const cct::TimeWindow& timeWindow, FormatContext& ctx) const -> decltype(ctx.out()) { + auto format(const cct::TimeWindow &timeWindow, FormatContext &ctx) const -> decltype(ctx.out()) { return fmt::format_to(ctx.out(), "{}", timeWindow.str()); } }; #endif + +namespace glz::detail { +template <> +struct from { + template + static void op(auto &&value, is_context auto &&, It &&it, End &&end) noexcept { + // used as a value. As a key, the first quote will not be present. + auto endIt = std::find(*it == '"' ? ++it : it, end, '"'); + value = ::cct::TimeWindow(std::string_view(it, endIt)); + it = ++endIt; + } +}; + +template <> +struct to { + template + static void op(auto &&value, Ctx &&, B &&b, IX &&ix) { + ::cct::details::ToStrLikeJson(value, b, ix); + } +}; +} // namespace glz::detail diff --git a/src/objects/include/tradedefinitions.hpp b/src/objects/include/tradedefinitions.hpp index c944f426..bd0027b4 100644 --- a/src/objects/include/tradedefinitions.hpp +++ b/src/objects/include/tradedefinitions.hpp @@ -2,16 +2,18 @@ #include +#include "cct_json.hpp" + namespace cct { enum class TradeTimeoutAction : int8_t { - kDefault, // Use exchange config file default settings - kCancel, // When timeout of trade is reached, cancel remaining order - kMatch // When timeout of trade is reached, update remaining order at market price to force match + exchange_default, // Use exchange config file default settings + cancel, // When timeout of trade is reached, cancel remaining order + match // When timeout of trade is reached, update remaining order at market price to force match }; enum class TradeMode : int8_t { - kSimulation, // No real trade will be made. Useful for tests. - kReal // Real trade that will be executed in the exchange + simulation, // No real trade will be made. Useful for tests. + real // Real trade that will be executed in the exchange }; /// Determines the default trade type if no override is present in the command. @@ -29,9 +31,30 @@ enum class TradeTypePolicy : int8_t { }; enum class TradeSyncPolicy : int8_t { - kSynchronous, // Follow lifetime of the placed order, manage the price updates until it is either matched or - // cancelled. - kAsynchronous // Placed order will not be followed-up - trade will exits once placed. + synchronous, // Follow lifetime of the placed order, manage the price updates until it is either matched or + // cancelled. + asynchronous // Placed order will not be followed-up - trade will exits once placed. +}; + +} // namespace cct + +template <> +struct glz::meta { + using enum cct::TradeMode; + + static constexpr auto value = enumerate(simulation, real); }; -} // namespace cct \ No newline at end of file +template <> +struct glz::meta { + using enum cct::TradeSyncPolicy; + + static constexpr auto value = enumerate(synchronous, asynchronous); +}; + +template <> +struct glz::meta { + using enum cct::TradeTimeoutAction; + + static constexpr auto value = enumerate(exchange_default, cancel, match); +}; \ No newline at end of file diff --git a/src/objects/include/tradeside.hpp b/src/objects/include/tradeside.hpp index d9863879..df7478d9 100644 --- a/src/objects/include/tradeside.hpp +++ b/src/objects/include/tradeside.hpp @@ -3,19 +3,16 @@ #include #include +#include "cct_json.hpp" #include "unreachable.hpp" namespace cct { -enum class TradeSide : int8_t { kBuy, kSell }; +enum class TradeSide : int8_t { buy, sell }; +} // namespace cct -inline std::string_view SideStr(TradeSide side) { - switch (side) { - case TradeSide::kBuy: - return "Buy"; - case TradeSide::kSell: - return "Sell"; - default: - unreachable(); - } -} -} // namespace cct \ No newline at end of file +template <> +struct glz::meta { + using enum cct::TradeSide; + + static constexpr auto value = enumerate(buy, sell); +}; \ No newline at end of file diff --git a/src/objects/src/marketorderbook.cpp b/src/objects/src/marketorderbook.cpp index 2bc1d661..094fe0b4 100644 --- a/src/objects/src/marketorderbook.cpp +++ b/src/objects/src/marketorderbook.cpp @@ -493,7 +493,7 @@ MarketOrderBook::AmountPerPriceVec MarketOrderBook::computeMatchedParts(TradeSid } }; switch (tradeSide) { - case TradeSide::kBuy: + case TradeSide::buy: for (int pos = _highestBidPricePos + 1; pos < nbOrders && integralTotalAmount > 0; ++pos) { // amount is < 0 here const auto linePrice = priceAt(pos); @@ -503,7 +503,7 @@ MarketOrderBook::AmountPerPriceVec MarketOrderBook::computeMatchedParts(TradeSid countAmount(linePrice, -_orders[pos].amount); } break; - case TradeSide::kSell: + case TradeSide::sell: for (int pos = _lowestAskPricePos - 1; pos >= 0 && integralTotalAmount > 0; --pos) { const auto linePrice = priceAt(pos); if (price > linePrice) { @@ -521,9 +521,9 @@ MarketOrderBook::AmountPerPriceVec MarketOrderBook::computeMatchedParts(TradeSid AmountPrice MarketOrderBook::avgPriceAndMatchedVolume(TradeSide tradeSide, MonetaryAmount amount, MonetaryAmount price) const { switch (tradeSide) { - case TradeSide::kBuy: + case TradeSide::buy: return avgPriceAndMatchedVolumeBuy(amount, price); - case TradeSide::kSell: + case TradeSide::sell: return avgPriceAndMatchedVolumeSell(amount, price); default: throw exception("Unexpected trade side {}", static_cast(tradeSide)); diff --git a/src/objects/src/publictrade.cpp b/src/objects/src/publictrade.cpp index 5836868d..e05aec1b 100644 --- a/src/objects/src/publictrade.cpp +++ b/src/objects/src/publictrade.cpp @@ -27,7 +27,7 @@ bool PublicTrade::isValid() const { log::error("Public trade has an invalid market {}", market()); return false; } - if (side() != TradeSide::kBuy && side() != TradeSide::kSell) { + if (side() != TradeSide::buy && side() != TradeSide::sell) { log::error("Public trade has an invalid trade side {}", static_cast(side())); return false; } diff --git a/src/objects/src/time-window.cpp b/src/objects/src/time-window.cpp index 62af8bb9..319622d6 100644 --- a/src/objects/src/time-window.cpp +++ b/src/objects/src/time-window.cpp @@ -2,12 +2,32 @@ #include +#include "cct_invalid_argument_exception.hpp" #include "cct_string.hpp" #include "timedef.hpp" #include "timestring.hpp" namespace cct { +TimeWindow::TimeWindow(std::string_view timeWindowStr) { + auto openingBracketPos = timeWindowStr.find('['); + if (openingBracketPos == std::string_view::npos) { + throw invalid_argument("Invalid time window - missing opening bracket"); + } + auto arrowPos = timeWindowStr.find(kArrow, openingBracketPos); + if (arrowPos == std::string_view::npos) { + throw invalid_argument("Invalid time window - missing arrow"); + } + auto closingBracketPos = timeWindowStr.find(')', arrowPos); + if (closingBracketPos == std::string_view::npos) { + throw invalid_argument("Invalid time window - missing closing bracket"); + } + + _from = StringToTime(timeWindowStr.substr(openingBracketPos + 1, arrowPos - openingBracketPos - 1), kTimeFormat); + _to = StringToTime(timeWindowStr.substr(arrowPos + kArrow.size(), closingBracketPos - arrowPos - kArrow.size()), + kTimeFormat); +} + TimeWindow TimeWindow::aggregateMinMax(TimeWindow rhs) const { TimeWindow ret{_from, std::max(_to, rhs._to)}; if (_from == TimePoint{}) { @@ -20,13 +40,18 @@ TimeWindow TimeWindow::aggregateMinMax(TimeWindow rhs) const { } string TimeWindow::str() const { - string ret; - ret.push_back('['); - ret.append(TimeToString(from(), kTimeYearToSecondSpaceSeparatedFormat)); - ret.append(" -> "); - ret.append(TimeToString(to(), kTimeYearToSecondSpaceSeparatedFormat)); - ret.push_back(')'); + string ret(kTimeWindowLen, '\0'); + appendTo(ret.data()); return ret; } +char *TimeWindow::appendTo(char *buf) const { + *buf++ = '['; + buf = std::ranges::copy(TimeToString(from(), kTimeFormat), buf).out; + buf = std::ranges::copy(kArrow, buf).out; + buf = std::ranges::copy(TimeToString(to(), kTimeFormat), buf).out; + *buf++ = ')'; + return buf; +} + } // namespace cct \ No newline at end of file diff --git a/src/objects/test/marketorderbook_test.cpp b/src/objects/test/marketorderbook_test.cpp index 5007fbc3..f925ade8 100644 --- a/src/objects/test/marketorderbook_test.cpp +++ b/src/objects/test/marketorderbook_test.cpp @@ -261,23 +261,22 @@ TEST_F(MarketOrderBookTestCase2, ConvertQuoteAmountToBase) { TEST_F(MarketOrderBookTestCase2, ComputeMatchedPartsBuy) { EXPECT_EQ( - marketOrderBook.computeMatchedParts(TradeSide::kBuy, MonetaryAmount(91000, "APM"), - MonetaryAmount("57.81", "KRW")), + marketOrderBook.computeMatchedParts(TradeSide::buy, MonetaryAmount(91000, "APM"), MonetaryAmount("57.81", "KRW")), AmountAtPriceVec({AmountPrice(MonetaryAmount("33.5081914157147", "APM"), MonetaryAmount("57.78", "KRW")), AmountPrice(MonetaryAmount("1991.3922", "APM"), MonetaryAmount("57.8", "KRW")), AmountPrice(MonetaryAmount("88975.0996085842853", "APM"), MonetaryAmount("57.81", "KRW"))})); - EXPECT_EQ(marketOrderBook.computeMatchedParts(TradeSide::kBuy, MonetaryAmount(91000, "APM"), - MonetaryAmount("57.77", "KRW")), - AmountAtPriceVec()); + EXPECT_EQ( + marketOrderBook.computeMatchedParts(TradeSide::buy, MonetaryAmount(91000, "APM"), MonetaryAmount("57.77", "KRW")), + AmountAtPriceVec()); } TEST_F(MarketOrderBookTestCase2, ComputeMatchedPartsSell) { - EXPECT_EQ(marketOrderBook.computeMatchedParts(TradeSide::kSell, MonetaryAmount(5000, "APM"), - MonetaryAmount("57.19", "KRW")), - AmountAtPriceVec({ - AmountPrice(MonetaryAmount("3890.879", "APM"), MonetaryAmount("57.19", "KRW")), - })); - EXPECT_EQ(marketOrderBook.computeMatchedParts(TradeSide::kSell, MonetaryAmount(91000, "APM"), + EXPECT_EQ( + marketOrderBook.computeMatchedParts(TradeSide::sell, MonetaryAmount(5000, "APM"), MonetaryAmount("57.19", "KRW")), + AmountAtPriceVec({ + AmountPrice(MonetaryAmount("3890.879", "APM"), MonetaryAmount("57.19", "KRW")), + })); + EXPECT_EQ(marketOrderBook.computeMatchedParts(TradeSide::sell, MonetaryAmount(91000, "APM"), MonetaryAmount("57.23", "KRW")), AmountAtPriceVec()); } @@ -312,17 +311,17 @@ TEST_F(MarketOrderBookTestCase3, Convert) { } TEST_F(MarketOrderBookTestCase3, AvgPriceAndMatchedVolume) { - EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::kBuy, MonetaryAmount(100000, "XLM"), + EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::buy, MonetaryAmount(100000, "XLM"), MonetaryAmount("0.000007121", "BTC")), AmountPrice(MonetaryAmount(100000, "XLM"), MonetaryAmount("0.0000071176273715", "BTC"))); - EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::kBuy, MonetaryAmount(100000, "XLM"), + EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::buy, MonetaryAmount(100000, "XLM"), MonetaryAmount("0.000007090", "BTC")), AmountPrice(MonetaryAmount(0, "XLM"), MonetaryAmount(0, "BTC"))); - EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::kSell, MonetaryAmount("4500000", "XLM"), + EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::sell, MonetaryAmount("4500000", "XLM"), MonetaryAmount("0.000007079", "BTC")), AmountPrice(MonetaryAmount("411248.27", "XLM"), MonetaryAmount("0.00000708595487037", "BTC"))); - EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::kSell, MonetaryAmount("4500000", "XLM"), + EXPECT_EQ(marketOrderBook.avgPriceAndMatchedVolume(TradeSide::sell, MonetaryAmount("4500000", "XLM"), MonetaryAmount("0.000007110", "BTC")), AmountPrice(MonetaryAmount(0, "XLM"), MonetaryAmount(0, "BTC"))); } diff --git a/src/objects/test/publictrade_test.cpp b/src/objects/test/publictrade_test.cpp index 2de5278c..99043889 100644 --- a/src/objects/test/publictrade_test.cpp +++ b/src/objects/test/publictrade_test.cpp @@ -24,9 +24,9 @@ class PublicTradeTest : public ::testing::Test { MonetaryAmount price1{"1500.5", market.quote()}; MonetaryAmount price2{"1501", market.quote()}; - PublicTrade pt1{TradeSide::kBuy, amount1, price1, tp1}; - PublicTrade pt2{TradeSide::kSell, amount2, price2, tp2}; - PublicTrade pt3{TradeSide::kSell, amount3, price2, tp1}; + PublicTrade pt1{TradeSide::buy, amount1, price1, tp1}; + PublicTrade pt2{TradeSide::sell, amount2, price2, tp2}; + PublicTrade pt3{TradeSide::sell, amount3, price2, tp1}; }; TEST_F(PublicTradeTest, Validity) { @@ -35,16 +35,16 @@ TEST_F(PublicTradeTest, Validity) { EXPECT_TRUE(pt3.isValid()); EXPECT_FALSE(PublicTrade(static_cast(-1), amount1, price1, tp1).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, amount1, amount2, tp1).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, amount1, price1, TimePoint{}).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, MonetaryAmount{}, price1, tp1).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, amount1, MonetaryAmount{0, market.quote()}, tp1).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, -amount1, price1, tp1).isValid()); - EXPECT_FALSE(PublicTrade(TradeSide::kBuy, amount1, -price1, tp1).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, amount1, amount2, tp1).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, amount1, price1, TimePoint{}).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, MonetaryAmount{}, price1, tp1).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, amount1, MonetaryAmount{0, market.quote()}, tp1).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, -amount1, price1, tp1).isValid()); + EXPECT_FALSE(PublicTrade(TradeSide::buy, amount1, -price1, tp1).isValid()); } TEST_F(PublicTradeTest, Members) { - EXPECT_EQ(pt1.side(), TradeSide::kBuy); + EXPECT_EQ(pt1.side(), TradeSide::buy); EXPECT_EQ(pt1.market(), market); EXPECT_EQ(pt1.amount(), amount1); EXPECT_EQ(pt1.price(), price1); diff --git a/src/objects/test/time-window_test.cpp b/src/objects/test/time-window_test.cpp index 732ae3ec..7f3b7986 100644 --- a/src/objects/test/time-window_test.cpp +++ b/src/objects/test/time-window_test.cpp @@ -164,4 +164,32 @@ TEST_F(TimeWindowTest, AggregateMinMaxWithNeutral) { EXPECT_EQ(tw2.aggregateMinMax(tw1), tw1); } +namespace { +constexpr std::string_view kExpectedTimeWindowStr = "[1999-03-25T04:46:43Z -> 1999-07-11T00:42:21Z)"; +} + +TEST_F(TimeWindowTest, Str) { + TimeWindow tw(tp1, tp2); + + EXPECT_EQ(tw.str(), kExpectedTimeWindowStr); +} + +TEST_F(TimeWindowTest, AppendTo) { + TimeWindow tw(tp1, tp2); + char buf[TimeWindow::strLen()]; + + EXPECT_EQ(tw.appendTo(buf), buf + TimeWindow::strLen()); + EXPECT_EQ(std::string_view(buf, TimeWindow::strLen()), kExpectedTimeWindowStr); +} + +TEST_F(TimeWindowTest, FromString) { + TimeWindow tw(kExpectedTimeWindowStr); + + EXPECT_EQ(tw.str(), kExpectedTimeWindowStr); + + // For some reason, the timepoints are not exactly equal, they differ by a few hundreds of milliseconds + EXPECT_LT(tw.from() > tp1 ? tw.from() - tp1 : tp1 - tw.from(), std::chrono::seconds{1}); + EXPECT_LT(tw.to() > tp2 ? tw.to() - tp2 : tp2 - tw.to(), std::chrono::seconds{1}); +} + } // namespace cct diff --git a/src/objects/test/writer_mock.hpp b/src/objects/test/writer_mock.hpp deleted file mode 100644 index 2f441c72..00000000 --- a/src/objects/test/writer_mock.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "writer.hpp" - -namespace cct { - -class MockWriter : public Writer { - public: - MOCK_METHOD(int, write, (const json::container &, Writer::Mode), (const override)); -}; - -} // namespace cct \ No newline at end of file diff --git a/src/schema/include/duration-schema.hpp b/src/schema/include/duration-schema.hpp index d1337592..a6e15ac8 100644 --- a/src/schema/include/duration-schema.hpp +++ b/src/schema/include/duration-schema.hpp @@ -5,7 +5,7 @@ #include #include "cct_hash.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "durationstring.hpp" #include "generic-object-json.hpp" #include "timedef.hpp" diff --git a/src/schema/include/exchange-query-config.hpp b/src/schema/include/exchange-query-config.hpp index aa083c25..1bcba4f2 100644 --- a/src/schema/include/exchange-query-config.hpp +++ b/src/schema/include/exchange-query-config.hpp @@ -6,7 +6,7 @@ #include #include "apiquerytypeenum.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "cct_string.hpp" #include "cct_vector.hpp" diff --git a/src/schema/include/read-json.hpp b/src/schema/include/read-json.hpp index 47043c81..ca4cc485 100644 --- a/src/schema/include/read-json.hpp +++ b/src/schema/include/read-json.hpp @@ -4,7 +4,7 @@ #include #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_log.hpp" #include "file.hpp" #include "reader.hpp" diff --git a/src/schema/include/secret-schema.hpp b/src/schema/include/secret-schema.hpp index a4665039..2fa7cb77 100644 --- a/src/schema/include/secret-schema.hpp +++ b/src/schema/include/secret-schema.hpp @@ -3,7 +3,7 @@ #include #include "cct_const.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" namespace cct::schema { diff --git a/src/schema/include/size-bytes-schema.hpp b/src/schema/include/size-bytes-schema.hpp index 4db70dc3..ec70abf8 100644 --- a/src/schema/include/size-bytes-schema.hpp +++ b/src/schema/include/size-bytes-schema.hpp @@ -5,7 +5,7 @@ #include #include "cct_hash.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "generic-object-json.hpp" #include "unitsparser.hpp" diff --git a/src/schema/include/timepoint-schema.hpp b/src/schema/include/timepoint-schema.hpp index c0304954..9e848089 100644 --- a/src/schema/include/timepoint-schema.hpp +++ b/src/schema/include/timepoint-schema.hpp @@ -5,7 +5,7 @@ #include #include "cct_hash.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "generic-object-json.hpp" #include "timedef.hpp" #include "timestring.hpp" diff --git a/src/schema/include/write-json.hpp b/src/schema/include/write-json.hpp index 123470e4..8e06db88 100644 --- a/src/schema/include/write-json.hpp +++ b/src/schema/include/write-json.hpp @@ -1,7 +1,7 @@ #pragma once #include "cct_exception.hpp" -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" namespace cct { @@ -32,6 +32,15 @@ string WriteJsonOrThrow(const auto &obj) { string WriteMiniJsonOrThrow(const auto &obj) { return WriteJsonOrThrow(obj); } +string WriteSingleObjectJsonNoQuotes(const auto &obj) { + auto buf = WriteMiniJsonOrThrow(obj); + if (!buf.empty() && buf.front() == '"') { + buf.pop_back(); + buf.erase(buf.begin()); + } + return buf; +} + string WritePrettyJsonOrThrow(const auto &obj) { return WriteJsonOrThrow(obj); } } // namespace cct \ No newline at end of file diff --git a/src/schema/test/duration-schema_test.cpp b/src/schema/test/duration-schema_test.cpp index 2d4b3c3c..8f4d012a 100644 --- a/src/schema/test/duration-schema_test.cpp +++ b/src/schema/test/duration-schema_test.cpp @@ -6,7 +6,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" namespace cct::schema { diff --git a/src/schema/test/size-bytes-schema_test.cpp b/src/schema/test/size-bytes-schema_test.cpp index 653c4646..1b224cc5 100644 --- a/src/schema/test/size-bytes-schema_test.cpp +++ b/src/schema/test/size-bytes-schema_test.cpp @@ -5,7 +5,7 @@ #include #include -#include "cct_json-serialization.hpp" +#include "cct_json.hpp" #include "cct_string.hpp" namespace cct::schema { diff --git a/src/serialization/src/proto-public-trade-converter.cpp b/src/serialization/src/proto-public-trade-converter.cpp index 298ffaa0..672c4e79 100644 --- a/src/serialization/src/proto-public-trade-converter.cpp +++ b/src/serialization/src/proto-public-trade-converter.cpp @@ -12,9 +12,9 @@ namespace cct { namespace { ::proto::TradeSide ConvertTradeSide(TradeSide tradeSide) { switch (tradeSide) { - case TradeSide::kBuy: + case TradeSide::buy: return ::proto::TRADE_BUY; - case TradeSide::kSell: + case TradeSide::sell: return ::proto::TRADE_SELL; default: unreachable(); @@ -24,9 +24,9 @@ ::proto::TradeSide ConvertTradeSide(TradeSide tradeSide) { TradeSide ConvertTradeSide(::proto::TradeSide tradeSide) { switch (tradeSide) { case ::proto::TRADE_BUY: - return TradeSide::kBuy; + return TradeSide::buy; case ::proto::TRADE_SELL: - return TradeSide::kSell; + return TradeSide::sell; default: unreachable(); } diff --git a/src/serialization/test/proto-public-trade-converter_test.cpp b/src/serialization/test/proto-public-trade-converter_test.cpp index 3c9a8f72..48ba2200 100644 --- a/src/serialization/test/proto-public-trade-converter_test.cpp +++ b/src/serialization/test/proto-public-trade-converter_test.cpp @@ -17,7 +17,7 @@ class ProtoPublicTradeTest : public ::testing::Test { protected: TimePoint tp{milliseconds{std::numeric_limits::max() / 10000000}}; Market market{"ETH", "USDT"}; - PublicTrade pt{TradeSide::kBuy, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp}; + PublicTrade pt{TradeSide::buy, MonetaryAmount{"0.13", "ETH"}, MonetaryAmount{"1500.5", "USDT"}, tp}; PublicTradeConverter publicTradeConverter{market}; }; diff --git a/src/serialization/test/proto-serialization-and-deserialization_test.cpp b/src/serialization/test/proto-serialization-and-deserialization_test.cpp index 347a92d0..6f1f2fad 100644 --- a/src/serialization/test/proto-serialization-and-deserialization_test.cpp +++ b/src/serialization/test/proto-serialization-and-deserialization_test.cpp @@ -168,7 +168,7 @@ TEST_F(ProtobufSerializerDeserializerTest, ManySerializationsDifferentHoursOfDay for (Market market : kMarkets) { for (TimePoint tp : kTimePoints) { for (auto ts = tp; ts < tp + kDurationRange; ts += kDurationStep) { - TradeSide side = tp == tp1 ? TradeSide::kBuy : TradeSide::kSell; + TradeSide side = tp == tp1 ? TradeSide::buy : TradeSide::sell; MonetaryAmount amount{"0.13", market.base()}; MonetaryAmount price{"1500.5", market.quote()}; PublicTrade pt{side, amount, price, ts}; diff --git a/src/serialization/test/proto-test-data.hpp b/src/serialization/test/proto-test-data.hpp index 5ef1eea7..01ffc03e 100644 --- a/src/serialization/test/proto-test-data.hpp +++ b/src/serialization/test/proto-test-data.hpp @@ -41,17 +41,17 @@ class ProtobufBaseDataTest : public ::testing::Test { Market mk6{"ETH", "BTC"}; Market mk7{"DOGE", "CAD"}; - PublicTrade pt1{TradeSide::kBuy, MonetaryAmount{"0.13", mk1.base()}, MonetaryAmount{"1500.5", mk1.quote()}, tp1}; - PublicTrade pt2{TradeSide::kSell, MonetaryAmount{"3.7", mk1.base()}, MonetaryAmount{"1500.5", mk1.quote()}, tp2}; - PublicTrade pt3{TradeSide::kBuy, MonetaryAmount{"0.004", mk1.base()}, MonetaryAmount{1501, mk1.quote()}, tp3}; - PublicTrade pt4{TradeSide::kBuy, MonetaryAmount{"44473434", mk3.base()}, MonetaryAmount{"0.00045", mk3.quote()}, tp1}; - PublicTrade pt5{TradeSide::kBuy, MonetaryAmount{"45.0986", mk4.base()}, MonetaryAmount{"0.00045", mk4.quote()}, tp7}; - PublicTrade pt6{TradeSide::kSell, MonetaryAmount{"0.81153", mk6.base()}, MonetaryAmount{"0.0834", mk6.quote()}, tp6}; - PublicTrade pt7{TradeSide::kSell, MonetaryAmount{694873, mk7.base()}, MonetaryAmount{"0.045", mk7.quote()}, tp8}; - PublicTrade pt8{TradeSide::kSell, MonetaryAmount{"0.1", mk2.base()}, MonetaryAmount{50000, mk2.quote()}, tp4}; - PublicTrade pt9{TradeSide::kSell, MonetaryAmount{"56", mk1.base()}, MonetaryAmount{1300, mk1.quote()}, tp5}; - PublicTrade pt10{TradeSide::kBuy, MonetaryAmount{"37.8", mk5.base()}, MonetaryAmount{"0.032", mk5.quote()}, tp9}; - PublicTrade pt11{TradeSide::kBuy, MonetaryAmount{"12.2", mk5.base()}, MonetaryAmount{"0.033", mk5.quote()}, tp10}; + PublicTrade pt1{TradeSide::buy, MonetaryAmount{"0.13", mk1.base()}, MonetaryAmount{"1500.5", mk1.quote()}, tp1}; + PublicTrade pt2{TradeSide::sell, MonetaryAmount{"3.7", mk1.base()}, MonetaryAmount{"1500.5", mk1.quote()}, tp2}; + PublicTrade pt3{TradeSide::buy, MonetaryAmount{"0.004", mk1.base()}, MonetaryAmount{1501, mk1.quote()}, tp3}; + PublicTrade pt4{TradeSide::buy, MonetaryAmount{"44473434", mk3.base()}, MonetaryAmount{"0.00045", mk3.quote()}, tp1}; + PublicTrade pt5{TradeSide::buy, MonetaryAmount{"45.0986", mk4.base()}, MonetaryAmount{"0.00045", mk4.quote()}, tp7}; + PublicTrade pt6{TradeSide::sell, MonetaryAmount{"0.81153", mk6.base()}, MonetaryAmount{"0.0834", mk6.quote()}, tp6}; + PublicTrade pt7{TradeSide::sell, MonetaryAmount{694873, mk7.base()}, MonetaryAmount{"0.045", mk7.quote()}, tp8}; + PublicTrade pt8{TradeSide::sell, MonetaryAmount{"0.1", mk2.base()}, MonetaryAmount{50000, mk2.quote()}, tp4}; + PublicTrade pt9{TradeSide::sell, MonetaryAmount{"56", mk1.base()}, MonetaryAmount{1300, mk1.quote()}, tp5}; + PublicTrade pt10{TradeSide::buy, MonetaryAmount{"37.8", mk5.base()}, MonetaryAmount{"0.032", mk5.quote()}, tp9}; + PublicTrade pt11{TradeSide::buy, MonetaryAmount{"12.2", mk5.base()}, MonetaryAmount{"0.033", mk5.quote()}, tp10}; ::proto::PublicTrade td1{ConvertPublicTradeToProto(pt1)}; ::proto::PublicTrade td2{ConvertPublicTradeToProto(pt2)}; diff --git a/src/tech/CMakeLists.txt b/src/tech/CMakeLists.txt index 151d710f..25be1e65 100644 --- a/src/tech/CMakeLists.txt +++ b/src/tech/CMakeLists.txt @@ -3,7 +3,6 @@ aux_source_directory(src API_TECH_SRC) add_coincenter_library(tech STATIC ${API_TECH_SRC}) -target_link_libraries(coincenter_tech PUBLIC nlohmann_json::nlohmann_json) target_link_libraries(coincenter_tech PUBLIC glaze::glaze) if (LINK_AMC) @@ -64,8 +63,6 @@ add_unit_test( test/flatkeyvaluestring_test.cpp DEFINITIONS CCT_DISABLE_SPDLOG - LIBRARIES - nlohmann_json::nlohmann_json ) if(MSVC) diff --git a/src/tech/include/cct_json-container.hpp b/src/tech/include/cct_json-container.hpp deleted file mode 100644 index dd8cf84b..00000000 --- a/src/tech/include/cct_json-container.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "cct_allocator.hpp" -#include "cct_smallvector.hpp" -#include "cct_string.hpp" -#include "cct_vector.hpp" - -namespace cct::json { - -using container = ::nlohmann::basic_json<::std::map, ::cct::vector, ::cct::string, bool, int64_t, uint64_t, double, - ::cct::allocator, ::nlohmann::adl_serializer, ::cct::SmallVector>; - -} // namespace cct::json diff --git a/src/tech/include/cct_json-serialization.hpp b/src/tech/include/cct_json.hpp similarity index 100% rename from src/tech/include/cct_json-serialization.hpp rename to src/tech/include/cct_json.hpp diff --git a/src/trading/algorithms/src/example-market-trader.cpp b/src/trading/algorithms/src/example-market-trader.cpp index 5018b146..d1458e67 100644 --- a/src/trading/algorithms/src/example-market-trader.cpp +++ b/src/trading/algorithms/src/example-market-trader.cpp @@ -12,7 +12,7 @@ ExampleMarketTrader::ExampleMarketTrader(const MarketTraderEngineState &marketTr : AbstractMarketTrader(kName, marketTraderEngineState) {} TraderCommand ExampleMarketTrader::trade([[maybe_unused]] const MarketDataView &marketDataView) { - return TraderCommand::Place(TradeSide::kSell); + return TraderCommand::Place(TradeSide::sell); } } // namespace cct \ No newline at end of file diff --git a/src/trading/common/src/market-trader-engine-state.cpp b/src/trading/common/src/market-trader-engine-state.cpp index 94d0107e..04c5fb83 100644 --- a/src/trading/common/src/market-trader-engine-state.cpp +++ b/src/trading/common/src/market-trader-engine-state.cpp @@ -36,9 +36,9 @@ void MarketTraderEngineState::placeBuyOrder(const schema::ExchangeConfig &exchan _availableQuoteAmount -= from; if (remainingVolume == 0) { - _closedOrders.emplace_back(nextOrderId(), matchedVolume, price, placedTime, placedTime, TradeSide::kBuy); + _closedOrders.emplace_back(nextOrderId(), matchedVolume, price, placedTime, placedTime, TradeSide::buy); } else { - _openedOrders.emplace_back(nextOrderId(), matchedVolume, remainingVolume, price, placedTime, TradeSide::kBuy); + _openedOrders.emplace_back(nextOrderId(), matchedVolume, remainingVolume, price, placedTime, TradeSide::buy); } } @@ -50,9 +50,9 @@ void MarketTraderEngineState::placeSellOrder(const schema::ExchangeConfig &excha _availableQuoteAmount += exchangeConfig.tradeFees.applyFee(matchedVolume.toNeutral() * price, feeType); if (remainingVolume == 0) { - _closedOrders.emplace_back(nextOrderId(), matchedVolume, price, placedTime, placedTime, TradeSide::kSell); + _closedOrders.emplace_back(nextOrderId(), matchedVolume, price, placedTime, placedTime, TradeSide::sell); } else { - _openedOrders.emplace_back(nextOrderId(), matchedVolume, remainingVolume, price, placedTime, TradeSide::kSell); + _openedOrders.emplace_back(nextOrderId(), matchedVolume, remainingVolume, price, placedTime, TradeSide::sell); } } @@ -70,11 +70,11 @@ void MarketTraderEngineState::countMatchedPart(const schema::ExchangeConfig &exc const OpenedOrder &matchedOrder, MonetaryAmount price, MonetaryAmount newMatchedVolume, TimePoint matchedTime) { switch (matchedOrder.side()) { - case TradeSide::kBuy: + case TradeSide::buy: _availableBaseAmount += exchangeConfig.tradeFees.applyFee(newMatchedVolume, schema::ExchangeTradeFeesConfig::FeeType::Maker); break; - case TradeSide::kSell: + case TradeSide::sell: _availableQuoteAmount += exchangeConfig.tradeFees.applyFee(newMatchedVolume.toNeutral() * price, schema::ExchangeTradeFeesConfig::FeeType::Maker); break; @@ -119,10 +119,10 @@ void MarketTraderEngineState::cancelAllOpenedOrders() { void MarketTraderEngineState::adjustAvailableAmountsCancel(const OpenedOrder &openedOrder) { switch (openedOrder.side()) { - case TradeSide::kBuy: + case TradeSide::buy: _availableQuoteAmount += openedOrder.remainingVolume().toNeutral() * openedOrder.price(); break; - case TradeSide::kSell: + case TradeSide::sell: _availableBaseAmount += openedOrder.remainingVolume(); break; default: diff --git a/src/trading/common/src/market-trader-engine.cpp b/src/trading/common/src/market-trader-engine.cpp index d39612d8..926eecf1 100644 --- a/src/trading/common/src/market-trader-engine.cpp +++ b/src/trading/common/src/market-trader-engine.cpp @@ -303,10 +303,10 @@ void MarketTraderEngine::updatePrice(const MarketOrderBook &marketOrderBook, Tra _marketTraderEngineState.cancelOpenedOrder(traderCommand.orderId()); switch (tradeSide) { - case TradeSide::kBuy: + case TradeSide::buy: buy(marketOrderBook, remainingAmount.toNeutral() * price, traderCommand.priceStrategy()); break; - case TradeSide::kSell: + case TradeSide::sell: sell(marketOrderBook, remainingAmount, traderCommand.priceStrategy()); break; default: diff --git a/src/trading/common/src/trader-command.cpp b/src/trading/common/src/trader-command.cpp index 6d3082b5..de3e1387 100644 --- a/src/trading/common/src/trader-command.cpp +++ b/src/trading/common/src/trader-command.cpp @@ -23,10 +23,10 @@ TraderCommand TraderCommand::Place(TradeSide tradeSide, int8_t amountIntensityPe } Type type; switch (tradeSide) { - case TradeSide::kBuy: + case TradeSide::buy: type = Type::kBuy; break; - case TradeSide::kSell: + case TradeSide::sell: type = Type::kSell; break; default: @@ -52,9 +52,9 @@ TraderCommand TraderCommand::UpdatePrice(OrderIdView orderId, PriceStrategy pric TradeSide TraderCommand::tradeSide() const { switch (_type) { case Type::kBuy: - return TradeSide::kBuy; + return TradeSide::buy; case Type::kSell: - return TradeSide::kSell; + return TradeSide::sell; default: throw exception("Unexpected trade command type for trade side"); }