From abea1f9aa04611d2858394e12503b6a43eef7e25 Mon Sep 17 00:00:00 2001 From: Stephane Janel Date: Sun, 17 Mar 2024 16:06:06 +0100 Subject: [PATCH] [Code cleaning] - Create PublicTradeVector and MarketOrderBookVector --- CONFIG.md | 34 +++++------ README.md | 24 ++++---- src/api-objects/include/apikey.hpp | 5 +- .../include/exchangepublicapitypes.hpp | 12 ++-- src/api-objects/include/recentdeposit.hpp | 2 +- src/api-objects/include/withdrawinfo.hpp | 9 ++- src/api/common/include/exchangepublicapi.hpp | 3 +- .../common/include/exchangepublicapi_mock.hpp | 3 +- src/api/common/src/exchangeprivateapi.cpp | 16 ++--- .../exchanges/include/binancepublicapi.hpp | 3 +- .../exchanges/include/bithumbprivateapi.hpp | 8 +-- .../exchanges/include/bithumbpublicapi.hpp | 3 +- src/api/exchanges/include/huobipublicapi.hpp | 3 +- src/api/exchanges/include/krakenpublicapi.hpp | 3 +- src/api/exchanges/include/kucoinpublicapi.hpp | 3 +- src/api/exchanges/include/upbitpublicapi.hpp | 3 +- src/api/exchanges/src/binanceprivateapi.cpp | 1 + src/api/exchanges/src/binancepublicapi.cpp | 9 +-- src/api/exchanges/src/bithumbpublicapi.cpp | 5 +- src/api/exchanges/src/huobipublicapi.cpp | 5 +- src/api/exchanges/src/krakenpublicapi.cpp | 5 +- src/api/exchanges/src/kucoinpublicapi.cpp | 7 ++- src/api/exchanges/src/upbitprivateapi.cpp | 1 + src/api/exchanges/src/upbitpublicapi.cpp | 7 ++- .../exchanges/test/exchangecommonapi_test.hpp | 3 +- src/api/interface/include/exchange.hpp | 10 ++-- src/api/interface/src/exchange.cpp | 11 +++- src/engine/include/coincentercommand.hpp | 30 ++++------ src/engine/include/coincenteroptions.hpp | 3 +- src/engine/include/coincenteroptionsdef.hpp | 41 +++++++------ src/engine/include/queryresultprinter.hpp | 3 +- src/engine/include/queryresulttypes.hpp | 3 +- src/engine/src/coincenter.cpp | 11 ++-- src/engine/src/coincentercommand.cpp | 59 +++---------------- src/engine/src/coincentercommandfactory.cpp | 4 +- src/engine/src/coincentercommands.cpp | 4 +- src/engine/src/queryresultprinter.cpp | 43 ++++++++------ src/engine/src/stringoptionparser.cpp | 10 +++- .../test/coincentercommandfactory_test.cpp | 3 +- src/engine/test/coincenteroptions_test.cpp | 2 +- .../test/queryresultprinter_public_test.cpp | 45 ++++++++------ src/http-request/include/curlhandle.hpp | 2 +- src/objects/include/generalconfigdefault.hpp | 4 +- .../include/market-order-book-vector.hpp | 10 ++++ src/objects/include/market-vector.hpp | 10 ++++ src/objects/include/marketorderbook.hpp | 2 +- src/objects/include/order-book-line.hpp | 5 ++ src/objects/include/public-trade-vector.hpp | 10 ++++ .../include/publictrade.hpp | 0 .../src/publictrade.cpp | 0 src/objects/test/marketorderbook_test.cpp | 1 + src/tech/src/durationstring.cpp | 51 ++++++++-------- src/tech/src/timestring.cpp | 3 +- src/tech/test/timestring_test.cpp | 2 +- 54 files changed, 297 insertions(+), 262 deletions(-) create mode 100644 src/objects/include/market-order-book-vector.hpp create mode 100644 src/objects/include/market-vector.hpp create mode 100644 src/objects/include/public-trade-vector.hpp rename src/{api-objects => objects}/include/publictrade.hpp (100%) rename src/{api-objects => objects}/src/publictrade.cpp (100%) diff --git a/CONFIG.md b/CONFIG.md index efba43e0..873fc5d1 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -1,5 +1,4 @@ -Configuration -============= +# Configuration At this step, `coincenter` is built. To execute properly, it needs read/write access to a special directory `data` which contains a tree of files as follows: @@ -14,9 +13,9 @@ This directory is set according to these rules, by decreasing priority: - or from `CCT_DATA_DIR` environment variable if it is set at runtime - or defaults to the default data directory chosen at build time from `CCT_DATA_DIR` environment variable -# Important files +## Important files -## secret/secret.json +### secret/secret.json Fill this file with your private keys for each of your account(s) in the exchanges. Of course, no need to say that this file should be kept secret, and not transit in the internet, or any other *Docker* image/layer or *git* commit. @@ -26,13 +25,13 @@ For additional security, always bind your keys to your IP (some exchanges will f [data/secret/secret_test.json](data/secret/secret_test.json) shows the syntax. -### Additional information +#### Additional information -#### Kucoin +##### Kucoin In addition of the `key` and `private` values, you will need to provide your `passphrase` as well. It's provided as a string field along with your key in the `secret.json` file. -#### Bithumb +##### Bithumb Bithumb **withdrawals** have an extra personal information check: they need to know the **English** and **Korean** name of the owner of the destination account. Thus it's also an information that you need to provide in the keys of your targeted accounts for a Bithumb withdrawal. @@ -41,13 +40,13 @@ Korean name should be provided with the `accountOwner.koName` field in the key o Refer to the [data/secret/secret_test.json](data/secret/secret_test.json) example file in case of doubt. -## static/generalconfig.json +### static/generalconfig.json Contains options that are not exchange specific. Configures the logging, tracking activity of relevant commands, and console output type. -### Options description +#### General options description | Name | Value | Description | | ---------------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -61,10 +60,10 @@ Configures the logging, tracking activity of relevant commands, and console outp | **log.maxNbFiles** | Integer | Number of maximum rotating files for log in files | | **requests.concurrency.nbMaxParallelRequests** | Integer | Size of the thread pool that makes exchange requests. | - -## static/exchangeconfig.json +### static/exchangeconfig.json This json file should follow this specific format: + ```yaml - top_level_option: - default: @@ -79,6 +78,7 @@ This json file should follow this specific format: ``` Currently, options are set from two ways: + - **Comma separated values** are aggregated for each exchange with the 'default' values (if present) - **Single values** are retrieved in a 'bottom first' priority model, meaning that if a value is specified for an exchange name, it is chosen. Otherwise, it checks at the default value for this option, and if again not present, uses a hardcoded default one (cf in the code). @@ -122,7 +122,7 @@ The chosen values will be: Refer to the hardcoded default json example as a model in case of doubt. -### Options description +#### Exchanges options description | Module | Name | Value | Description | | ----------- | ---------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -156,10 +156,8 @@ Refer to the hardcoded default json example as a model in case of doubt. | *tradefees* | **taker** | String as decimal number representing a percentage (for instance, "0.15") | Trade fees occurring when a taker order is matched | | *withdraw* | **validateDepositAddressesInFile** | Boolean (`true` or `false`) | If `true`, each withdraw will perform an additional validation check from a trusted list of "whitelisted" addresses in `depositaddresses.json` file. Withdraw will not be processed if destination wallet is not present in the file. | -#### Notes - - `updateFrequency` is itself a json document containing all duration values as query frequencies. - See [ExchangeConfig default file](src/objects/src/exchangeconfigdefault.hpp) as an example for the syntax. - - Unused and not explicitly set values (so, when loaded from default values) from your personal `exchangeconfig.json` file will be logged for information about what will actually be used by `coincenter`. - - +##### Notes +- `updateFrequency` is itself a json document containing all duration values as query frequencies. + See [ExchangeConfig default file](src/objects/src/exchangeconfigdefault.hpp) as an example for the syntax. +- Unused and not explicitly set values (so, when loaded from default values) from your personal `exchangeconfig.json` file will be logged for information about what will actually be used by `coincenter`. diff --git a/README.md b/README.md index de42d014..9cce03c7 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Main features: - Last trades - Withdraw fees -## Private requests +## Account requests - Balance - Trade (buy & sell in several flavors) @@ -55,7 +55,7 @@ Main features: - [coincenter](#coincenter) - [Market Data](#market-data) - - [Private requests](#private-requests) + - [Account requests](#account-requests) - [Supported exchanges](#supported-exchanges) - [About](#about) - [Installation](#installation) @@ -76,7 +76,7 @@ Main features: - [Currencies](#currencies) - [Examples](#examples) - [Markets](#markets) - - [Examples](#examples-1) + - [Examples of markets queries](#examples-of-markets-queries) - [Ticker information](#ticker-information) - [Order books](#order-books) - [Last 24h traded volume](#last-24h-traded-volume) @@ -90,7 +90,7 @@ Main features: - [Withdraw fees](#withdraw-fees) - [Example 1: query all withdraw fees](#example-1-query-all-withdraw-fees) - [Example 2: query ETH withdraw fees on Kraken and Kucoin](#example-2-query-eth-withdraw-fees-on-kraken-and-kucoin) - - [Private requests](#private-requests-1) + - [Private requests](#private-requests) - [Selecting private keys on exchanges](#selecting-private-keys-on-exchanges) - [Balance](#balance) - [Trade](#trade) @@ -114,9 +114,9 @@ Main features: - [Examples with explanation](#examples-with-explanation-1) - [Deposit information](#deposit-information) - [Recent deposits](#recent-deposits) - - [Examples](#examples-2) + - [Examples](#examples-1) - [Recent withdraws](#recent-withdraws) - - [Examples](#examples-3) + - [Examples](#examples-2) - [Closed orders](#closed-orders) - [Opened orders](#opened-orders) - [Cancel opened orders](#cancel-opened-orders) @@ -251,7 +251,7 @@ This allows to flush correctly the latest data (caches, logs, etc) to files at t By default, it logs in the console with the 'info' level, and in 'debug' in rotating files. -For this, you can configure statically the default level for each in the [config file](CONFIG.md#options-description). +For this, you can configure statically the default level for each in the [config file](CONFIG.md#general-options-description). It can be overridden on the command line, with options `--log ` and `--log-file `. ##### Activity history @@ -268,7 +268,7 @@ By default, it stores all types of trades and withdraws results, but the list is ### Parallel requests You may want to query several exchanges for a command at the same time. In this case, it's possible to ask `coincenter` to launch requests in parallel when it's possible. -By default, the number of requests in parallel is `1`. To increase it, change the value of the field `nbMaxParallelRequests` in `generalconfig.json` file (more information [here](CONFIG.md#options-description)). +By default, the number of requests in parallel is `1`. To increase it, change the value of the field `nbMaxParallelRequests` in `generalconfig.json` file (more information [here](CONFIG.md#general-options-description)). You will have a nice boost of speed when you query the same thing from multiple exchanges / or accounts. However, the logs may not be ordered anymore. @@ -310,7 +310,7 @@ Also, result can be narrowed to list of exchanges given after the optional curre **Note**: Markets are returned with the currency pair presented in original order from the exchange, as it could give additional information for services relying on this option (even though it's not needed for `trade` option of `coincenter`) -##### Examples +##### Examples of markets queries Lists all markets for all exchanges @@ -793,7 +793,7 @@ If you want to trade coin *AAA* into *CCC* but exchange does not have a *AAA-CCC In order to activate multi trades, there are two ways: -- Default behavior is controlled by [multiTradeAllowedByDefault option](CONFIG.md#options-description) in the `exchangeconfig.json` file. If `true`, multi trade is allowed for the given exchange (or all exchanges if under `default` level). +- Default behavior is controlled by [multiTradeAllowedByDefault option](CONFIG.md#exchanges-options-description) in the `exchangeconfig.json` file. If `true`, multi trade is allowed for the given exchange (or all exchanges if under `default` level). - It can be forced by adding command line flag `--multi-trade`. In the case it's activated in the config file, `--no-multi-trade` can force deactivation of the multi trade. @@ -804,13 +804,13 @@ Some exchanges (**Kraken** and **Binance** for instance) allow to actually query #### Buy / Sell -Trade family of commands require that you specify the *start amount* (with the start currency) and the *target currency*. You can use `buy` and `sell` commands when you have a start amount (for *sell*) or a target amount (for *buy*) only. It's more easy to use, but `coincenter` needs to know which are the [preferred currencies](CONFIG.md#options-description) to which it can *sell* the start amount to, or use as start amount for a *buy*. +Trade family of commands require that you specify the *start amount* (with the start currency) and the *target currency*. You can use `buy` and `sell` commands when you have a start amount (for *sell*) or a target amount (for *buy*) only. It's more easy to use, but `coincenter` needs to know which are the [preferred currencies](CONFIG.md#exchanges-options-description) to which it can *sell* the start amount to, or use as start amount for a *buy*. Sell option also supports percentage as start amount. In this case, the desired percentage of total available amount of given currency on matching exchanges (the ones specified after the `,` or all if none given as usual) will be sold. To complement this, `sell-all` option with a start currency instead of an amount is supported as well, which is syntactic sugar of a sell of `100%` of available amount. Buy a percentage is not available yet, simply because I am not sure about what should be the behavior of this option. If you have ideas about it, do not hesitate to propose them. -The list of preferred currencies should be filled prior to **buy / sell** command and is statically loaded at start of coincenter. It is an array of currencies ordered by decreasing priority, and they represent the currencies that can be used as target currency for a *sell*, and base currency for a *buy*. See [config](CONFIG.md#options-description) file to see how to set the preferred currencies. +The list of preferred currencies should be filled prior to **buy / sell** command and is statically loaded at start of coincenter. It is an array of currencies ordered by decreasing priority, and they represent the currencies that can be used as target currency for a *sell*, and base currency for a *buy*. See [config](CONFIG.md#exchanges-options-description) file to see how to set the preferred currencies. ##### Syntax diff --git a/src/api-objects/include/apikey.hpp b/src/api-objects/include/apikey.hpp index 378c35a0..5c327e30 100644 --- a/src/api-objects/include/apikey.hpp +++ b/src/api-objects/include/apikey.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "accountowner.hpp" #include "cct_string.hpp" @@ -57,8 +58,8 @@ class APIKey { std::string_view passphrase() const { return _passphrase; } const AccountOwner &accountOwner() const { return _accountOwner; } - using trivially_relocatable = std::integral_constant && - is_trivially_relocatable_v>::type; + using trivially_relocatable = + std::bool_constant && is_trivially_relocatable_v>::type; private: string _platform; diff --git a/src/api-objects/include/exchangepublicapitypes.hpp b/src/api-objects/include/exchangepublicapitypes.hpp index f1e28e2f..e4c8d9a6 100644 --- a/src/api-objects/include/exchangepublicapitypes.hpp +++ b/src/api-objects/include/exchangepublicapitypes.hpp @@ -1,20 +1,22 @@ #pragma once +#include #include +#include "cct_allocator.hpp" #include "cct_flatset.hpp" #include "cct_smallvector.hpp" -#include "cct_vector.hpp" #include "currencycode.hpp" +#include "market-vector.hpp" #include "market.hpp" #include "marketorderbook.hpp" #include "monetaryamount.hpp" -#include "publictrade.hpp" namespace cct { -using MarketSet = FlatSet; + +using MarketSet = FlatSet, allocator, MarketVector>; using MarketOrderBookMap = std::unordered_map; using MarketPriceMap = std::unordered_map; using MarketsPath = SmallVector; -using TradesVector = vector; -} // namespace cct \ No newline at end of file + +} // namespace cct diff --git a/src/api-objects/include/recentdeposit.hpp b/src/api-objects/include/recentdeposit.hpp index 639f489a..2b0e19a9 100644 --- a/src/api-objects/include/recentdeposit.hpp +++ b/src/api-objects/include/recentdeposit.hpp @@ -18,7 +18,7 @@ class RecentDeposit { private: MonetaryAmount _amount; - TimePoint _timePoint{}; + TimePoint _timePoint; }; class ClosestRecentDepositPicker { diff --git a/src/api-objects/include/withdrawinfo.hpp b/src/api-objects/include/withdrawinfo.hpp index 8b09ee84..481ab4a9 100644 --- a/src/api-objects/include/withdrawinfo.hpp +++ b/src/api-objects/include/withdrawinfo.hpp @@ -31,13 +31,13 @@ class InitiatedWithdrawInfo { MonetaryAmount grossEmittedAmount() const { return _grossEmittedAmount; } using trivially_relocatable = - std::integral_constant && is_trivially_relocatable_v>::type; + std::bool_constant && is_trivially_relocatable_v>::type; private: Wallet _receivingWallet; string _withdrawIdOrMsgIfNotInitiated; MonetaryAmount _grossEmittedAmount; - TimePoint _initiatedTime{}; // The time at which withdraw has been ordered from the source exchange + TimePoint _initiatedTime; // The time at which withdraw has been ordered from the source exchange }; class SentWithdrawInfo { @@ -84,12 +84,11 @@ class DeliveredWithdrawInfo { std::string_view withdrawId() const; - using trivially_relocatable = - std::integral_constant && is_trivially_relocatable_v>::type; + using trivially_relocatable = is_trivially_relocatable::type; private: api::InitiatedWithdrawInfo _initiatedWithdrawInfo; - TimePoint _receivedTime{}; // time at which destination provides received funds as available for trade + TimePoint _receivedTime; // time at which destination provides received funds as available for trade MonetaryAmount _receivedAmount; // fee deduced amount that destination will receive }; diff --git a/src/api/common/include/exchangepublicapi.hpp b/src/api/common/include/exchangepublicapi.hpp index 4bb3f91c..8e75dcf6 100644 --- a/src/api/common/include/exchangepublicapi.hpp +++ b/src/api/common/include/exchangepublicapi.hpp @@ -15,6 +15,7 @@ #include "monetaryamount.hpp" #include "monetaryamountbycurrencyset.hpp" #include "priceoptions.hpp" +#include "public-trade-vector.hpp" namespace cct { @@ -104,7 +105,7 @@ class ExchangePublic : public ExchangeBase { virtual MonetaryAmount queryLast24hVolume(Market mk) = 0; /// Retrieve an ordered vector of recent last trades - virtual TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) = 0; + virtual PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) = 0; /// Retrieve the last price of given market. virtual MonetaryAmount queryLastPrice(Market mk) = 0; diff --git a/src/api/common/include/exchangepublicapi_mock.hpp b/src/api/common/include/exchangepublicapi_mock.hpp index 4910b2ac..36cf1db5 100644 --- a/src/api/common/include/exchangepublicapi_mock.hpp +++ b/src/api/common/include/exchangepublicapi_mock.hpp @@ -9,6 +9,7 @@ #include "exchangepublicapitypes.hpp" #include "fiatconverter.hpp" #include "monetaryamount.hpp" +#include "public-trade-vector.hpp" namespace cct::api { class MockExchangePublic : public ExchangePublic { @@ -28,7 +29,7 @@ class MockExchangePublic : public ExchangePublic { MOCK_METHOD(MarketOrderBookMap, queryAllApproximatedOrderBooks, (int depth), (override)); MOCK_METHOD(MarketOrderBook, queryOrderBook, (Market mk, int depth), (override)); MOCK_METHOD(MonetaryAmount, queryLast24hVolume, (Market mk), (override)); - MOCK_METHOD(TradesVector, queryLastTrades, (Market mk, int nbTrades), (override)); + MOCK_METHOD(PublicTradeVector, queryLastTrades, (Market mk, int nbTrades), (override)); MOCK_METHOD(MonetaryAmount, queryLastPrice, (Market mk), (override)); }; } // namespace cct::api \ No newline at end of file diff --git a/src/api/common/src/exchangeprivateapi.cpp b/src/api/common/src/exchangeprivateapi.cpp index 92243956..b4d5a6e3 100644 --- a/src/api/common/src/exchangeprivateapi.cpp +++ b/src/api/common/src/exchangeprivateapi.cpp @@ -16,7 +16,6 @@ #include "balanceoptions.hpp" #include "balanceportfolio.hpp" #include "cct_log.hpp" -#include "cct_vector.hpp" #include "coincenterinfo.hpp" #include "currencycode.hpp" #include "deposit.hpp" @@ -28,6 +27,7 @@ #include "exchangeprivateapitypes.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" +#include "market-vector.hpp" #include "market.hpp" #include "marketorderbook.hpp" #include "monetaryamount.hpp" @@ -337,11 +337,11 @@ void IncrementPenalty(Market mk, PenaltyPerMarketMap &penaltyPerMarketMap) { } } -vector GetPossibleMarketsForDustThresholds(const BalancePortfolio &balance, - const MonetaryAmountByCurrencySet &dustThresholds, - CurrencyCode currencyCode, const MarketSet &markets, - const PenaltyPerMarketMap &penaltyPerMarketMap) { - vector possibleMarkets; +MarketVector GetPossibleMarketsForDustThresholds(const BalancePortfolio &balance, + const MonetaryAmountByCurrencySet &dustThresholds, + CurrencyCode currencyCode, const MarketSet &markets, + const PenaltyPerMarketMap &penaltyPerMarketMap) { + MarketVector possibleMarkets; for (const BalancePortfolio::MonetaryAmountWithEquivalent &avAmountEq : balance) { MonetaryAmount avAmount = avAmountEq.amount; CurrencyCode avCur = avAmount.currencyCode(); @@ -494,7 +494,7 @@ TradedAmountsVectorWithFinalAmount ExchangePrivate::queryDustSweeper(CurrencyCod // Pick a trade currency which has some available balance for which the market exists with 'currencyCode', // whose amount is higher than its dust amount threshold if it exists - vector possibleMarkets = + MarketVector possibleMarkets = GetPossibleMarketsForDustThresholds(balance, dustThresholds, currencyCode, markets, penaltyPerMarketMap); if (possibleMarkets.empty()) { log::warn("No more market is allowed for trade in dust threshold sweeper context"); @@ -513,7 +513,7 @@ TradedAmountsVectorWithFinalAmount ExchangePrivate::queryDustSweeper(CurrencyCod continue; } - // At this point we did not sell all amount, but it's possible that some trades have been done, with remainings. + // At this point we did not sell all amount, but it's possible that some trades have been done, with remaining. // Selling has not worked - so we need to buy some amount on the requested currency first tradedAmounts = buySomeAmountToMakeFutureSellPossible(possibleMarkets, marketPriceMap, dustThreshold, balance, tradeOptions, dustThresholds); diff --git a/src/api/exchanges/include/binancepublicapi.hpp b/src/api/exchanges/include/binancepublicapi.hpp index 96b6fbfc..1eeef1c9 100644 --- a/src/api/exchanges/include/binancepublicapi.hpp +++ b/src/api/exchanges/include/binancepublicapi.hpp @@ -15,6 +15,7 @@ #include "market.hpp" #include "monetaryamount.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "runmodes.hpp" namespace cct { @@ -63,7 +64,7 @@ class BinancePublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tradedVolumeCache.get(mk); } - TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override { return _tickerCache.get(mk); } diff --git a/src/api/exchanges/include/bithumbprivateapi.hpp b/src/api/exchanges/include/bithumbprivateapi.hpp index 941a9978..c04dc54d 100644 --- a/src/api/exchanges/include/bithumbprivateapi.hpp +++ b/src/api/exchanges/include/bithumbprivateapi.hpp @@ -71,13 +71,13 @@ class BithumbPrivate : public ExchangePrivate { struct CurrencyOrderInfo { int8_t nbDecimals{}; - TimePoint lastNbDecimalsUpdatedTime{}; + TimePoint lastNbDecimalsUpdatedTime; MonetaryAmount minOrderSize; - TimePoint lastMinOrderSizeUpdatedTime{}; + TimePoint lastMinOrderSizeUpdatedTime; MonetaryAmount minOrderPrice; - TimePoint lastMinOrderPriceUpdatedTime{}; + TimePoint lastMinOrderPriceUpdatedTime; MonetaryAmount maxOrderPrice; - TimePoint lastMaxOrderPriceUpdatedTime{}; + TimePoint lastMaxOrderPriceUpdatedTime; }; using CurrencyOrderInfoMap = std::unordered_map; diff --git a/src/api/exchanges/include/bithumbpublicapi.hpp b/src/api/exchanges/include/bithumbpublicapi.hpp index a804852c..71c9e0d5 100644 --- a/src/api/exchanges/include/bithumbpublicapi.hpp +++ b/src/api/exchanges/include/bithumbpublicapi.hpp @@ -12,6 +12,7 @@ #include "marketorderbook.hpp" #include "monetaryamount.hpp" #include "monetaryamountbycurrencyset.hpp" +#include "public-trade-vector.hpp" namespace cct { @@ -59,7 +60,7 @@ class BithumbPublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tradedVolumeCache.get(mk); } - TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override; diff --git a/src/api/exchanges/include/huobipublicapi.hpp b/src/api/exchanges/include/huobipublicapi.hpp index 04bceff6..0923e2ca 100644 --- a/src/api/exchanges/include/huobipublicapi.hpp +++ b/src/api/exchanges/include/huobipublicapi.hpp @@ -11,6 +11,7 @@ #include "currencycode.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" +#include "public-trade-vector.hpp" #include "volumeandpricenbdecimals.hpp" namespace cct { @@ -58,7 +59,7 @@ class HuobiPublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tradedVolumeCache.get(mk); } - TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override { return _tickerCache.get(mk); } diff --git a/src/api/exchanges/include/krakenpublicapi.hpp b/src/api/exchanges/include/krakenpublicapi.hpp index 091578e6..6d92ec54 100644 --- a/src/api/exchanges/include/krakenpublicapi.hpp +++ b/src/api/exchanges/include/krakenpublicapi.hpp @@ -7,7 +7,6 @@ #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" #include "static_string_view_helpers.hpp" -#include "timedef.hpp" #include "volumeandpricenbdecimals.hpp" namespace cct { @@ -56,7 +55,7 @@ class KrakenPublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tickerCache.get(mk).first; } - TradesVector queryLastTrades(Market mk, int nbLastTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbLastTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override { return _tickerCache.get(mk).second; } diff --git a/src/api/exchanges/include/kucoinpublicapi.hpp b/src/api/exchanges/include/kucoinpublicapi.hpp index 34975510..882ac7d4 100644 --- a/src/api/exchanges/include/kucoinpublicapi.hpp +++ b/src/api/exchanges/include/kucoinpublicapi.hpp @@ -11,6 +11,7 @@ #include "currencycode.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" +#include "public-trade-vector.hpp" #include "volumeandpricenbdecimals.hpp" namespace cct { @@ -56,7 +57,7 @@ class KucoinPublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tradedVolumeCache.get(mk); } - TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override { return _tickerCache.get(mk); } diff --git a/src/api/exchanges/include/upbitpublicapi.hpp b/src/api/exchanges/include/upbitpublicapi.hpp index db801f27..6b581e25 100644 --- a/src/api/exchanges/include/upbitpublicapi.hpp +++ b/src/api/exchanges/include/upbitpublicapi.hpp @@ -8,6 +8,7 @@ #include "currencycodeset.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" +#include "public-trade-vector.hpp" namespace cct { @@ -52,7 +53,7 @@ class UpbitPublic : public ExchangePublic { MonetaryAmount queryLast24hVolume(Market mk) override { return _tradedVolumeCache.get(mk); } - TradesVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; + PublicTradeVector queryLastTrades(Market mk, int nbTrades = kNbLastTradesDefault) override; MonetaryAmount queryLastPrice(Market mk) override { return _tickerCache.get(mk); } diff --git a/src/api/exchanges/src/binanceprivateapi.cpp b/src/api/exchanges/src/binanceprivateapi.cpp index 22649353..5998d3d1 100644 --- a/src/api/exchanges/src/binanceprivateapi.cpp +++ b/src/api/exchanges/src/binanceprivateapi.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/src/api/exchanges/src/binancepublicapi.cpp b/src/api/exchanges/src/binancepublicapi.cpp index 863aea0a..415fb18b 100644 --- a/src/api/exchanges/src/binancepublicapi.cpp +++ b/src/api/exchanges/src/binancepublicapi.cpp @@ -39,6 +39,7 @@ #include "monetaryamountbycurrencyset.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "runmodes.hpp" #include "timedef.hpp" #include "tradeside.hpp" @@ -321,7 +322,7 @@ MonetaryAmount BinancePublic::sanitizePrice(Market mk, MonetaryAmount pri) { MonetaryAmount BinancePublic::computePriceForNotional(Market mk, int avgPriceMins) { if (avgPriceMins == 0) { // price should be the last matched price - TradesVector lastTrades = queryLastTrades(mk, 1); + PublicTradeVector lastTrades = queryLastTrades(mk, 1); if (!lastTrades.empty()) { return lastTrades.front().price(); } @@ -520,7 +521,7 @@ MonetaryAmount BinancePublic::TradedVolumeFunc::operator()(Market mk) { return {last24hVol, mk.base()}; } -TradesVector BinancePublic::queryLastTrades(Market mk, int nbTrades) { +PublicTradeVector BinancePublic::queryLastTrades(Market mk, int nbTrades) { if (nbTrades > kMaxNbLastTrades) { log::warn("{} is larger than maximum number of last trades of {} on {}", nbTrades, kMaxNbLastTrades, _name); nbTrades = kMaxNbLastTrades; @@ -528,8 +529,8 @@ TradesVector BinancePublic::queryLastTrades(Market mk, int nbTrades) { json result = PublicQuery(_commonInfo._curlHandle, "/api/v3/trades", {{"symbol", mk.assetsPairStrUpper()}, {"limit", nbTrades}}); - TradesVector ret; - ret.reserve(static_cast(result.size())); + PublicTradeVector ret; + ret.reserve(static_cast(result.size())); for (const json& detail : result) { MonetaryAmount amount(detail["qty"].get(), mk.base()); MonetaryAmount price(detail["price"].get(), mk.quote()); diff --git a/src/api/exchanges/src/bithumbpublicapi.cpp b/src/api/exchanges/src/bithumbpublicapi.cpp index 24d3b014..0f098521 100644 --- a/src/api/exchanges/src/bithumbpublicapi.cpp +++ b/src/api/exchanges/src/bithumbpublicapi.cpp @@ -36,6 +36,7 @@ #include "monetaryamount.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "stringhelpers.hpp" #include "timedef.hpp" #include "timestring.hpp" @@ -300,9 +301,9 @@ TimePoint EpochTime(std::string&& dateStr) { } } // namespace -TradesVector BithumbPublic::queryLastTrades(Market mk, [[maybe_unused]] int nbTrades) { +PublicTradeVector BithumbPublic::queryLastTrades(Market mk, [[maybe_unused]] int nbTrades) { json result = PublicQuery(_curlHandle, "/public/transaction_history/", mk.base(), mk.quote()); - TradesVector ret; + PublicTradeVector ret; ret.reserve(result.size()); for (const json& detail : result) { MonetaryAmount amount(detail["units_traded"].get(), mk.base()); diff --git a/src/api/exchanges/src/huobipublicapi.cpp b/src/api/exchanges/src/huobipublicapi.cpp index f10a86b1..f72c96d1 100644 --- a/src/api/exchanges/src/huobipublicapi.cpp +++ b/src/api/exchanges/src/huobipublicapi.cpp @@ -35,6 +35,7 @@ #include "monetaryamountbycurrencyset.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "timedef.hpp" #include "toupperlower-string.hpp" #include "tradeside.hpp" @@ -458,12 +459,12 @@ MonetaryAmount HuobiPublic::TradedVolumeFunc::operator()(Market mk) { return MonetaryAmount(last24hVol, mk.base()); } -TradesVector HuobiPublic::queryLastTrades(Market mk, int nbTrades) { +PublicTradeVector HuobiPublic::queryLastTrades(Market mk, int nbTrades) { nbTrades = std::min(nbTrades, 2000); // max authorized nbTrades = std::max(nbTrades, 1); // min authorized json result = PublicQuery(_curlHandle, "/market/history/trade", {{"symbol", mk.assetsPairStrLower()}, {"size", nbTrades}}); - TradesVector ret; + PublicTradeVector ret; for (const json& detail : result) { auto dataDetails = detail.find("data"); if (dataDetails != detail.end()) { diff --git a/src/api/exchanges/src/krakenpublicapi.cpp b/src/api/exchanges/src/krakenpublicapi.cpp index 02d61914..c337e999 100644 --- a/src/api/exchanges/src/krakenpublicapi.cpp +++ b/src/api/exchanges/src/krakenpublicapi.cpp @@ -33,6 +33,7 @@ #include "monetaryamountbycurrencyset.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "timedef.hpp" #include "tradeside.hpp" @@ -336,10 +337,10 @@ KrakenPublic::TickerFunc::Last24hTradedVolumeAndLatestPricePair KrakenPublic::Ti throw exception("Invalid data retrieved from ticker information"); } -TradesVector KrakenPublic::queryLastTrades(Market mk, int nbLastTrades) { +PublicTradeVector KrakenPublic::queryLastTrades(Market mk, int nbLastTrades) { Market krakenMarket(_tradableCurrenciesCache.get().getOrThrow(mk.base()).altCode(), _tradableCurrenciesCache.get().getOrThrow(mk.quote()).altCode()); - TradesVector ret; + PublicTradeVector ret; json result = PublicQuery(_curlHandle, "/public/Trades", {{"pair", krakenMarket.assetsPairStrUpper()}, {"count", nbLastTrades}}); if (!result.empty()) { diff --git a/src/api/exchanges/src/kucoinpublicapi.cpp b/src/api/exchanges/src/kucoinpublicapi.cpp index c1b3193c..a98aeae3 100644 --- a/src/api/exchanges/src/kucoinpublicapi.cpp +++ b/src/api/exchanges/src/kucoinpublicapi.cpp @@ -34,6 +34,7 @@ #include "monetaryamountbycurrencyset.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "stringhelpers.hpp" #include "timedef.hpp" #include "tradeside.hpp" @@ -349,10 +350,10 @@ MonetaryAmount KucoinPublic::TradedVolumeFunc::operator()(Market mk) { return {amountStr, mk.base()}; } -TradesVector KucoinPublic::queryLastTrades(Market mk, [[maybe_unused]] int nbTrades) { +PublicTradeVector KucoinPublic::queryLastTrades(Market mk, [[maybe_unused]] int nbTrades) { json result = PublicQuery(_curlHandle, "/api/v1/market/histories", GetSymbolPostData(mk)); - TradesVector ret; - ret.reserve(static_cast(result.size())); + PublicTradeVector ret; + ret.reserve(static_cast(result.size())); for (const json& detail : result) { MonetaryAmount amount(detail["size"].get(), mk.base()); MonetaryAmount price(detail["price"].get(), mk.quote()); diff --git a/src/api/exchanges/src/upbitprivateapi.cpp b/src/api/exchanges/src/upbitprivateapi.cpp index e5526dbb..15d790df 100644 --- a/src/api/exchanges/src/upbitprivateapi.cpp +++ b/src/api/exchanges/src/upbitprivateapi.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "apikey.hpp" diff --git a/src/api/exchanges/src/upbitpublicapi.cpp b/src/api/exchanges/src/upbitpublicapi.cpp index 65aeaa85..7b2953e7 100644 --- a/src/api/exchanges/src/upbitpublicapi.cpp +++ b/src/api/exchanges/src/upbitpublicapi.cpp @@ -34,6 +34,7 @@ #include "monetaryamountbycurrencyset.hpp" #include "order-book-line.hpp" #include "permanentcurloptions.hpp" +#include "public-trade-vector.hpp" #include "timedef.hpp" #include "tradeside.hpp" @@ -255,10 +256,10 @@ MonetaryAmount UpbitPublic::TradedVolumeFunc::operator()(Market mk) { return MonetaryAmount(last24hVol, mk.base()); } -TradesVector UpbitPublic::queryLastTrades(Market mk, int nbTrades) { +PublicTradeVector UpbitPublic::queryLastTrades(Market mk, int nbTrades) { json result = PublicQuery(_curlHandle, "/v1/trades/ticks", {{"count", nbTrades}, {"market", ReverseMarketStr(mk)}}); - TradesVector ret; - ret.reserve(static_cast(result.size())); + PublicTradeVector ret; + ret.reserve(static_cast(result.size())); for (const json& detail : result) { MonetaryAmount amount(detail["trade_volume"].get(), mk.base()); MonetaryAmount price(detail["trade_price"].get(), mk.quote()); diff --git a/src/api/exchanges/test/exchangecommonapi_test.hpp b/src/api/exchanges/test/exchangecommonapi_test.hpp index a39a6f85..a3614ed9 100644 --- a/src/api/exchanges/test/exchangecommonapi_test.hpp +++ b/src/api/exchanges/test/exchangecommonapi_test.hpp @@ -14,6 +14,7 @@ #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" #include "fiatconverter.hpp" +#include "public-trade-vector.hpp" namespace cct::api { @@ -280,7 +281,7 @@ class TestAPI { } if (!sampleMarkets.empty()) { Market mk = sampleMarkets.front(); - TradesVector lastTrades = exchangePublic.queryLastTrades(mk); + PublicTradeVector lastTrades = exchangePublic.queryLastTrades(mk); if (!lastTrades.empty() && exchangePrivateOpt) { auto compareTradedVolume = [](const PublicTrade &lhs, const PublicTrade &rhs) { return lhs.amount() < rhs.amount(); diff --git a/src/api/interface/include/exchange.hpp b/src/api/interface/include/exchange.hpp index ba5510dd..c150a9b4 100644 --- a/src/api/interface/include/exchange.hpp +++ b/src/api/interface/include/exchange.hpp @@ -12,9 +12,11 @@ #include "exchangeprivateapi.hpp" #include "exchangepublicapi.hpp" #include "exchangepublicapitypes.hpp" +#include "market.hpp" #include "marketorderbook.hpp" #include "monetaryamount.hpp" #include "monetaryamountbycurrencyset.hpp" +#include "public-trade-vector.hpp" namespace cct { class Exchange { @@ -86,16 +88,12 @@ class Exchange { return _exchangePublic.queryAllApproximatedOrderBooks(depth); } - MarketOrderBook queryOrderBook(Market mk, int depth = ExchangePublic::kDefaultDepth) { - return _exchangePublic.queryOrderBook(mk, depth); - } + MarketOrderBook queryOrderBook(Market mk, int depth = ExchangePublic::kDefaultDepth); MonetaryAmount queryLast24hVolume(Market mk) { return _exchangePublic.queryLast24hVolume(mk); } /// Retrieve an ordered vector of recent last trades - TradesVector queryLastTrades(Market mk, int nbTrades = ExchangePublic::kNbLastTradesDefault) { - return _exchangePublic.queryLastTrades(mk, nbTrades); - } + PublicTradeVector queryLastTrades(Market mk, int nbTrades = ExchangePublic::kNbLastTradesDefault); /// Retrieve the last price of given market. MonetaryAmount queryLastPrice(Market mk) { return _exchangePublic.queryLastPrice(mk); } diff --git a/src/api/interface/src/exchange.cpp b/src/api/interface/src/exchange.cpp index b6ed7dd8..f252693d 100644 --- a/src/api/interface/src/exchange.cpp +++ b/src/api/interface/src/exchange.cpp @@ -8,6 +8,8 @@ #include "exchangeconfig.hpp" #include "exchangeprivateapi.hpp" #include "exchangepublicapi.hpp" +#include "marketorderbook.hpp" +#include "public-trade-vector.hpp" namespace cct { @@ -33,7 +35,7 @@ bool Exchange::canWithdraw(CurrencyCode currencyCode, const CurrencyExchangeFlat } bool Exchange::canDeposit(CurrencyCode currencyCode, const CurrencyExchangeFlatSet ¤cyExchangeSet) const { - auto lb = currencyExchangeSet.find(currencyCode); + const auto lb = currencyExchangeSet.find(currencyCode); if (lb == currencyExchangeSet.end()) { log::trace("{} cannot be deposited on {}", currencyCode, name()); return false; @@ -41,6 +43,13 @@ bool Exchange::canDeposit(CurrencyCode currencyCode, const CurrencyExchangeFlatS return lb->canDeposit(); } +MarketOrderBook Exchange::queryOrderBook(Market mk, int depth) { return _exchangePublic.queryOrderBook(mk, depth); } + +/// Retrieve an ordered vector of recent last trades +PublicTradeVector Exchange::queryLastTrades(Market mk, int nbTrades) { + return _exchangePublic.queryLastTrades(mk, nbTrades); +} + void Exchange::updateCacheFile() const { _exchangePublic.updateCacheFile(); if (_pExchangePrivate != nullptr) { diff --git a/src/engine/include/coincentercommand.hpp b/src/engine/include/coincentercommand.hpp index 6991477c..a9c0704e 100644 --- a/src/engine/include/coincentercommand.hpp +++ b/src/engine/include/coincentercommand.hpp @@ -22,28 +22,21 @@ class CoincenterCommand { public: explicit CoincenterCommand(CoincenterCommandType type) : _type(type) {} - CoincenterCommand& setExchangeNames(const ExchangeNames& exchangeNames); - CoincenterCommand& setExchangeNames(ExchangeNames&& exchangeNames); + CoincenterCommand& setExchangeNames(ExchangeNames exchangeNames); - CoincenterCommand& setOrdersConstraints(const OrdersConstraints& ordersConstraints); - CoincenterCommand& setOrdersConstraints(OrdersConstraints&& ordersConstraints); + CoincenterCommand& setOrdersConstraints(OrdersConstraints ordersConstraints); - CoincenterCommand& setDepositsConstraints(const DepositsConstraints& depositsConstraints); - CoincenterCommand& setDepositsConstraints(DepositsConstraints&& depositsConstraints); + CoincenterCommand& setDepositsConstraints(DepositsConstraints depositsConstraints); - CoincenterCommand& setWithdrawsConstraints(const WithdrawsConstraints& withdrawsConstraints); - CoincenterCommand& setWithdrawsConstraints(WithdrawsConstraints&& withdrawsConstraints); + CoincenterCommand& setWithdrawsConstraints(WithdrawsConstraints withdrawsConstraints); - CoincenterCommand& setTradeOptions(const TradeOptions& tradeOptions); - CoincenterCommand& setTradeOptions(TradeOptions&& tradeOptions); + CoincenterCommand& setTradeOptions(TradeOptions tradeOptions); - CoincenterCommand& setWithdrawOptions(const WithdrawOptions& withdrawOptions); - CoincenterCommand& setWithdrawOptions(WithdrawOptions&& withdrawOptions); + CoincenterCommand& setWithdrawOptions(WithdrawOptions withdrawOptions); CoincenterCommand& setAmount(MonetaryAmount amount); CoincenterCommand& setDepth(int depth); - CoincenterCommand& setNbLastTrades(int nbTrades) { return setDepth(nbTrades); } CoincenterCommand& setMarket(Market market); @@ -67,7 +60,7 @@ class CoincenterCommand { MonetaryAmount amount() const { return _amount; } - int nbLastTrades() const { return _n; } + int depth() const { return _n; } std::optional optDepth() const { return _n == -1 ? std::nullopt : std::optional(_n); } Market market() const { return _market; } @@ -82,11 +75,12 @@ class CoincenterCommand { bool operator==(const CoincenterCommand&) const noexcept = default; - using trivially_relocatable = std::integral_constant && - is_trivially_relocatable_v>::type; + using trivially_relocatable = std::bool_constant && + is_trivially_relocatable_v>::type; private: - using SpecialOptions = std::variant; + using SpecialOptions = + std::variant; ExchangeNames _exchangeNames; SpecialOptions _specialOptions; @@ -99,4 +93,4 @@ class CoincenterCommand { bool _withBalanceInUse = false; }; -} // namespace cct \ No newline at end of file +} // namespace cct diff --git a/src/engine/include/coincenteroptions.hpp b/src/engine/include/coincenteroptions.hpp index b70c981b..de6c3a29 100644 --- a/src/engine/include/coincenteroptions.hpp +++ b/src/engine/include/coincenteroptions.hpp @@ -98,9 +98,8 @@ class CoincenterCmdLineOptions { std::string_view lastTrades; CommandLineOptionalInt repeats; - int nbLastTrades = api::ExchangePublic::kNbLastTradesDefault; int monitoringPort = CoincenterCmdLineOptionsDefinitions::kDefaultMonitoringPort; - int orderbookDepth = 0; + int depth = 0; bool forceMultiTrade = false; bool forceSingleTrade = false; diff --git a/src/engine/include/coincenteroptionsdef.hpp b/src/engine/include/coincenteroptionsdef.hpp index 44a79587..bf4f5711 100644 --- a/src/engine/include/coincenteroptionsdef.hpp +++ b/src/engine/include/coincenteroptionsdef.hpp @@ -218,8 +218,7 @@ struct CoincenterAllowedOptions : private CoincenterCmdLineOptionsDefinitions { "If conversion of cur2 into cur is possible (for each exchange), " "prints additional column converted to given asset"}, &OptValueType::orderbookCur}, - {{{"Public queries", 2300}, "--depth", "", "Override default depth of order book"}, - &OptValueType::orderbookDepth}, + {{{"Public queries", 2300}, "--depth", "", "Override default depth of order book"}, &OptValueType::depth}, {{{"Public queries", 2400}, "ticker", "<[exch1,...]>", @@ -249,7 +248,7 @@ struct CoincenterAllowedOptions : private CoincenterCmdLineOptionsDefinitions { "Print last trades for market 'cur1'-'cur2' " "for all exchanges (or specified one)"}, &OptValueType::lastTrades}, - {{{"Public queries", 2800}, "--n", "", kLastTradesN}, &OptValueType::nbLastTrades}, + {{{"Public queries", 2800}, "--n", "", kLastTradesN}, &OptValueType::depth}, {{{"Public queries", 2900}, "price", "", @@ -331,14 +330,14 @@ struct CoincenterAllowedOptions : private CoincenterCmdLineOptionsDefinitions { &OptValueType::minAge}, {{{"Private queries", 3902}, "--max-age", "