From 89ce5ec07883a11592f870aad6294325d6e40e58 Mon Sep 17 00:00:00 2001 From: Stephane Janel Date: Tue, 12 Nov 2024 22:44:54 +0100 Subject: [PATCH] [Code refactoring] - Use ExchangeNameEnum instead of string_view in ExchangePublic --- src/api-objects/include/apikeysprovider.hpp | 8 ++- src/api-objects/src/apikeysprovider.cpp | 21 ++++--- src/api/common/include/exchangeprivateapi.hpp | 4 +- src/api/common/src/exchangeprivateapi.cpp | 2 +- src/api/exchanges/src/binanceprivateapi.cpp | 2 +- src/api/exchanges/src/bithumbprivateapi.cpp | 9 ++- src/api/exchanges/src/huobiprivateapi.cpp | 2 +- src/api/exchanges/src/krakenprivateapi.cpp | 2 +- src/api/exchanges/src/kucoinprivateapi.cpp | 2 +- src/api/exchanges/src/upbitprivateapi.cpp | 7 +-- .../test/bithumb_place_order_test.cpp | 3 +- .../exchanges/test/exchangecommonapi_test.hpp | 8 +-- src/api/interface/include/exchange.hpp | 6 +- .../interface/include/exchangeretriever.hpp | 13 +++- src/api/interface/src/exchangepool.cpp | 27 ++++---- src/basic-objects/include/cct_const.hpp | 8 ++- src/engine/include/coincenter.hpp | 10 +-- src/engine/include/coincenteroptionsdef.hpp | 1 - src/engine/include/exchangesorchestrator.hpp | 8 +-- src/engine/include/queryresulttypes.hpp | 2 +- .../src/coincenter-commands-processor.cpp | 6 +- src/engine/src/coincenter.cpp | 35 ++++++----- src/engine/src/exchangesorchestrator.cpp | 18 +++--- src/engine/src/metricsexporter.cpp | 8 +-- src/engine/src/queryresultprinter.cpp | 8 +-- .../test/coincentercommandfactory_test.cpp | 31 ++++----- .../exchangesorchestrator_private_test.cpp | 37 +++++------ .../exchangesorchestrator_public_test.cpp | 5 +- .../test/exchangesorchestrator_trade_test.cpp | 63 ++++++++++--------- .../test/queryresultprinter_public_test.cpp | 43 ++++++------- src/engine/test/stringoptionparser_test.cpp | 25 +++++--- .../test/transferablecommandresult_test.cpp | 8 +-- src/objects/include/exchange-names.hpp | 5 +- src/objects/include/exchangename.hpp | 4 +- src/objects/include/marketorderbook.hpp | 3 +- src/objects/src/exchange-names.cpp | 12 ++++ src/objects/src/exchangename.cpp | 9 +-- src/objects/src/marketorderbook.cpp | 3 +- src/objects/test/exchangename_test.cpp | 19 +++--- src/objects/test/wallet_test.cpp | 8 +-- 40 files changed, 272 insertions(+), 223 deletions(-) diff --git a/src/api-objects/include/apikeysprovider.hpp b/src/api-objects/include/apikeysprovider.hpp index ba4da3b3..18906a6b 100644 --- a/src/api-objects/include/apikeysprovider.hpp +++ b/src/api-objects/include/apikeysprovider.hpp @@ -23,9 +23,11 @@ class APIKeysProvider { APIKeysProvider(std::string_view dataDir, const ExchangeSecretsInfo &exchangeSecretsInfo, settings::RunMode runMode); - KeyNames getKeyNames(std::string_view platform) const; + KeyNames getKeyNames(ExchangeNameEnum exchangeNameEnum) const; - bool contains(std::string_view platform) const { return _apiKeysMap.find(platform) != _apiKeysMap.end(); } + bool contains(ExchangeNameEnum exchangeNameEnum) const { + return _apiKeysMap.find(exchangeNameEnum) != _apiKeysMap.end(); + } const APIKey &get(const ExchangeName &exchangeName) const; @@ -33,7 +35,7 @@ class APIKeysProvider { private: using APIKeys = vector; - using APIKeysMap = std::map>; + using APIKeysMap = std::map; static APIKeysMap ParseAPIKeys(std::string_view dataDir, const ExchangeSecretsInfo &exchangeSecretsInfo, settings::RunMode runMode); diff --git a/src/api-objects/src/apikeysprovider.cpp b/src/api-objects/src/apikeysprovider.cpp index 7d5e23d1..30f6638c 100644 --- a/src/api-objects/src/apikeysprovider.cpp +++ b/src/api-objects/src/apikeysprovider.cpp @@ -40,9 +40,9 @@ APIKeysProvider::APIKeysProvider(std::string_view dataDir, const ExchangeSecrets } } -APIKeysProvider::KeyNames APIKeysProvider::getKeyNames(std::string_view platform) const { +APIKeysProvider::KeyNames APIKeysProvider::getKeyNames(ExchangeNameEnum exchangeNameEnum) const { KeyNames keyNames; - auto foundIt = _apiKeysMap.find(platform); + auto foundIt = _apiKeysMap.find(exchangeNameEnum); if (foundIt != _apiKeysMap.end()) { const APIKeys& apiKeys = foundIt->second; std::ranges::transform(apiKeys, std::back_inserter(keyNames), [](const APIKey& apiKey) { return apiKey.name(); }); @@ -52,7 +52,10 @@ APIKeysProvider::KeyNames APIKeysProvider::getKeyNames(std::string_view platform const APIKey& APIKeysProvider::get(const ExchangeName& exchangeName) const { std::string_view platformStr = exchangeName.name(); - auto foundIt = _apiKeysMap.find(platformStr); + ExchangeNameEnum exchangeNameEnum = static_cast( + std::find(std::begin(kSupportedExchanges), std::end(kSupportedExchanges), platformStr) - + std::begin(kSupportedExchanges)); + auto foundIt = _apiKeysMap.find(exchangeNameEnum); if (foundIt == _apiKeysMap.end()) { throw exception("Unable to retrieve private key for {}", platformStr); } @@ -89,6 +92,10 @@ APIKeysProvider::APIKeysMap APIKeysProvider::ParseAPIKeys(std::string_view dataD log::info("Not loading {} private keys as requested", publicExchangeName); continue; } + ExchangeNameEnum exchangeNameEnum = static_cast( + std::find(std::begin(kSupportedExchanges), std::end(kSupportedExchanges), publicExchangeName) - + std::begin(kSupportedExchanges)); + for (auto& [name, keySecretObj] : keyObj.items()) { auto keyIt = keySecretObj.find("key"); auto privateIt = keySecretObj.find("private"); @@ -115,9 +122,9 @@ APIKeysProvider::APIKeysMap APIKeysProvider::ParseAPIKeys(std::string_view dataD } } - map[publicExchangeName].emplace_back(publicExchangeName, name, std::move(keyIt->get_ref()), - std::move(privateIt->get_ref()), std::move(passphrase), - AccountOwner(ownerEnName, ownerKoName)); + map[exchangeNameEnum].emplace_back(publicExchangeName, name, std::move(keyIt->get_ref()), + std::move(privateIt->get_ref()), std::move(passphrase), + AccountOwner(ownerEnName, ownerKoName)); } } if (map.empty()) { @@ -149,7 +156,7 @@ string APIKeysProvider::str() const { foundKeysStr.push_back('}'); } foundKeysStr.push_back('@'); - foundKeysStr.append(platform); + foundKeysStr.append(kSupportedExchanges[static_cast(platform)]); } return foundKeysStr; } diff --git a/src/api/common/include/exchangeprivateapi.hpp b/src/api/common/include/exchangeprivateapi.hpp index 8f095b4b..be359147 100644 --- a/src/api/common/include/exchangeprivateapi.hpp +++ b/src/api/common/include/exchangeprivateapi.hpp @@ -124,9 +124,9 @@ class ExchangePrivate : public CacheFileUpdatorInterface { TradedAmountsVectorWithFinalAmount queryDustSweeper(CurrencyCode currencyCode); /// Builds an ExchangeName wrapping the exchange and the key name - ExchangeName exchangeName() const { return {_exchangePublic.name(), _apiKey.name()}; } + ExchangeName exchangeName() const { return ExchangeName(_exchangePublic.exchangeNameEnum(), _apiKey.name()); } - const ExchangeConfig &exchangeConfig() const { return _exchangePublic.exchangeConfig(); } + const auto &exchangeConfig() const { return _exchangePublic.exchangeConfig(); } protected: ExchangePrivate(const CoincenterInfo &coincenterInfo, ExchangePublic &exchangePublic, const APIKey &apiKey); diff --git a/src/api/common/src/exchangeprivateapi.cpp b/src/api/common/src/exchangeprivateapi.cpp index 733e02a6..adfc413f 100644 --- a/src/api/common/src/exchangeprivateapi.cpp +++ b/src/api/common/src/exchangeprivateapi.cpp @@ -586,7 +586,7 @@ PlaceOrderInfo ExchangePrivate::computeSimulatedMatchedPlacedOrderInfo(MonetaryA const bool isSell = tradeInfo.tradeContext.side == TradeSide::kSell; MonetaryAmount toAmount = isSell ? volume.convertTo(price) : volume; - ExchangeConfig::FeeType feeType = isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; + auto feeType = isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; toAmount = _coincenterInfo.exchangeConfig(_exchangePublic.name()).applyFee(toAmount, feeType); PlaceOrderInfo placeOrderInfo(OrderInfo(TradedAmounts(isSell ? volume : volume.toNeutral() * price, toAmount)), OrderId("SimulatedOrderId")); diff --git a/src/api/exchanges/src/binanceprivateapi.cpp b/src/api/exchanges/src/binanceprivateapi.cpp index ee5be48c..2a40289b 100644 --- a/src/api/exchanges/src/binanceprivateapi.cpp +++ b/src/api/exchanges/src/binanceprivateapi.cpp @@ -289,7 +289,7 @@ Wallet BinancePrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) const CoincenterInfo& coincenterInfo = _exchangePublic.coincenterInfo(); bool doCheckWallet = coincenterInfo.exchangeConfig(_exchangePublic.name()).validateDepositAddressesInFile(); WalletCheck walletCheck(coincenterInfo.dataDir(), doCheckWallet); - Wallet wallet(ExchangeName(_exchangePublic.name(), _apiKey.name()), currencyCode, + Wallet wallet(ExchangeName(_exchangePublic.exchangeNameEnum(), _apiKey.name()), currencyCode, std::move(result["address"].get_ref()), tag, walletCheck, _apiKey.accountOwner()); log::info("Retrieved {} (URL: '{}')", wallet, result["url"].get()); return wallet; diff --git a/src/api/exchanges/src/bithumbprivateapi.cpp b/src/api/exchanges/src/bithumbprivateapi.cpp index c92ced3f..2fed6004 100644 --- a/src/api/exchanges/src/bithumbprivateapi.cpp +++ b/src/api/exchanges/src/bithumbprivateapi.cpp @@ -410,8 +410,8 @@ Wallet BithumbPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) const CoincenterInfo& coincenterInfo = _exchangePublic.coincenterInfo(); bool doCheckWallet = coincenterInfo.exchangeConfig(_exchangePublic.name()).validateDepositAddressesInFile(); WalletCheck walletCheck(coincenterInfo.dataDir(), doCheckWallet); - Wallet wallet(ExchangeName(_exchangePublic.name(), _apiKey.name()), currencyCode, string(address), tag, walletCheck, - _apiKey.accountOwner()); + Wallet wallet(ExchangeName(_exchangePublic.exchangeNameEnum(), _apiKey.name()), currencyCode, string(address), tag, + walletCheck, _apiKey.accountOwner()); log::info("Retrieved {}", wallet); return wallet; } @@ -867,9 +867,8 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun // Volume is gross amount if from amount is in quote currency, we should remove the fees if (fromCurrencyCode == mk.quote()) { - ExchangeConfig::FeeType feeType = - isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; - const ExchangeConfig& exchangeConfig = _coincenterInfo.exchangeConfig(_exchangePublic.name()); + const auto feeType = isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; + const auto& exchangeConfig = _coincenterInfo.exchangeConfig(_exchangePublic.name()); volume = exchangeConfig.applyFee(volume, feeType); } diff --git a/src/api/exchanges/src/huobiprivateapi.cpp b/src/api/exchanges/src/huobiprivateapi.cpp index 2b80219d..22b89cb9 100644 --- a/src/api/exchanges/src/huobiprivateapi.cpp +++ b/src/api/exchanges/src/huobiprivateapi.cpp @@ -194,7 +194,7 @@ Wallet HuobiPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { string address; std::string_view tag; - ExchangeName exchangeName(_huobiPublic.name(), _apiKey.name()); + ExchangeName exchangeName(_huobiPublic.exchangeNameEnum(), _apiKey.name()); const CoincenterInfo& coincenterInfo = _huobiPublic.coincenterInfo(); bool doCheckWallet = coincenterInfo.exchangeConfig(_huobiPublic.name()).validateDepositAddressesInFile(); WalletCheck walletCheck(coincenterInfo.dataDir(), doCheckWallet); diff --git a/src/api/exchanges/src/krakenprivateapi.cpp b/src/api/exchanges/src/krakenprivateapi.cpp index 833b78ed..cc616e20 100644 --- a/src/api/exchanges/src/krakenprivateapi.cpp +++ b/src/api/exchanges/src/krakenprivateapi.cpp @@ -199,7 +199,7 @@ BalancePortfolio KrakenPrivate::queryAccountBalance(const BalanceOptions& balanc Wallet KrakenPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { CurrencyExchange krakenCurrency = _exchangePublic.convertStdCurrencyToCurrencyExchange(currencyCode); auto [res, err] = PrivateQuery(_curlHandle, _apiKey, "/private/DepositMethods", {{"asset", krakenCurrency.altStr()}}); - ExchangeName eName(_exchangePublic.name(), _apiKey.name()); + ExchangeName eName(_exchangePublic.exchangeNameEnum(), _apiKey.name()); if (res.empty()) { throw exception("No deposit method found on {} for {}", eName, currencyCode); } diff --git a/src/api/exchanges/src/kucoinprivateapi.cpp b/src/api/exchanges/src/kucoinprivateapi.cpp index 04c05b01..d713eb83 100644 --- a/src/api/exchanges/src/kucoinprivateapi.cpp +++ b/src/api/exchanges/src/kucoinprivateapi.cpp @@ -198,7 +198,7 @@ BalancePortfolio KucoinPrivate::queryAccountBalance(const BalanceOptions& balanc Wallet KucoinPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { json::container result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/api/v2/deposit-addresses", {{"currency", currencyCode.str()}})["data"]; - ExchangeName exchangeName(_kucoinPublic.name(), _apiKey.name()); + ExchangeName exchangeName(_kucoinPublic.exchangeNameEnum(), _apiKey.name()); if (result.empty()) { log::info("No deposit address for {} in {}, creating one", currencyCode, exchangeName); result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kPost, "/api/v1/deposit-addresses", diff --git a/src/api/exchanges/src/upbitprivateapi.cpp b/src/api/exchanges/src/upbitprivateapi.cpp index b8d46b93..85679f22 100644 --- a/src/api/exchanges/src/upbitprivateapi.cpp +++ b/src/api/exchanges/src/upbitprivateapi.cpp @@ -238,7 +238,7 @@ Wallet UpbitPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { const CoincenterInfo& coincenterInfo = _exchangePublic.coincenterInfo(); bool doCheckWallet = coincenterInfo.exchangeConfig(_exchangePublic.name()).validateDepositAddressesInFile(); WalletCheck walletCheck(coincenterInfo.dataDir(), doCheckWallet); - Wallet wallet(ExchangeName(_exchangePublic.name(), _apiKey.name()), currencyCode, + Wallet wallet(ExchangeName(_exchangePublic.exchangeNameEnum(), _apiKey.name()), currencyCode, std::move(addressIt->get_ref()), tag, walletCheck, _apiKey.accountOwner()); log::info("Retrieved {}", wallet); return wallet; @@ -554,9 +554,8 @@ void UpbitPrivate::applyFee(Market mk, CurrencyCode fromCurrencyCode, bool isTak MonetaryAmount& volume) { if (fromCurrencyCode == mk.quote()) { // For 'buy', from amount is fee excluded - ExchangeConfig::FeeType feeType = - isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; - const ExchangeConfig& exchangeConfig = _coincenterInfo.exchangeConfig(_exchangePublic.name()); + const auto feeType = isTakerStrategy ? ExchangeConfig::FeeType::kTaker : ExchangeConfig::FeeType::kMaker; + const auto& exchangeConfig = _coincenterInfo.exchangeConfig(_exchangePublic.name()); if (isTakerStrategy) { from = exchangeConfig.applyFee(from, feeType); } else { diff --git a/src/api/exchanges/test/bithumb_place_order_test.cpp b/src/api/exchanges/test/bithumb_place_order_test.cpp index 6be1c407..2f4b431b 100644 --- a/src/api/exchanges/test/bithumb_place_order_test.cpp +++ b/src/api/exchanges/test/bithumb_place_order_test.cpp @@ -43,7 +43,8 @@ class BithumbPrivateAPIPlaceOrderTest : public ::testing::Test { CommonAPI commonAPI{coincenterInfo, Duration::max()}; BithumbPublic exchangePublic{coincenterInfo, fiatConverter, commonAPI}; APIKeysProvider apiKeysProvider{coincenterInfo.dataDir(), coincenterInfo.getRunMode()}; - ExchangeName exchangeName{exchangePublic.name(), apiKeysProvider.getKeyNames(exchangePublic.name()).front()}; + ExchangeName exchangeName{exchangePublic.exchangeNameEnum(), + apiKeysProvider.getKeyNames(exchangePublic.exchangeNameEnum()).front()}; const APIKey& testKey = apiKeysProvider.get(exchangeName); BithumbPrivate exchangePrivate{coincenterInfo, exchangePublic, testKey}; diff --git a/src/api/exchanges/test/exchangecommonapi_test.hpp b/src/api/exchanges/test/exchangecommonapi_test.hpp index a3614ed9..068ff14b 100644 --- a/src/api/exchanges/test/exchangecommonapi_test.hpp +++ b/src/api/exchanges/test/exchangecommonapi_test.hpp @@ -299,13 +299,13 @@ class TestAPI { private: void createPrivateExchangeIfKeyPresent() { - std::string_view publicExchangeName = exchangePublic.name(); - if (!apiKeysProvider.contains(publicExchangeName)) { - log::warn("Skip {} private API test as cannot find associated private key", publicExchangeName); + auto exchangeNameEnum = exchangePublic.exchangeNameEnum(); + if (!apiKeysProvider.contains(exchangeNameEnum)) { + log::warn("Skip {} private API test as cannot find associated private key", exchangePublic.name()); return; } - ExchangeName exchangeName(publicExchangeName, apiKeysProvider.getKeyNames(publicExchangeName).front()); + ExchangeName exchangeName(exchangeNameEnum, apiKeysProvider.getKeyNames(exchangeNameEnum).front()); const APIKey &firstAPIKey = apiKeysProvider.get(exchangeName); exchangePrivateOpt.emplace(coincenterInfo, exchangePublic, firstAPIKey); diff --git a/src/api/interface/include/exchange.hpp b/src/api/interface/include/exchange.hpp index 80b49f8e..88a6bed9 100644 --- a/src/api/interface/include/exchange.hpp +++ b/src/api/interface/include/exchange.hpp @@ -36,15 +36,13 @@ class Exchange : public CacheFileUpdatorInterface { std::unique_ptr exchangePrivate); std::string_view name() const { return apiPublic().name(); } + ExchangeNameEnum exchangeNameEnum() const { return apiPublic().exchangeNameEnum(); } std::string_view keyName() const { return apiPrivate().keyName(); } std::size_t publicExchangePos() const; ExchangeName createExchangeName() const { - if (hasPrivateAPI()) { - return {name(), keyName()}; - } - return ExchangeName(name()); + return ExchangeName(exchangeNameEnum(), hasPrivateAPI() ? keyName() : std::string_view()); } ExchangePublic &apiPublic() { return *_pExchangePublic; } diff --git a/src/api/interface/include/exchangeretriever.hpp b/src/api/interface/include/exchangeretriever.hpp index fc5e850a..ab34dc9c 100644 --- a/src/api/interface/include/exchangeretriever.hpp +++ b/src/api/interface/include/exchangeretriever.hpp @@ -89,7 +89,11 @@ class ExchangeRetriever { ret.push_back(std::addressof(*foundIt)); } if (ret.size() == oldSize) { - throw exception("Unable to find {} in the exchange list", name); + if constexpr (std::is_same_v, ExchangeNameEnum>) { + throw exception("Unable to find {} in the exchange list", kSupportedExchanges[static_cast(name)]); + } else { + throw exception("Unable to find {} in the exchange list", name); + } } } break; @@ -103,13 +107,16 @@ class ExchangeRetriever { template struct Matcher { - static_assert(std::is_same_v || std::is_same_v); + static_assert(std::is_same_v || std::is_same_v || + std::is_same_v); bool operator()(const Exchange &e, const NameType &n) const { if constexpr (std::is_same_v) { return e.name() == n; - } else { + } else if constexpr (std::is_same_v) { return e.matches(n); + } else if constexpr (std::is_same_v) { + return e.exchangeNameEnum() == n; } } }; diff --git a/src/api/interface/src/exchangepool.cpp b/src/api/interface/src/exchangepool.cpp index ad25e314..95b00cbb 100644 --- a/src/api/interface/src/exchangepool.cpp +++ b/src/api/interface/src/exchangepool.cpp @@ -34,30 +34,31 @@ ExchangePool::ExchangePool(const CoincenterInfo& coincenterInfo, FiatConverter& _krakenPublic(_coincenterInfo, _fiatConverter, _commonAPI), _kucoinPublic(_coincenterInfo, _fiatConverter, _commonAPI), _upbitPublic(_coincenterInfo, _fiatConverter, _commonAPI) { - for (std::string_view exchangeStr : kSupportedExchanges) { + for (int exchangePos = 0; exchangePos < kNbSupportedExchanges; ++exchangePos) { + ExchangeNameEnum exchangeNameEnum = static_cast(exchangePos); api::ExchangePublic* exchangePublic; - if (exchangeStr == "binance") { + if (exchangeNameEnum == ExchangeNameEnum::binance) { exchangePublic = &_binancePublic; - } else if (exchangeStr == "bithumb") { + } else if (exchangeNameEnum == ExchangeNameEnum::bithumb) { exchangePublic = &_bithumbPublic; - } else if (exchangeStr == "huobi") { + } else if (exchangeNameEnum == ExchangeNameEnum::huobi) { exchangePublic = &_huobiPublic; - } else if (exchangeStr == "kraken") { + } else if (exchangeNameEnum == ExchangeNameEnum::kraken) { exchangePublic = &_krakenPublic; - } else if (exchangeStr == "kucoin") { + } else if (exchangeNameEnum == ExchangeNameEnum::kucoin) { exchangePublic = &_kucoinPublic; - } else if (exchangeStr == "upbit") { + } else if (exchangeNameEnum == ExchangeNameEnum::upbit) { exchangePublic = &_upbitPublic; } else { - throw exception("Should not happen, unsupported platform {}", exchangeStr); + throw exception("Should not happen, unsupported exchange pos {}", exchangePos); } - const bool canUsePrivateExchange = _apiKeyProvider.contains(exchangeStr); - const ExchangeConfig& exchangeConfig = _coincenterInfo.exchangeConfig(exchangePublic->name()); + const bool canUsePrivateExchange = _apiKeyProvider.contains(exchangeNameEnum); + const auto& exchangeConfig = _coincenterInfo.exchangeConfig(kSupportedExchanges[exchangePos]); if (canUsePrivateExchange) { - for (std::string_view keyName : _apiKeyProvider.getKeyNames(exchangeStr)) { + for (std::string_view keyName : _apiKeyProvider.getKeyNames(exchangeNameEnum)) { std::unique_ptr exchangePrivate; - ExchangeName exchangeName(exchangeStr, keyName); + ExchangeName exchangeName(exchangeNameEnum, keyName); const api::APIKey& apiKey = _apiKeyProvider.get(exchangeName); if (exchangePublic == &_binancePublic) { exchangePrivate = std::make_unique(_coincenterInfo, _binancePublic, apiKey); @@ -72,7 +73,7 @@ ExchangePool::ExchangePool(const CoincenterInfo& coincenterInfo, FiatConverter& } else if (exchangePublic == &_upbitPublic) { exchangePrivate = std::make_unique(_coincenterInfo, _upbitPublic, apiKey); } else { - throw exception("Unsupported platform {}", exchangeStr); + throw exception("Should not happen"); } if (exchangeConfig.shouldValidateApiKey()) { diff --git a/src/basic-objects/include/cct_const.hpp b/src/basic-objects/include/cct_const.hpp index 763e2d7b..dc7a89e1 100644 --- a/src/basic-objects/include/cct_const.hpp +++ b/src/basic-objects/include/cct_const.hpp @@ -9,7 +9,9 @@ namespace cct { -enum class ExchangeNameEnum : int8_t { binance, bithumb, huobi, kraken, kucoin, upbit }; +#define CCT_EXCHANGE_NAMES binance, bithumb, huobi, kraken, kucoin, upbit + +enum class ExchangeNameEnum : int8_t { CCT_EXCHANGE_NAMES }; static constexpr std::string_view kDefaultDataDir = CCT_DATA_DIR; @@ -35,9 +37,11 @@ template <> struct glz::meta { using enum cct::ExchangeNameEnum; - static constexpr auto value = enumerate(binance, bithumb, huobi, kraken, kucoin, upbit); + static constexpr auto value = enumerate(CCT_EXCHANGE_NAMES); }; +#undef CCT_EXCHANGE_NAMES + namespace cct { /// Ordered list of supported exchange names. diff --git a/src/engine/include/coincenter.hpp b/src/engine/include/coincenter.hpp index 00a1bd1f..e813e142 100644 --- a/src/engine/include/coincenter.hpp +++ b/src/engine/include/coincenter.hpp @@ -107,11 +107,11 @@ class Coincenter { /// Returns given amount converted into target currency code for given exchanges, when possible. MonetaryAmountPerExchange getConversion(MonetaryAmount amount, CurrencyCode targetCurrencyCode, - ExchangeNameSpan exchangeNames); + ExchangeNameEnumSpan exchangeNameEnums); /// Returns given amount per exchange converted into target currency code for given exchanges, when possible. MonetaryAmountPerExchange getConversion(std::span monetaryAmountPerExchangeToConvert, - CurrencyCode targetCurrencyCode, ExchangeNameSpan exchangeNames); + CurrencyCode targetCurrencyCode, ExchangeNameEnumSpan exchangeNameEnums); /// Query the conversion paths for each public exchange requested ConversionPathPerExchange getConversionPaths(Market mk, ExchangeNameSpan exchangeNames); @@ -170,15 +170,15 @@ class Coincenter { std::string_view algorithmName, const ReplayOptions &replayOptions, std::span marketTraderEngines, - const PublicExchangeNameVector &exchangesWithThisMarketData); + const ExchangeNameEnumVector &exchangesWithThisMarketData); // TODO: may be moved somewhere else? MarketTraderEngineVector createMarketTraderEngines(const ReplayOptions &replayOptions, Market market, - PublicExchangeNameVector &exchangesWithThisMarketData); + ExchangeNameEnumVector &exchangesWithThisMarketData); MarketTradeRangeStatsPerExchange tradingProcess(const ReplayOptions &replayOptions, std::span marketTraderEngines, - ExchangeNameSpan exchangesWithThisMarketData); + std::span exchangesWithThisMarketData); const CoincenterInfo &_coincenterInfo; api::CommonAPI _commonAPI; diff --git a/src/engine/include/coincenteroptionsdef.hpp b/src/engine/include/coincenteroptionsdef.hpp index aeb4c8e1..051740e5 100644 --- a/src/engine/include/coincenteroptionsdef.hpp +++ b/src/engine/include/coincenteroptionsdef.hpp @@ -8,7 +8,6 @@ #include "apioutputtype.hpp" #include "cct_const.hpp" #include "commandlineoption.hpp" -#include "exchangeconfigmap.hpp" #include "exchangepublicapi.hpp" #include "loadconfiguration.hpp" #include "logginginfo.hpp" diff --git a/src/engine/include/exchangesorchestrator.hpp b/src/engine/include/exchangesorchestrator.hpp index 4ab28249..70facd0c 100644 --- a/src/engine/include/exchangesorchestrator.hpp +++ b/src/engine/include/exchangesorchestrator.hpp @@ -55,10 +55,10 @@ class ExchangesOrchestrator { const WithdrawsConstraints &withdrawsConstraints); MonetaryAmountPerExchange getConversion(MonetaryAmount amount, CurrencyCode targetCurrencyCode, - ExchangeNameSpan exchangeNames); + ExchangeNameEnumSpan exchangeNameEnums); MonetaryAmountPerExchange getConversion(std::span monetaryAmountPerExchangeToConvert, - CurrencyCode targetCurrencyCode, ExchangeNameSpan exchangeNames); + CurrencyCode targetCurrencyCode, ExchangeNameEnumSpan exchangeNameEnums); ConversionPathPerExchange getConversionPaths(Market mk, ExchangeNameSpan exchangeNames); @@ -103,11 +103,11 @@ class ExchangesOrchestrator { MarketTradeRangeStatsPerExchange traderConsumeRange(const ReplayOptions &replayOptions, TimeWindow subTimeWindow, std::span marketTraderEngines, - ExchangeNameSpan exchangeNames); + std::span exchangeNames); MarketTradingGlobalResultPerExchange getMarketTraderResultPerExchange( std::span marketTraderEngines, MarketTradeRangeStatsPerExchange &&tradeRangeStatsPerExchange, - ExchangeNameSpan exchangeNames); + std::span exchangeNames); private: ExchangeRetriever _exchangeRetriever; diff --git a/src/engine/include/queryresulttypes.hpp b/src/engine/include/queryresulttypes.hpp index 786ece5f..9f62eb8f 100644 --- a/src/engine/include/queryresulttypes.hpp +++ b/src/engine/include/queryresulttypes.hpp @@ -33,7 +33,7 @@ class Exchange; template using ExchangeWith = std::pair; -using MarketOrderBookConversionRate = std::tuple>; +using MarketOrderBookConversionRate = std::tuple>; using MarketOrderBookConversionRates = FixedCapacityVector; diff --git a/src/engine/src/coincenter-commands-processor.cpp b/src/engine/src/coincenter-commands-processor.cpp index 933cd9da..401e6b60 100644 --- a/src/engine/src/coincenter-commands-processor.cpp +++ b/src/engine/src/coincenter-commands-processor.cpp @@ -122,6 +122,7 @@ TransferableCommandResultVector CoincenterCommandsProcessor::processGroupedComma break; } case CoincenterCommandType::Conversion: { + ExchangeNameEnumVector exchangeNameEnumVector; if (firstCmd.amount().isDefault()) { std::array startAmountsPerExchangePos; bool oneSet = false; @@ -129,6 +130,7 @@ TransferableCommandResultVector CoincenterCommandsProcessor::processGroupedComma auto publicExchangePos = transferableResult.targetedExchange().publicExchangePos(); if (startAmountsPerExchangePos[publicExchangePos].isDefault()) { startAmountsPerExchangePos[publicExchangePos] = transferableResult.resultedAmount(); + exchangeNameEnumVector.push_back(static_cast(publicExchangePos)); oneSet = true; } else { throw invalid_argument( @@ -140,12 +142,12 @@ TransferableCommandResultVector CoincenterCommandsProcessor::processGroupedComma } const auto conversionPerExchange = - _coincenter.getConversion(startAmountsPerExchangePos, firstCmd.cur1(), firstCmd.exchangeNames()); + _coincenter.getConversion(startAmountsPerExchangePos, firstCmd.cur1(), exchangeNameEnumVector); _queryResultPrinter.printConversion(startAmountsPerExchangePos, firstCmd.cur1(), conversionPerExchange); FillConversionTransferableCommandResults(conversionPerExchange, transferableResults); } else { const auto conversionPerExchange = - _coincenter.getConversion(firstCmd.amount(), firstCmd.cur1(), firstCmd.exchangeNames()); + _coincenter.getConversion(firstCmd.amount(), firstCmd.cur1(), exchangeNameEnumVector); _queryResultPrinter.printConversion(firstCmd.amount(), firstCmd.cur1(), conversionPerExchange); FillConversionTransferableCommandResults(conversionPerExchange, transferableResults); } diff --git a/src/engine/src/coincenter.cpp b/src/engine/src/coincenter.cpp index 24f6f4fc..56df9bbc 100644 --- a/src/engine/src/coincenter.cpp +++ b/src/engine/src/coincenter.cpp @@ -92,7 +92,7 @@ MarketDataPerExchange Coincenter::queryMarketDataPerExchange(std::spanname(), + return std::make_tuple(exchangeWithPairOrderBooksAndTrades.first->exchangeNameEnum(), exchangeWithPairOrderBooksAndTrades.second.first, std::nullopt); }); @@ -160,13 +160,15 @@ TradedAmountsVectorWithFinalAmountPerExchange Coincenter::dustSweeper( } MonetaryAmountPerExchange Coincenter::getConversion(MonetaryAmount amount, CurrencyCode targetCurrencyCode, - ExchangeNameSpan exchangeNames) { - return _exchangesOrchestrator.getConversion(amount, targetCurrencyCode, exchangeNames); + ExchangeNameEnumSpan exchangeNameEnums) { + return _exchangesOrchestrator.getConversion(amount, targetCurrencyCode, exchangeNameEnums); } MonetaryAmountPerExchange Coincenter::getConversion(std::span monetaryAmountPerExchangeToConvert, - CurrencyCode targetCurrencyCode, ExchangeNameSpan exchangeNames) { - return _exchangesOrchestrator.getConversion(monetaryAmountPerExchangeToConvert, targetCurrencyCode, exchangeNames); + CurrencyCode targetCurrencyCode, + ExchangeNameEnumSpan exchangeNameEnums) { + return _exchangesOrchestrator.getConversion(monetaryAmountPerExchangeToConvert, targetCurrencyCode, + exchangeNameEnums); } ConversionPathPerExchange Coincenter::getConversionPaths(Market mk, ExchangeNameSpan exchangeNames) { @@ -247,10 +249,10 @@ MarketTimestampSetsPerExchange Coincenter::getMarketsAvailableForReplay(const Re namespace { auto CreateExchangeNameVector(Market market, const MarketTimestampSetsPerExchange &marketTimestampSetsPerExchange) { - PublicExchangeNameVector exchangesWithThisMarketData; + ExchangeNameEnumVector exchangesWithThisMarketData; for (const auto &[exchange, marketTimestampSets] : marketTimestampSetsPerExchange) { if (ContainsMarket(market, marketTimestampSets)) { - exchangesWithThisMarketData.emplace_back(exchange->name()); + exchangesWithThisMarketData.emplace_back(exchange->exchangeNameEnum()); } } return exchangesWithThisMarketData; @@ -339,7 +341,7 @@ ReplayResults Coincenter::replay(const AbstractMarketTraderFactory &marketTrader MarketTradingGlobalResultPerExchange Coincenter::replayAlgorithm( const AbstractMarketTraderFactory &marketTraderFactory, std::string_view algorithmName, const ReplayOptions &replayOptions, std::span marketTraderEngines, - const PublicExchangeNameVector &exchangesWithThisMarketData) { + const ExchangeNameEnumVector &exchangesWithThisMarketData) { CreateAndRegisterTraderAlgorithms(marketTraderFactory, algorithmName, marketTraderEngines); MarketTradeRangeStatsPerExchange tradeRangeStatsPerExchange = @@ -363,7 +365,7 @@ MonetaryAmount ComputeStartAmount(CurrencyCode currencyCode, MonetaryAmount conv } // namespace Coincenter::MarketTraderEngineVector Coincenter::createMarketTraderEngines( - const ReplayOptions &replayOptions, Market market, PublicExchangeNameVector &exchangesWithThisMarketData) { + const ReplayOptions &replayOptions, Market market, ExchangeNameEnumVector &exchangesWithThisMarketData) { const auto &automationConfig = _coincenterInfo.generalConfig().trading.automation; const auto startBaseAmountEquivalent = automationConfig.startingContext.startBaseAmountEquivalent; const auto startQuoteAmountEquivalent = automationConfig.startingContext.startQuoteAmountEquivalent; @@ -377,7 +379,7 @@ Coincenter::MarketTraderEngineVector Coincenter::createMarketTraderEngines( : getConversion(startQuoteAmountEquivalent, market.quote(), exchangesWithThisMarketData); MarketTraderEngineVector marketTraderEngines; - for (PublicExchangeNameVector::size_type exchangePos{}; exchangePos < exchangesWithThisMarketData.size(); + for (ExchangeNameEnumVector::size_type exchangePos{}; exchangePos < exchangesWithThisMarketData.size(); ++exchangePos) { const auto startBaseAmount = isValidateOnly ? MonetaryAmount{0, market.base()} @@ -388,7 +390,8 @@ Coincenter::MarketTraderEngineVector Coincenter::createMarketTraderEngines( if (!isValidateOnly && (startBaseAmount == 0 || startQuoteAmount == 0)) { log::warn("Cannot convert to start base / quote amounts for {} ({} / {})", - exchangesWithThisMarketData[exchangePos], startBaseAmount, startQuoteAmount); + kSupportedExchanges[static_cast(exchangesWithThisMarketData[exchangePos])], startBaseAmount, + startQuoteAmount); exchangesWithThisMarketData.erase(exchangesWithThisMarketData.begin() + exchangePos); convertedBaseAmountPerExchange.erase(convertedBaseAmountPerExchange.begin() + exchangePos); convertedQuoteAmountPerExchange.erase(convertedQuoteAmountPerExchange.begin() + exchangePos); @@ -396,17 +399,17 @@ Coincenter::MarketTraderEngineVector Coincenter::createMarketTraderEngines( continue; } - const ExchangeConfig &exchangeConfig = - _coincenterInfo.exchangeConfig(exchangesWithThisMarketData[exchangePos].name()); + const auto &exchangeConfig = + _coincenterInfo.exchangeConfig(kSupportedExchanges[static_cast(exchangesWithThisMarketData[exchangePos])]); marketTraderEngines.emplace_back(exchangeConfig, market, startBaseAmount, startQuoteAmount); } return marketTraderEngines; } -MarketTradeRangeStatsPerExchange Coincenter::tradingProcess(const ReplayOptions &replayOptions, - std::span marketTraderEngines, - ExchangeNameSpan exchangesWithThisMarketData) { +MarketTradeRangeStatsPerExchange Coincenter::tradingProcess( + const ReplayOptions &replayOptions, std::span marketTraderEngines, + std::span exchangesWithThisMarketData) { const auto &automationConfig = _coincenterInfo.generalConfig().trading.automation; const auto loadChunkDuration = automationConfig.deserialization.loadChunkDuration.duration; const auto timeWindow = replayOptions.timeWindow(); diff --git a/src/engine/src/exchangesorchestrator.cpp b/src/engine/src/exchangesorchestrator.cpp index ffd174c7..d331d77e 100644 --- a/src/engine/src/exchangesorchestrator.cpp +++ b/src/engine/src/exchangesorchestrator.cpp @@ -178,7 +178,7 @@ MarketOrderBookConversionRates ExchangesOrchestrator::getMarketOrderBooks(Market if (!optConversionRate && !equiCurrencyCode.isNeutral()) { log::warn("Unable to convert {} into {} on {}", mk.quote(), equiCurrencyCode, exchange->name()); } - return std::make_tuple(exchange->name(), exchange->getOrderBook(mk, actualDepth), optConversionRate); + return std::make_tuple(exchange->exchangeNameEnum(), exchange->getOrderBook(mk, actualDepth), optConversionRate); }; _threadPool.parallelTransform(selectedExchanges, ret.begin(), marketOrderBooksFunc); return ret; @@ -328,10 +328,10 @@ WithdrawsPerExchange ExchangesOrchestrator::getRecentWithdraws(ExchangeNameSpan } MonetaryAmountPerExchange ExchangesOrchestrator::getConversion(MonetaryAmount amount, CurrencyCode targetCurrencyCode, - ExchangeNameSpan exchangeNames) { + ExchangeNameEnumSpan exchangeNameEnums) { log::info("Query {} conversion into {} from {}", amount, targetCurrencyCode, - ConstructAccumulatedExchangeNames(exchangeNames)); - UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNames); + ConstructAccumulatedExchangeNames(exchangeNameEnums)); + UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNameEnums); MonetaryAmountPerExchange convertedAmountPerExchange(selectedExchanges.size()); _threadPool.parallelTransform( selectedExchanges, convertedAmountPerExchange.begin(), [amount, targetCurrencyCode](Exchange *exchange) { @@ -344,10 +344,10 @@ MonetaryAmountPerExchange ExchangesOrchestrator::getConversion(MonetaryAmount am MonetaryAmountPerExchange ExchangesOrchestrator::getConversion( std::span monetaryAmountPerExchangeToConvert, CurrencyCode targetCurrencyCode, - ExchangeNameSpan exchangeNames) { + ExchangeNameEnumSpan exchangeNameEnums) { log::info("Query multiple conversions into {} from {}", targetCurrencyCode, - ConstructAccumulatedExchangeNames(exchangeNames)); - UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNames); + ConstructAccumulatedExchangeNames(exchangeNameEnums)); + UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNameEnums); MonetaryAmountPerExchange convertedAmountPerExchange(selectedExchanges.size()); _threadPool.parallelTransform( selectedExchanges, convertedAmountPerExchange.begin(), @@ -1004,7 +1004,7 @@ MarketTimestampSetsPerExchange ExchangesOrchestrator::pullAvailableMarketsForRep MarketTradeRangeStatsPerExchange ExchangesOrchestrator::traderConsumeRange( const ReplayOptions &replayOptions, TimeWindow subTimeWindow, std::span marketTraderEngines, - ExchangeNameSpan exchangeNames) { + std::span exchangeNames) { UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNames); MarketTradeRangeStatsPerExchange tradeRangeResultsPerExchange(selectedExchanges.size()); @@ -1043,7 +1043,7 @@ MarketTradeRangeStatsPerExchange ExchangesOrchestrator::traderConsumeRange( MarketTradingGlobalResultPerExchange ExchangesOrchestrator::getMarketTraderResultPerExchange( std::span marketTraderEngines, MarketTradeRangeStatsPerExchange &&tradeRangeStatsPerExchange, - ExchangeNameSpan exchangeNames) { + std::span exchangeNames) { UniquePublicSelectedExchanges selectedExchanges = _exchangeRetriever.selectOneAccount(exchangeNames); if (selectedExchanges.size() != tradeRangeStatsPerExchange.size()) { diff --git a/src/engine/src/metricsexporter.cpp b/src/engine/src/metricsexporter.cpp index 45e47b56..a14e2db9 100644 --- a/src/engine/src/metricsexporter.cpp +++ b/src/engine/src/metricsexporter.cpp @@ -92,9 +92,9 @@ void MetricsExporter::exportOrderbookMetrics(const MarketOrderBookConversionRate RETURN_IF_NO_MONITORING; MetricKey key = CreateMetricKey("limit_pri", "Best bids and asks prices"); - for (const auto &[exchangeName, marketOrderBook, optConversionRate] : marketOrderBookConversionRates) { + for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBookConversionRates) { key.set("market", marketOrderBook.market().assetsPairStrLower('-')); - key.set("exchange", exchangeName); + key.set("exchange", kSupportedExchanges[static_cast(exchangeNameEnum)]); key.set("side", "ask"); _pMetricsGateway->add(MetricType::kGauge, MetricOperation::kSet, key, marketOrderBook.lowestAskPrice().toDouble()); key.set("side", "bid"); @@ -102,9 +102,9 @@ void MetricsExporter::exportOrderbookMetrics(const MarketOrderBookConversionRate } key.set(kMetricNameKey, "limit_vol"); key.set(kMetricHelpKey, "Best bids and asks volumes"); - for (const auto &[exchangeName, marketOrderBook, optConversionRate] : marketOrderBookConversionRates) { + for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBookConversionRates) { key.set("market", marketOrderBook.market().assetsPairStrLower('-')); - key.set("exchange", exchangeName); + key.set("exchange", kSupportedExchanges[static_cast(exchangeNameEnum)]); key.set("side", "ask"); _pMetricsGateway->add(MetricType::kGauge, MetricOperation::kSet, key, marketOrderBook.amountAtAskPrice().toDouble()); diff --git a/src/engine/src/queryresultprinter.cpp b/src/engine/src/queryresultprinter.cpp index 86e37a9a..ec62affb 100644 --- a/src/engine/src/queryresultprinter.cpp +++ b/src/engine/src/queryresultprinter.cpp @@ -227,7 +227,7 @@ json::container MarketOrderBooksJson(Market mk, CurrencyCode equiCurrencyCode, s in.emplace("opt", std::move(inOpt)); json::container out = json::container::object(); - for (const auto &[exchangeName, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { + for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { json::container marketOrderBookForExchange; json::container bidsForExchange; json::container asksForExchange; @@ -241,7 +241,7 @@ json::container MarketOrderBooksJson(Market mk, CurrencyCode equiCurrencyCode, s AppendOrderbookLine(marketOrderBook, askPos, optConversionRate, asksForExchange); } marketOrderBookForExchange.emplace("ask", std::move(asksForExchange)); - out.emplace(exchangeName, std::move(marketOrderBookForExchange)); + out.emplace(kSupportedExchanges[static_cast(exchangeNameEnum)], std::move(marketOrderBookForExchange)); } return ToJson(CoincenterCommandType::Orderbook, std::move(in), std::move(out)); @@ -1050,8 +1050,8 @@ void QueryResultPrinter::printMarketOrderBooks( const json::container jsonData = MarketOrderBooksJson(mk, equiCurrencyCode, depth, marketOrderBooksConversionRates); switch (_apiOutputType) { case ApiOutputType::table: { - for (const auto &[exchangeName, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { - printTable(marketOrderBook.getTable(exchangeName, optConversionRate)); + for (const auto &[exchangeNameEnum, marketOrderBook, optConversionRate] : marketOrderBooksConversionRates) { + printTable(marketOrderBook.getTable(exchangeNameEnum, optConversionRate)); } break; } diff --git a/src/engine/test/coincentercommandfactory_test.cpp b/src/engine/test/coincentercommandfactory_test.cpp index 1f0b629e..72002fca 100644 --- a/src/engine/test/coincentercommandfactory_test.cpp +++ b/src/engine/test/coincentercommandfactory_test.cpp @@ -60,10 +60,11 @@ TEST_F(CoincenterCommandFactoryTest, CreateMarketCommandMarketTest) { } TEST_F(CoincenterCommandFactoryTest, CreateMarketCommandSingleCurTest) { - EXPECT_EQ(CoincenterCommandFactory::CreateMarketCommand(inputStr("XLM,kraken,binance_user1")), - CoincenterCommand(CoincenterCommandType::Markets) - .setCur1("XLM") - .setExchangeNames(ExchangeNames({ExchangeName("kraken"), ExchangeName("binance", "user1")}))); + EXPECT_EQ( + CoincenterCommandFactory::CreateMarketCommand(inputStr("XLM,kraken,binance_user1")), + CoincenterCommand(CoincenterCommandType::Markets) + .setCur1("XLM") + .setExchangeNames(ExchangeNames({ExchangeName("kraken"), ExchangeName(ExchangeNameEnum::binance, "user1")}))); EXPECT_NO_THROW(optionParser.checkEndParsing()); } @@ -111,19 +112,20 @@ TEST_F(CoincenterCommandFactoryTest, CreateTradeAbsolute) { .setAmount(MonetaryAmount("13XRP")) .setPercentageAmount(false) .setCur1("BTC") - .setExchangeNames(ExchangeNames({ExchangeName("binance", "user2")}))); + .setExchangeNames(ExchangeNames({ExchangeName(ExchangeNameEnum::binance, "user2")}))); EXPECT_NO_THROW(optionParser.checkEndParsing()); } TEST_F(CoincenterCommandFactoryTest, CreateTradePercentage) { CoincenterCommandType type = CoincenterCommandType::Trade; - EXPECT_EQ(commandFactory.createTradeCommand(type, inputStr("67.906%eth-USDT,huobi,upbit_user1")), - CoincenterCommand(type) - .setTradeOptions(cmdLineOptions.computeTradeOptions()) - .setAmount(MonetaryAmount("67.906ETH")) - .setPercentageAmount(true) - .setCur1("USDT") - .setExchangeNames(ExchangeNames({ExchangeName("huobi"), ExchangeName("upbit", "user1")}))); + EXPECT_EQ( + commandFactory.createTradeCommand(type, inputStr("67.906%eth-USDT,huobi,upbit_user1")), + CoincenterCommand(type) + .setTradeOptions(cmdLineOptions.computeTradeOptions()) + .setAmount(MonetaryAmount("67.906ETH")) + .setPercentageAmount(true) + .setCur1("USDT") + .setExchangeNames(ExchangeNames({ExchangeName("huobi"), ExchangeName(ExchangeNameEnum::upbit, "user1")}))); EXPECT_NO_THROW(optionParser.checkEndParsing()); } @@ -182,7 +184,8 @@ TEST_F(CoincenterCommandFactoryTest, CreateWithdrawAbsoluteValid) { CoincenterCommand(CoincenterCommandType::Withdraw) .setWithdrawOptions(cmdLineOptions.computeWithdrawOptions()) .setAmount(MonetaryAmount("5000XRP")) - .setExchangeNames(ExchangeNames({ExchangeName("binance", "user1"), ExchangeName("kucoin", "user2")}))); + .setExchangeNames(ExchangeNames({ExchangeName(ExchangeNameEnum::binance, "user1"), + ExchangeName(ExchangeNameEnum::kucoin, "user2")}))); EXPECT_NO_THROW(optionParser.checkEndParsing()); } @@ -251,7 +254,7 @@ TEST_F(CoincenterCommandFactoryWithPreviousTest, CreateWithdrawWithPreviousValid EXPECT_EQ(commandFactory.createWithdrawApplyCommand(inputStr("kraken_user1")), CoincenterCommand(CoincenterCommandType::Withdraw) .setWithdrawOptions(cmdLineOptions.computeWithdrawOptions()) - .setExchangeNames(ExchangeNames({ExchangeName("kraken", "user1")}))); + .setExchangeNames(ExchangeNames({ExchangeName(ExchangeNameEnum::kraken, "user1")}))); EXPECT_NO_THROW(optionParser.checkEndParsing()); } diff --git a/src/engine/test/exchangesorchestrator_private_test.cpp b/src/engine/test/exchangesorchestrator_private_test.cpp index cb8c3431..d072d1d1 100644 --- a/src/engine/test/exchangesorchestrator_private_test.cpp +++ b/src/engine/test/exchangesorchestrator_private_test.cpp @@ -44,7 +44,7 @@ TEST_F(ExchangeOrchestratorTest, BalanceNoEquivalentCurrencyUniqueExchange) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(balanceOptions)) .WillOnce(testing::Return(balancePortfolio1)); - const ExchangeName privateExchangeNames[1] = {ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[1] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; BalancePerExchange ret{{&exchange1, balancePortfolio1}}; EXPECT_EQ(exchangesOrchestrator.getBalance(privateExchangeNames, balanceOptions), ret); } @@ -57,9 +57,9 @@ TEST_F(ExchangeOrchestratorTest, BalanceNoEquivalentCurrencySeveralExchanges) { EXPECT_CALL(ExchangePrivate(exchange4), queryAccountBalance(balanceOptions)) .WillOnce(testing::Return(balancePortfolio3)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange4.name(), exchange4.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; BalancePerExchange ret{ {&exchange1, balancePortfolio1}, {&exchange3, balancePortfolio2}, {&exchange4, balancePortfolio3}}; EXPECT_EQ(exchangesOrchestrator.getBalance(privateExchangeNames, balanceOptions), ret); @@ -68,7 +68,7 @@ TEST_F(ExchangeOrchestratorTest, BalanceNoEquivalentCurrencySeveralExchanges) { TEST_F(ExchangeOrchestratorTest, DepositInfoUniqueExchanges) { CurrencyCode depositCurrency{"ETH"}; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange2.name(), exchange2.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName())}; CurrencyExchangeFlatSet tradableCurrencies2{ CurrencyExchangeVector{CurrencyExchange(depositCurrency, CurrencyExchange::Deposit::kAvailable, @@ -88,9 +88,10 @@ TEST_F(ExchangeOrchestratorTest, DepositInfoUniqueExchanges) { TEST_F(ExchangeOrchestratorTest, DepositInfoSeveralExchangesWithUnavailableDeposits) { CurrencyCode depositCurrency{"XRP"}; - const ExchangeName privateExchangeNames[] = { - ExchangeName(exchange3.name(), exchange3.keyName()), ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName()), ExchangeName(exchange4.name(), exchange4.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; CurrencyExchangeFlatSet tradableCurrencies1{ CurrencyExchangeVector{CurrencyExchange(depositCurrency, CurrencyExchange::Deposit::kUnavailable, @@ -131,9 +132,9 @@ TEST_F(ExchangeOrchestratorTest, DepositInfoSeveralExchangesWithUnavailableDepos TEST_F(ExchangeOrchestratorTest, GetOpenedOrders) { OrdersConstraints noConstraints; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName()), - ExchangeName(exchange4.name(), exchange4.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; OpenedOrderVector openedOrders2{OpenedOrder("Id1", MonetaryAmount("0.1ETH"), MonetaryAmount("0.9ETH"), MonetaryAmount("0.14BTC"), Clock::now(), TradeSide::kBuy), @@ -158,7 +159,7 @@ TEST_F(ExchangeOrchestratorTest, GetOpenedOrders) { TEST_F(ExchangeOrchestratorTest, WithdrawSameAccountImpossible) { MonetaryAmount grossAmount{1000, "XRP"}; - ExchangeName fromExchange(exchange1.name(), exchange1.keyName()); + ExchangeName fromExchange(exchange1.exchangeNameEnum(), exchange1.keyName()); const ExchangeName &toExchange = fromExchange; EXPECT_THROW(exchangesOrchestrator.withdraw(grossAmount, false, fromExchange, toExchange, withdrawOptions), exception); @@ -166,8 +167,8 @@ TEST_F(ExchangeOrchestratorTest, WithdrawSameAccountImpossible) { TEST_F(ExchangeOrchestratorTest, WithdrawImpossibleFrom) { MonetaryAmount grossAmount{1000, "XRP"}; - ExchangeName fromExchange(exchange1.name(), exchange1.keyName()); - ExchangeName toExchange(exchange2.name(), exchange2.keyName()); + ExchangeName fromExchange(exchange1.exchangeNameEnum(), exchange1.keyName()); + ExchangeName toExchange(exchange2.exchangeNameEnum(), exchange2.keyName()); CurrencyExchangeFlatSet tradableCurrencies1{ CurrencyExchangeVector{CurrencyExchange(grossAmount.currencyCode(), CurrencyExchange::Deposit::kAvailable, @@ -189,8 +190,8 @@ TEST_F(ExchangeOrchestratorTest, WithdrawImpossibleFrom) { TEST_F(ExchangeOrchestratorTest, WithdrawImpossibleTo) { MonetaryAmount grossAmount{1000, "XRP"}; - ExchangeName fromExchange(exchange1.name(), exchange1.keyName()); - ExchangeName toExchange(exchange2.name(), exchange2.keyName()); + ExchangeName fromExchange(exchange1.exchangeNameEnum(), exchange1.keyName()); + ExchangeName toExchange(exchange2.exchangeNameEnum(), exchange2.keyName()); CurrencyExchangeFlatSet tradableCurrencies1{ CurrencyExchangeVector{CurrencyExchange(grossAmount.currencyCode(), CurrencyExchange::Deposit::kAvailable, @@ -272,8 +273,8 @@ class ExchangeOrchestratorWithdrawTest : public ExchangeOrchestratorTest { } CurrencyCode cur{"XRP"}; - ExchangeName fromExchange{exchange1.name(), exchange1.keyName()}; - ExchangeName toExchange{exchange2.name(), exchange2.keyName()}; + ExchangeName fromExchange{exchange1.exchangeNameEnum(), exchange1.keyName()}; + ExchangeName toExchange{exchange2.exchangeNameEnum(), exchange2.keyName()}; MonetaryAmount fee{"0.02", cur}; std::string_view withdrawId = "WithdrawId"; diff --git a/src/engine/test/exchangesorchestrator_public_test.cpp b/src/engine/test/exchangesorchestrator_public_test.cpp index 2ea3e78c..f00c1ad0 100644 --- a/src/engine/test/exchangesorchestrator_public_test.cpp +++ b/src/engine/test/exchangesorchestrator_public_test.cpp @@ -73,8 +73,9 @@ class ExchangeOrchestratorMarketOrderbookTest : public ExchangeOrchestratorTest const MarketSet markets3{m1, testedMarket, m3}; CurrencyCode equiCurrencyCode; std::optional optDepth; - MarketOrderBookConversionRates marketOrderBookConversionRates{{exchange1.name(), marketOrderBook20, std::nullopt}, - {exchange3.name(), marketOrderBook21, std::nullopt}}; + MarketOrderBookConversionRates marketOrderBookConversionRates{ + {exchange1.exchangeNameEnum(), marketOrderBook20, std::nullopt}, + {exchange3.exchangeNameEnum(), marketOrderBook21, std::nullopt}}; }; TEST_F(ExchangeOrchestratorMarketOrderbookTest, AllSpecifiedExchanges) { diff --git a/src/engine/test/exchangesorchestrator_trade_test.cpp b/src/engine/test/exchangesorchestrator_trade_test.cpp index cd47785b..4c266108 100644 --- a/src/engine/test/exchangesorchestrator_trade_test.cpp +++ b/src/engine/test/exchangesorchestrator_trade_test.cpp @@ -322,7 +322,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuy) { TradedAmounts tradedAmounts = expectSingleTrade(1, from, toCurrency, side, TradableMarkets::kExpectCall, OrderBook::kExpectCall, AllOrderBooks::kExpectNoCall, true); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; EXPECT_EQ(exchangesOrchestrator.trade(from, isPercentageTrade, toCurrency, privateExchangeNames, tradeOptions), TradeResultPerExchange(1, std::make_pair(&exchange1, TradeResult(tradedAmounts, from)))); @@ -333,8 +333,8 @@ TEST_F(ExchangeOrchestratorTradeTest, NoAvailableAmountToSell) { CurrencyCode toCurrency("EUR"); TradeSide side = TradeSide::kSell; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName())}; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(BalanceOptions())) .WillOnce(testing::Return(balancePortfolio1)); @@ -356,8 +356,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoAccountsSameExchangeSell) { CurrencyCode toCurrency("USDT"); TradeSide side = TradeSide::kSell; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange4.name(), exchange4.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; // 1.5ETH EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(BalanceOptions())) @@ -495,7 +495,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeBuyAll) { CurrencyCode toCurrency("XRP"); TradeSide side = TradeSide::kBuy; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); @@ -515,9 +515,9 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSellAll) { CurrencyCode toCurrency("EUR"); TradeSide side = TradeSide::kSell; - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName()), - ExchangeName(exchange3.name(), exchange3.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); @@ -543,9 +543,10 @@ TEST_F(ExchangeOrchestratorTradeTest, AllExchangesBuyAllOneMarketUnavailable) { CurrencyCode toCurrency("DOT"); TradeSide side = TradeSide::kBuy; - const ExchangeName privateExchangeNames[] = { - ExchangeName(exchange1.name(), exchange1.keyName()), ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName()), ExchangeName(exchange4.name(), exchange4.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName())}; EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); @@ -587,7 +588,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartBuy) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1))}; EXPECT_EQ(exchangesOrchestrator.smartBuy(endAmount, privateExchangeNames, tradeOptions), tradeResultPerExchange); @@ -607,7 +608,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartBuyTwoSteps) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1))}; EXPECT_EQ(exchangesOrchestrator.smartBuy(endAmount, privateExchangeNames, tradeOptions), tradeResultPerExchange); @@ -632,8 +633,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartBuy) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1)), std::make_pair(&exchange3, TradeResult(tradedAmounts31, from31)), @@ -657,8 +658,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartBuyNoMarketOnOneExchange) EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.name(), exchange3.keyName()), - ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange3, TradeResult(tradedAmounts3, from3))}; EXPECT_EQ(exchangesOrchestrator.smartBuy(endAmount, privateExchangeNames, tradeOptions), tradeResultPerExchange); @@ -692,9 +693,9 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesSmartBuy) { EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); EXPECT_CALL(ExchangePrivate(exchange4), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio4)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange4.name(), exchange4.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName()), - ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1)), std::make_pair(&exchange4, TradeResult(tradedAmounts4, from42))}; @@ -752,7 +753,7 @@ TEST_F(ExchangeOrchestratorTradeTest, SingleExchangeSmartSell) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1))}; EXPECT_EQ(exchangesOrchestrator.smartSell(startAmount, false, privateExchangeNames, tradeOptions), @@ -791,8 +792,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSell) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange2.name(), exchange2.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1)), std::make_pair(&exchange2, TradeResult(tradedAmounts2, from2))}; @@ -817,8 +818,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellPercentage) { EXPECT_CALL(ExchangePrivate(exchange1), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio1)); EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange3.name(), exchange3.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange1, TradeResult(tradedAmounts1, from1))}; EXPECT_EQ(tradeResultPerExchange, @@ -841,8 +842,8 @@ TEST_F(ExchangeOrchestratorTradeTest, TwoExchangesSmartSellNoMarketOnOneExchange EXPECT_CALL(ExchangePrivate(exchange2), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio2)); EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange2.name(), exchange2.keyName()), - ExchangeName(exchange3.name(), exchange3.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange2.exchangeNameEnum(), exchange2.keyName()), + ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange2, TradeResult(tradedAmounts2, from2))}; EXPECT_EQ(exchangesOrchestrator.smartSell(startAmount, false, privateExchangeNames, tradeOptions), @@ -869,9 +870,9 @@ TEST_F(ExchangeOrchestratorTradeTest, ThreeExchangesSmartSellFromAnotherPreferre EXPECT_CALL(ExchangePrivate(exchange3), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio3)); EXPECT_CALL(ExchangePrivate(exchange4), queryAccountBalance(testing::_)).WillOnce(testing::Return(balancePortfolio4)); - const ExchangeName privateExchangeNames[] = {ExchangeName(exchange4.name(), exchange4.keyName()), - ExchangeName(exchange1.name(), exchange1.keyName()), - ExchangeName(exchange3.name(), exchange3.keyName())}; + const ExchangeName privateExchangeNames[] = {ExchangeName(exchange4.exchangeNameEnum(), exchange4.keyName()), + ExchangeName(exchange1.exchangeNameEnum(), exchange1.keyName()), + ExchangeName(exchange3.exchangeNameEnum(), exchange3.keyName())}; TradeResultPerExchange tradeResultPerExchange{std::make_pair(&exchange3, TradeResult(tradedAmounts3, from3)), std::make_pair(&exchange4, TradeResult(tradedAmounts4, from4))}; diff --git a/src/engine/test/queryresultprinter_public_test.cpp b/src/engine/test/queryresultprinter_public_test.cpp index 24a20d8f..3f505ac0 100644 --- a/src/engine/test/queryresultprinter_public_test.cpp +++ b/src/engine/test/queryresultprinter_public_test.cpp @@ -489,33 +489,34 @@ class QueryResultPrinterMarketOrderBookTest : public QueryResultPrinterTest { int d = 3; MarketOrderBook mob{tp1, askPrice2, MonetaryAmount("0.12BTC"), bidPrice2, MonetaryAmount("0.00234 BTC"), volAndPriDec2, d}; - MarketOrderBookConversionRates marketOrderBookConversionRates{{"exchangeA", mob, {}}, {"exchangeD", mob, {}}}; + MarketOrderBookConversionRates marketOrderBookConversionRates{{ExchangeNameEnum::binance, mob, {}}, + {ExchangeNameEnum::huobi, mob, {}}}; }; TEST_F(QueryResultPrinterMarketOrderBookTest, FormattedTable) { basicQueryResultPrinter(ApiOutputType::table) .printMarketOrderBooks(mk, CurrencyCode{}, d, marketOrderBookConversionRates); static constexpr std::string_view kExpected = R"( -+-----------------------+----------------------------+----------------------+ -| Sellers of BTC (asks) | exchangeA BTC price in EUR | Buyers of BTC (bids) | -+-----------------------+----------------------------+----------------------+ -| 0.18116 | 31056.7 | | -| 0.15058 | 31056.68 | | -| 0.12 | 31056.67 | | -| | 31056.66 | 0.00234 | -| | 31056.65 | 0.03292 | -| | 31056.63 | 0.0635 | -+-----------------------+----------------------------+----------------------+ -+-----------------------+----------------------------+----------------------+ -| Sellers of BTC (asks) | exchangeD BTC price in EUR | Buyers of BTC (bids) | -+-----------------------+----------------------------+----------------------+ -| 0.18116 | 31056.7 | | -| 0.15058 | 31056.68 | | -| 0.12 | 31056.67 | | -| | 31056.66 | 0.00234 | -| | 31056.65 | 0.03292 | -| | 31056.63 | 0.0635 | -+-----------------------+----------------------------+----------------------+ ++-----------------------+--------------------------+----------------------+ +| Sellers of BTC (asks) | binance BTC price in EUR | Buyers of BTC (bids) | ++-----------------------+--------------------------+----------------------+ +| 0.18116 | 31056.7 | | +| 0.15058 | 31056.68 | | +| 0.12 | 31056.67 | | +| | 31056.66 | 0.00234 | +| | 31056.65 | 0.03292 | +| | 31056.63 | 0.0635 | ++-----------------------+--------------------------+----------------------+ ++-----------------------+------------------------+----------------------+ +| Sellers of BTC (asks) | huobi BTC price in EUR | Buyers of BTC (bids) | ++-----------------------+------------------------+----------------------+ +| 0.18116 | 31056.7 | | +| 0.15058 | 31056.68 | | +| 0.12 | 31056.67 | | +| | 31056.66 | 0.00234 | +| | 31056.65 | 0.03292 | +| | 31056.63 | 0.0635 | ++-----------------------+------------------------+----------------------+ )"; expectStr(kExpected); } diff --git a/src/engine/test/stringoptionparser_test.cpp b/src/engine/test/stringoptionparser_test.cpp index 4059145b..7746e8a6 100644 --- a/src/engine/test/stringoptionparser_test.cpp +++ b/src/engine/test/stringoptionparser_test.cpp @@ -24,15 +24,16 @@ constexpr auto mandatory = StringOptionParser::FieldIs::kMandatory; TEST(StringOptionParserTest, ParseExchangesDefaultSeparator) { EXPECT_TRUE(StringOptionParser("").parseExchanges().empty()); EXPECT_EQ(StringOptionParser("kraken,upbit").parseExchanges(), - ExchangeNames({ExchangeName("kraken"), ExchangeName("upbit")})); + ExchangeNames({ExchangeName(ExchangeNameEnum::kraken), ExchangeName(ExchangeNameEnum::upbit)})); EXPECT_EQ(StringOptionParser("huobi_user1").parseExchanges(), ExchangeNames({ExchangeName("huobi_user1")})); } TEST(StringOptionParserTest, ParseExchangesCustomSeparator) { EXPECT_TRUE(StringOptionParser("").parseExchanges('-').empty()); EXPECT_EQ(StringOptionParser("kucoin-huobi_user1").parseExchanges('-'), - ExchangeNames({ExchangeName("kucoin"), ExchangeName("huobi", "user1")})); - EXPECT_EQ(StringOptionParser("kraken_user2").parseExchanges('-'), ExchangeNames({ExchangeName("kraken", "user2")})); + ExchangeNames({ExchangeName(ExchangeNameEnum::kucoin), ExchangeName(ExchangeNameEnum::huobi, "user1")})); + EXPECT_EQ(StringOptionParser("kraken_user2").parseExchanges('-'), + ExchangeNames({ExchangeName(ExchangeNameEnum::kraken, "user2")})); } TEST(StringOptionParserTest, ParseMarketMandatory) { @@ -145,7 +146,8 @@ TEST(StringOptionParserTest, AmountExchangesFlow) { EXPECT_EQ(parser.parseNonZeroAmount(StringOptionParser::FieldIs::kOptional), std::make_pair(MonetaryAmount(), StringOptionParser::AmountType::kNotPresent)); - EXPECT_EQ(parser.parseExchanges(','), ExchangeNames({ExchangeName("kraken"), ExchangeName("huobi", "long_user1")})); + EXPECT_EQ(parser.parseExchanges(','), ExchangeNames({ExchangeName(ExchangeNameEnum::kraken), + ExchangeName(ExchangeNameEnum::huobi, "long_user1")})); EXPECT_NO_THROW(parser.checkEndParsing()); } @@ -175,7 +177,8 @@ TEST(StringOptionParserTest, AmountCurrencyWithExchangesFlow) { std::make_pair(MonetaryAmount(), StringOptionParser::AmountType::kNotPresent)); EXPECT_EQ(parser.parseCurrency(StringOptionParser::FieldIs::kMandatory), CurrencyCode("USDT")); - EXPECT_EQ(parser.parseExchanges(','), ExchangeNames({ExchangeName("binance", "long_user2"), ExchangeName("kucoin")})); + EXPECT_EQ(parser.parseExchanges(','), ExchangeNames({ExchangeName(ExchangeNameEnum::binance, "long_user2"), + ExchangeName(ExchangeNameEnum::kucoin)})); EXPECT_NO_THROW(parser.checkEndParsing()); } @@ -191,7 +194,8 @@ TEST(StringOptionParserTest, SeveralAmountCurrencyExchangesFlow) { EXPECT_EQ(parser.parseCurrency(StringOptionParser::FieldIs::kOptional), CurrencyCode("HYDRA")); EXPECT_EQ(parser.parseCurrency(StringOptionParser::FieldIs::kOptional), CurrencyCode()); - EXPECT_EQ(parser.parseExchanges('-'), ExchangeNames({ExchangeName("binance"), ExchangeName("kraken")})); + EXPECT_EQ(parser.parseExchanges('-'), + ExchangeNames({ExchangeName(ExchangeNameEnum::binance), ExchangeName(ExchangeNameEnum::kraken)})); EXPECT_NO_THROW(parser.checkEndParsing()); } @@ -207,7 +211,8 @@ TEST(StringOptionParserTest, ExchangesNotLast) { EXPECT_EQ(parser.parseCurrency(StringOptionParser::FieldIs::kOptional), CurrencyCode()); EXPECT_EQ(parser.parseExchanges('-', ','), - ExchangeNames({ExchangeName("kucoin", "user1"), ExchangeName("binance"), ExchangeName("kraken")})); + ExchangeNames({ExchangeName(ExchangeNameEnum::kucoin, "user1"), ExchangeName(ExchangeNameEnum::binance), + ExchangeName(ExchangeNameEnum::kraken)})); EXPECT_EQ(parser.parseCurrency(StringOptionParser::FieldIs::kMandatory), CurrencyCode("KRW")); EXPECT_NO_THROW(parser.checkEndParsing()); @@ -218,7 +223,8 @@ TEST(StringOptionParserTest, ParseDurationMandatory) { EXPECT_EQ(parser.parseDuration(StringOptionParser::FieldIs::kMandatory), std::chrono::minutes{45} + std::chrono::seconds{83}); - EXPECT_EQ(parser.parseExchanges(',', '\0'), ExchangeNames({ExchangeName("kraken"), ExchangeName("upbit")})); + EXPECT_EQ(parser.parseExchanges(',', '\0'), + ExchangeNames({ExchangeName(ExchangeNameEnum::kraken), ExchangeName(ExchangeNameEnum::upbit)})); EXPECT_NO_THROW(parser.checkEndParsing()); } @@ -227,7 +233,8 @@ TEST(StringOptionParserTest, ParseDurationOptional) { StringOptionParser parser("binance,huobi_user1,34h 4500ms"); EXPECT_EQ(parser.parseDuration(StringOptionParser::FieldIs::kOptional), kUndefinedDuration); - EXPECT_EQ(parser.parseExchanges(',', '\0'), ExchangeNames({ExchangeName("binance"), ExchangeName("huobi", "user1")})); + EXPECT_EQ(parser.parseExchanges(',', '\0'), + ExchangeNames({ExchangeName(ExchangeNameEnum::binance), ExchangeName(ExchangeNameEnum::huobi, "user1")})); EXPECT_EQ(parser.parseDuration(StringOptionParser::FieldIs::kOptional), std::chrono::hours{34} + std::chrono::milliseconds{4500}); diff --git a/src/engine/test/transferablecommandresult_test.cpp b/src/engine/test/transferablecommandresult_test.cpp index e3d551be..048fe5ab 100644 --- a/src/engine/test/transferablecommandresult_test.cpp +++ b/src/engine/test/transferablecommandresult_test.cpp @@ -24,11 +24,11 @@ class TransferableCommandResultTest : public ::testing::Test { return cmd; } - ExchangeName exchangeName11{"binance", "user1"}; - ExchangeName exchangeName12{"binance", "user2"}; + ExchangeName exchangeName11{ExchangeNameEnum::binance, "user1"}; + ExchangeName exchangeName12{ExchangeNameEnum::binance, "user2"}; - ExchangeName exchangeName21{"kraken", "user1"}; - ExchangeName exchangeName22{"kraken", "user2"}; + ExchangeName exchangeName21{ExchangeNameEnum::kraken, "user1"}; + ExchangeName exchangeName22{ExchangeNameEnum::kraken, "user2"}; MonetaryAmount amount11{50, "DOGE"}; MonetaryAmount amount12{10, "DOGE"}; diff --git a/src/objects/include/exchange-names.hpp b/src/objects/include/exchange-names.hpp index b9850579..0211ca43 100644 --- a/src/objects/include/exchange-names.hpp +++ b/src/objects/include/exchange-names.hpp @@ -11,10 +11,13 @@ namespace cct { using ExchangeNameSpan = std::span; +using ExchangeNameEnumSpan = std::span; using ExchangeNames = SmallVector; -using PublicExchangeNameVector = FixedCapacityVector; +using ExchangeNameEnumVector = FixedCapacityVector; string ConstructAccumulatedExchangeNames(ExchangeNameSpan exchangeNames); +string ConstructAccumulatedExchangeNames(ExchangeNameEnumSpan exchangeNames); + } // namespace cct \ No newline at end of file diff --git a/src/objects/include/exchangename.hpp b/src/objects/include/exchangename.hpp index f5af5024..623dc2cb 100644 --- a/src/objects/include/exchangename.hpp +++ b/src/objects/include/exchangename.hpp @@ -36,7 +36,7 @@ class ExchangeName { /// first '_' that is important. explicit ExchangeName(std::string_view globalExchangeName); - ExchangeName(std::string_view exchangeName, std::string_view keyName); + explicit ExchangeName(ExchangeNameEnum exchangeNameEnum, std::string_view keyName = {}); std::string_view name() const { const auto underscore = underscorePos(); @@ -51,6 +51,8 @@ class ExchangeName { auto publicExchangePos() const { return PublicExchangePos(name()); } + ExchangeNameEnum exchangeNameEnum() const { return static_cast(publicExchangePos()); } + bool isKeyNameDefined() const { return underscorePos() != string::npos; } std::string_view str() const { return _nameWithKey; } diff --git a/src/objects/include/marketorderbook.hpp b/src/objects/include/marketorderbook.hpp index 7d74f5aa..4a65acc6 100644 --- a/src/objects/include/marketorderbook.hpp +++ b/src/objects/include/marketorderbook.hpp @@ -5,6 +5,7 @@ #include #include "amount-price.hpp" +#include "cct_const.hpp" #include "cct_smallvector.hpp" #include "market.hpp" #include "monetaryamount.hpp" @@ -145,7 +146,7 @@ class MarketOrderBook { /// Print the market order book in a SimpleTable and returns it. /// @param conversionPriceRate prices will be multiplied to given amount to display an additional column of equivalent /// currency - SimpleTable getTable(std::string_view exchangeName, std::optional conversionPriceRate) const; + SimpleTable getTable(ExchangeNameEnum exchangeNameEnum, std::optional conversionPriceRate) const; private: using AmountType = MonetaryAmount::AmountType; diff --git a/src/objects/src/exchange-names.cpp b/src/objects/src/exchange-names.cpp index 8365cfa4..3d757c5e 100644 --- a/src/objects/src/exchange-names.cpp +++ b/src/objects/src/exchange-names.cpp @@ -16,4 +16,16 @@ string ConstructAccumulatedExchangeNames(ExchangeNameSpan exchangeNames) { return exchangesStr; } +string ConstructAccumulatedExchangeNames(ExchangeNameEnumSpan exchangeNames) { + // TODO: Use C++23 join_with feature + string exchangesStr(exchangeNames.empty() ? "all" : ""); + for (const auto &exchangeName : exchangeNames) { + if (!exchangesStr.empty()) { + exchangesStr.push_back(','); + } + exchangesStr.append(kSupportedExchanges[static_cast(exchangeName)]); + } + return exchangesStr; +} + } // namespace cct \ No newline at end of file diff --git a/src/objects/src/exchangename.cpp b/src/objects/src/exchangename.cpp index e761fa4e..90a61b48 100644 --- a/src/objects/src/exchangename.cpp +++ b/src/objects/src/exchangename.cpp @@ -44,13 +44,8 @@ ExchangeName::ExchangeName(std::string_view globalExchangeName) : _nameWithKey(g } } -ExchangeName::ExchangeName(std::string_view exchangeName, std::string_view keyName) - : _nameWithKey(ToLower(exchangeName)) { - if (std::ranges::find_if(kSupportedExchanges, [this](const auto exchangeStr) { - return exchangeStr == this->_nameWithKey; - }) == std::end(kSupportedExchanges)) { - throw invalid_argument("Invalid exchange name '{}'", exchangeName); - } +ExchangeName::ExchangeName(ExchangeNameEnum exchangeNameEnum, std::string_view keyName) + : _nameWithKey(kSupportedExchanges[static_cast(exchangeNameEnum)]) { if (!keyName.empty()) { _nameWithKey.push_back('_'); _nameWithKey.append(keyName); diff --git a/src/objects/src/marketorderbook.cpp b/src/objects/src/marketorderbook.cpp index 8bdc6959..5c359edc 100644 --- a/src/objects/src/marketorderbook.cpp +++ b/src/objects/src/marketorderbook.cpp @@ -728,11 +728,12 @@ std::optional MarketOrderBook::computeAvgPrice(MonetaryAmount fr } } -SimpleTable MarketOrderBook::getTable(std::string_view exchangeName, +SimpleTable MarketOrderBook::getTable(ExchangeNameEnum exchangeNameEnum, std::optional conversionPriceRate) const { string h1("Sellers of "); string baseStr = _market.base().str(); h1.append(baseStr).append(" (asks)"); + std::string_view exchangeName = kSupportedExchanges[static_cast(exchangeNameEnum)]; string h2(exchangeName); h2.append(" ").append(baseStr).append(" price in "); _market.quote().appendStrTo(h2); diff --git a/src/objects/test/exchangename_test.cpp b/src/objects/test/exchangename_test.cpp index c714313a..69691e5d 100644 --- a/src/objects/test/exchangename_test.cpp +++ b/src/objects/test/exchangename_test.cpp @@ -42,27 +42,26 @@ TEST(ExchangeName, ConstructorWith1ParamInvalid) { } TEST(ExchangeName, ConstructorWith2ParamsValid) { - EXPECT_EQ(ExchangeName("upbit", "user1").str(), "upbit_user1"); - EXPECT_EQ(ExchangeName("binance", "_user13").str(), "binance__user13"); + EXPECT_EQ(ExchangeName(ExchangeNameEnum::upbit, "user1").str(), "upbit_user1"); + EXPECT_EQ(ExchangeName(ExchangeNameEnum::binance, "_user13").str(), "binance__user13"); } TEST(ExchangeName, ConstructorWith2ParamsInvalid) { - EXPECT_THROW(ExchangeName("kraken_", "_user13"), invalid_argument); - EXPECT_THROW(ExchangeName("unknown", "user1"), invalid_argument); + EXPECT_THROW(ExchangeName(ExchangeNameEnum::kraken, "_user13"), invalid_argument); } TEST(ExchangeName, IsKeyNameDefined) { - EXPECT_TRUE(ExchangeName("binance", "_user13").isKeyNameDefined()); - EXPECT_FALSE(ExchangeName("binance", "").isKeyNameDefined()); + EXPECT_TRUE(ExchangeName(ExchangeNameEnum::binance, "_user13").isKeyNameDefined()); + EXPECT_FALSE(ExchangeName(ExchangeNameEnum::binance, "").isKeyNameDefined()); EXPECT_TRUE(ExchangeName("upbit__thisisaTrap_").isKeyNameDefined()); EXPECT_FALSE(ExchangeName("kraken").isKeyNameDefined()); } TEST(ExchangeName, Equality) { - EXPECT_EQ(ExchangeName("binance", "_user13"), ExchangeName("BinanCE", "_user13")); - EXPECT_NE(ExchangeName("kucoin", "_user13"), ExchangeName("huobi", "_user13")); - EXPECT_NE(ExchangeName("binance", "_user13"), ExchangeName("binance", "_uSer13")); - EXPECT_NE(ExchangeName("upbit", "_user13"), ExchangeName("binance", "_user13")); + EXPECT_EQ(ExchangeName(ExchangeNameEnum::binance, "_user13"), ExchangeName(ExchangeNameEnum::binance, "_user13")); + EXPECT_NE(ExchangeName(ExchangeNameEnum::kucoin, "_user13"), ExchangeName(ExchangeNameEnum::huobi, "_user13")); + EXPECT_NE(ExchangeName(ExchangeNameEnum::binance, "_user13"), ExchangeName(ExchangeNameEnum::binance, "_uSer13")); + EXPECT_NE(ExchangeName(ExchangeNameEnum::upbit, "_user13"), ExchangeName(ExchangeNameEnum::binance, "_user13")); } TEST(ExchangeName, FormatWithoutKey) { diff --git a/src/objects/test/wallet_test.cpp b/src/objects/test/wallet_test.cpp index 54427f22..4aa721eb 100644 --- a/src/objects/test/wallet_test.cpp +++ b/src/objects/test/wallet_test.cpp @@ -17,7 +17,7 @@ class WalletTest : public ::testing::Test { }; TEST_F(WalletTest, NoDestinationTag) { - Wallet wallet(ExchangeName("kraken", "user1"), "ETH", "MyAddress", "", walletCheck, + Wallet wallet(ExchangeName(ExchangeNameEnum::kraken, "user1"), "ETH", "MyAddress", "", walletCheck, AccountOwner("SmithJohn", "스미스존")); EXPECT_EQ(wallet.address(), "MyAddress"); EXPECT_FALSE(wallet.hasTag()); @@ -26,8 +26,8 @@ TEST_F(WalletTest, NoDestinationTag) { } TEST_F(WalletTest, DestinationTag1) { - Wallet wallet(ExchangeName("kraken", "user1"), "ETH", "023432423423xxxx54645654", "346723423", walletCheck, - AccountOwner("SmithJohn", "스미스존")); + Wallet wallet(ExchangeName(ExchangeNameEnum::kraken, "user1"), "ETH", "023432423423xxxx54645654", "346723423", + walletCheck, AccountOwner("SmithJohn", "스미스존")); EXPECT_EQ(wallet.address(), "023432423423xxxx54645654"); EXPECT_TRUE(wallet.hasTag()); EXPECT_EQ(wallet.tag(), "346723423"); @@ -35,7 +35,7 @@ TEST_F(WalletTest, DestinationTag1) { TEST_F(WalletTest, DestinationTag2) { string address("023432423423xxxx5464565sd234657dsfsdfnnMMSERwedfsas"); - Wallet wallet(ExchangeName("kraken", "user1"), "XRP", std::move(address), "superTAG4576", walletCheck, + Wallet wallet(ExchangeName(ExchangeNameEnum::kraken, "user1"), "XRP", std::move(address), "superTAG4576", walletCheck, AccountOwner("SmithJohn", "스미스존")); EXPECT_EQ(wallet.address(), "023432423423xxxx5464565sd234657dsfsdfnnMMSERwedfsas"); EXPECT_TRUE(wallet.hasTag());