Skip to content

Commit

Permalink
Currency is now optional for withdraw-fee CLI, renamed into withdraw-…
Browse files Browse the repository at this point in the history
…fees
  • Loading branch information
sjanel committed Dec 2, 2023
1 parent dfe9714 commit dba81d7
Show file tree
Hide file tree
Showing 43 changed files with 242 additions and 158 deletions.
2 changes: 0 additions & 2 deletions src/api-objects/include/exchangepublicapitypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
#include "market.hpp"
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "publictrade.hpp"

namespace cct {
using MarketSet = FlatSet<Market>;
using MarketOrderBookMap = std::unordered_map<Market, MarketOrderBook>;
using MarketPriceMap = std::unordered_map<Market, MonetaryAmount>;
using MarketsPath = SmallVector<Market, 3>;
using WithdrawalFeesSet = MonetaryAmountByCurrencySet;
using LastTradesVector = vector<PublicTrade>;
} // namespace cct
8 changes: 3 additions & 5 deletions src/api/common/include/exchangeprivateapi.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#pragma once

#include <chrono>
#include <span>
#include <utility>

#include "apikey.hpp"
#include "balanceoptions.hpp"
#include "balanceportfolio.hpp"
#include "cachedresultvault.hpp"
#include "curlhandle.hpp"
#include "currencycode.hpp"
#include "currencyexchangeflatset.hpp"
#include "depositsconstraints.hpp"
Expand All @@ -19,7 +17,7 @@
#include "exchangepublicapitypes.hpp"
#include "market.hpp"
#include "monetaryamount.hpp"
#include "order.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "orderid.hpp"
#include "ordersconstraints.hpp"
#include "tradedamounts.hpp"
Expand Down Expand Up @@ -105,11 +103,11 @@ class ExchangePrivate : public ExchangeBase {

/// Retrieve the fixed withdrawal fees per currency.
/// Some exchanges provide this service in the public REST API but not all, hence this private API flavor.
virtual WithdrawalFeesSet queryWithdrawalFees() { return _exchangePublic.queryWithdrawalFees(); }
virtual MonetaryAmountByCurrencySet queryWithdrawalFees() { return _exchangePublic.queryWithdrawalFees(); }

/// Retrieve the withdrawal fee of a Currency only
/// Some exchanges provide this service in the public REST API but not all, hence this private API flavor.
virtual MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) {
virtual std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) {
return _exchangePublic.queryWithdrawalFee(currencyCode);
}

Expand Down
10 changes: 7 additions & 3 deletions src/api/common/include/exchangepublicapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#include "market.hpp"
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "priceoptions.hpp"
#include "tradedefinitions.hpp"

namespace cct {

Expand Down Expand Up @@ -70,10 +70,10 @@ class ExchangePublic : public ExchangeBase {
/// Retrieve the fixed withdrawal fees per currency.
/// Depending on the exchange, this could be retrieved dynamically,
/// or, if not possible, should be retrieved from a static source updated regularly.
virtual WithdrawalFeesSet queryWithdrawalFees() = 0;
virtual MonetaryAmountByCurrencySet queryWithdrawalFees() = 0;

/// Retrieve the withdrawal fee of a Currency only
virtual MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) = 0;
virtual std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) = 0;

/// Return true if exchange supports official REST API has an endpoint to get withdrawal fees
/// For instance, Kraken does not offer such endpoint, we nee to query external sources which may provide inaccurate
Expand Down Expand Up @@ -162,6 +162,10 @@ class ExchangePublic : public ExchangeBase {

CommonAPI &commonAPI() { return _commonApi; }

/// Query withdrawal fee for given currency code.
/// If no data found, return a 0 MonetaryAmount on given currency.
MonetaryAmount queryWithdrawalFeeOrZero(CurrencyCode currencyCode);

protected:
friend class ExchangePrivate;

Expand Down
7 changes: 5 additions & 2 deletions src/api/common/include/exchangepublicapi_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

#include <gmock/gmock.h>

#include <optional>

#include "commonapi.hpp"
#include "exchangepublicapi.hpp"
#include "exchangepublicapitypes.hpp"
#include "fiatconverter.hpp"
#include "monetaryamount.hpp"

namespace cct::api {
class MockExchangePublic : public ExchangePublic {
Expand All @@ -19,8 +22,8 @@ class MockExchangePublic : public ExchangePublic {
MOCK_METHOD(CurrencyExchange, convertStdCurrencyToCurrencyExchange, (CurrencyCode currencyCode), (override));
MOCK_METHOD(MarketSet, queryTradableMarkets, (), (override));
MOCK_METHOD(MarketPriceMap, queryAllPrices, (), (override));
MOCK_METHOD(WithdrawalFeesSet, queryWithdrawalFees, (), (override));
MOCK_METHOD(MonetaryAmount, queryWithdrawalFee, (CurrencyCode currencyCode), (override));
MOCK_METHOD(MonetaryAmountByCurrencySet, queryWithdrawalFees, (), (override));
MOCK_METHOD(std::optional<MonetaryAmount>, queryWithdrawalFee, (CurrencyCode currencyCode), (override));
MOCK_METHOD(bool, isWithdrawalFeesSourceReliable, (), (const override));
MOCK_METHOD(MarketOrderBookMap, queryAllApproximatedOrderBooks, (int depth), (override));
MOCK_METHOD(MarketOrderBook, queryOrderBook, (Market mk, int depth), (override));
Expand Down
12 changes: 12 additions & 0 deletions src/api/common/src/exchangepublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,16 @@ Market ExchangePublic::determineMarketFromFilterCurrencies(MarketSet &markets, C
return ret;
}

MonetaryAmount ExchangePublic::queryWithdrawalFeeOrZero(CurrencyCode currencyCode) {
std::optional<MonetaryAmount> optWithdrawFee = queryWithdrawalFee(currencyCode);
MonetaryAmount withdrawFee;
if (optWithdrawFee) {
withdrawFee = *optWithdrawFee;
} else {
log::error("Unable to retrieve withdraw fee for {} on {}, consider 0", currencyCode, name());
withdrawFee = MonetaryAmount(0, currencyCode);
}
return withdrawFee;
}

} // namespace cct::api
12 changes: 7 additions & 5 deletions src/api/exchanges/include/binanceprivateapi.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <optional>
#include <type_traits>

#include "apikey.hpp"
Expand All @@ -13,7 +14,6 @@
#include "depositsconstraints.hpp"
#include "exchangeprivateapi.hpp"
#include "exchangeprivateapitypes.hpp"
#include "exchangepublicapitypes.hpp"
#include "httprequesttype.hpp"
#include "monetaryamount.hpp"
#include "ordersconstraints.hpp"
Expand Down Expand Up @@ -54,9 +54,11 @@ class BinancePrivate : public ExchangePrivate {

WithdrawsSet queryRecentWithdraws(const WithdrawsConstraints& withdrawsConstraints = WithdrawsConstraints()) override;

WithdrawalFeesSet queryWithdrawalFees() override { return _allWithdrawFeesCache.get(); }
MonetaryAmountByCurrencySet queryWithdrawalFees() override { return _allWithdrawFeesCache.get(); }

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override { return _withdrawFeesCache.get(currencyCode); }
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override {
return _withdrawFeesCache.get(currencyCode);
}

protected:
bool isSimulatedOrderSupported() const override { return true; }
Expand Down Expand Up @@ -111,14 +113,14 @@ class BinancePrivate : public ExchangePrivate {
Duration& queryDelay)
: BinanceContext(curlHandle, apiKey, exchangePublic, queryDelay) {}

WithdrawalFeesSet operator()();
MonetaryAmountByCurrencySet operator()();
};

struct WithdrawFeesFunc : public BinanceContext {
WithdrawFeesFunc(CurlHandle& curlHandle, const APIKey& apiKey, BinancePublic& exchangePublic, Duration& queryDelay)
: BinanceContext(curlHandle, apiKey, exchangePublic, queryDelay) {}

MonetaryAmount operator()(CurrencyCode currencyCode);
std::optional<MonetaryAmount> operator()(CurrencyCode currencyCode);
};

CurlHandle _curlHandle;
Expand Down
5 changes: 3 additions & 2 deletions src/api/exchanges/include/binancepublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <optional>
#include <string_view>
#include <unordered_map>

Expand Down Expand Up @@ -46,9 +47,9 @@ class BinancePublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

WithdrawalFeesSet queryWithdrawalFees() override;
MonetaryAmountByCurrencySet queryWithdrawalFees() override;

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return true; }

Expand Down
7 changes: 4 additions & 3 deletions src/api/exchanges/include/bithumbpublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <optional>
#include <string_view>

#include "cachedresult.hpp"
Expand Down Expand Up @@ -34,9 +35,9 @@ class BithumbPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get()); }

WithdrawalFeesSet queryWithdrawalFees() override { return _withdrawalFeesCache.get(); }
MonetaryAmountByCurrencySet queryWithdrawalFees() override { return _withdrawalFeesCache.get(); }

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return true; }

Expand Down Expand Up @@ -74,7 +75,7 @@ class BithumbPublic : public ExchangePublic {
settings::RunMode runMode)
: _curlHandle(kFeeUrl, pMetricGateway, permanentCurlOptions, runMode) {}

WithdrawalFeesSet operator()();
MonetaryAmountByCurrencySet operator()();

CurlHandle _curlHandle;
};
Expand Down
6 changes: 3 additions & 3 deletions src/api/exchanges/include/huobipublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#pragma once

#include <limits>
#include <optional>
#include <string_view>
#include <unordered_map>

#include "cachedresult.hpp"
#include "cct_json.hpp"
#include "cct_string.hpp"
#include "curlhandle.hpp"
#include "currencycode.hpp"
#include "exchangepublicapi.hpp"
Expand Down Expand Up @@ -42,9 +42,9 @@ class HuobiPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

WithdrawalFeesSet queryWithdrawalFees() override;
MonetaryAmountByCurrencySet queryWithdrawalFees() override;

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return true; }

Expand Down
9 changes: 5 additions & 4 deletions src/api/exchanges/include/krakenpublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once

#include <optional>

#include "cachedresult.hpp"
#include "cct_string.hpp"
#include "curlhandle.hpp"
#include "exchangepublicapi.hpp"
#include "exchangepublicapitypes.hpp"
Expand Down Expand Up @@ -35,9 +36,9 @@ class KrakenPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

WithdrawalFeesSet queryWithdrawalFees() override { return _withdrawalFeesCache.get().first; }
MonetaryAmountByCurrencySet queryWithdrawalFees() override { return _withdrawalFeesCache.get().first; }

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return false; }

Expand Down Expand Up @@ -76,7 +77,7 @@ class KrakenPublic : public ExchangePublic {
class WithdrawalFeesFunc {
public:
using WithdrawalMinMap = std::unordered_map<CurrencyCode, MonetaryAmount>;
using WithdrawalInfoMaps = std::pair<WithdrawalFeesSet, WithdrawalMinMap>;
using WithdrawalInfoMaps = std::pair<MonetaryAmountByCurrencySet, WithdrawalMinMap>;

WithdrawalFeesFunc(const CoincenterInfo& coincenterInfo, Duration minDurationBetweenQueries);

Expand Down
8 changes: 3 additions & 5 deletions src/api/exchanges/include/kucoinpublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#pragma once

#include <limits>
#include <optional>
#include <string_view>
#include <unordered_map>

#include "cachedresult.hpp"
#include "cct_flatset.hpp"
#include "cct_json.hpp"
#include "cct_string.hpp"
#include "curlhandle.hpp"
#include "curlpostdata.hpp"
#include "currencycode.hpp"
Expand Down Expand Up @@ -44,9 +42,9 @@ class KucoinPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

WithdrawalFeesSet queryWithdrawalFees() override;
MonetaryAmountByCurrencySet queryWithdrawalFees() override;

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return true; }

Expand Down
4 changes: 2 additions & 2 deletions src/api/exchanges/include/upbitprivateapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class UpbitPrivate : public ExchangePrivate {

WithdrawsSet queryRecentWithdraws(const WithdrawsConstraints& withdrawsConstraints = WithdrawsConstraints()) override;

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override {
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override {
return _withdrawalFeesCache.get(currencyCode);
}

Expand Down Expand Up @@ -70,7 +70,7 @@ class UpbitPrivate : public ExchangePrivate {
};

struct WithdrawFeesFunc {
MonetaryAmount operator()(CurrencyCode currencyCode);
std::optional<MonetaryAmount> operator()(CurrencyCode currencyCode);

CurlHandle& _curlHandle;
const APIKey& _apiKey;
Expand Down
7 changes: 4 additions & 3 deletions src/api/exchanges/include/upbitpublicapi.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <optional>
#include <string_view>

#include "cachedresult.hpp"
Expand Down Expand Up @@ -33,9 +34,9 @@ class UpbitPublic : public ExchangePublic {

MarketPriceMap queryAllPrices() override { return MarketPriceMapFromMarketOrderBookMap(_allOrderBooksCache.get(1)); }

WithdrawalFeesSet queryWithdrawalFees() override { return _withdrawalFeesCache.get(); }
MonetaryAmountByCurrencySet queryWithdrawalFees() override { return _withdrawalFeesCache.get(); }

MonetaryAmount queryWithdrawalFee(CurrencyCode currencyCode) override;
std::optional<MonetaryAmount> queryWithdrawalFee(CurrencyCode currencyCode) override;

bool isWithdrawalFeesSourceReliable() const override { return true; }

Expand Down Expand Up @@ -79,7 +80,7 @@ class UpbitPublic : public ExchangePublic {
};

struct WithdrawalFeesFunc {
WithdrawalFeesSet operator()();
MonetaryAmountByCurrencySet operator()();

const string& _name;
std::string_view _dataDir;
Expand Down
10 changes: 5 additions & 5 deletions src/api/exchanges/src/binanceprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ WithdrawsSet BinancePrivate::queryRecentWithdraws(const WithdrawsConstraints& wi
return withdrawsSet;
}

WithdrawalFeesSet BinancePrivate::AllWithdrawFeesFunc::operator()() {
MonetaryAmountByCurrencySet BinancePrivate::AllWithdrawFeesFunc::operator()() {
json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/sapi/v1/asset/assetDetail", _queryDelay);
vector<MonetaryAmount> fees;
for (const auto& [curCodeStr, withdrawFeeDetails] : result.items()) {
Expand All @@ -551,20 +551,20 @@ WithdrawalFeesSet BinancePrivate::AllWithdrawFeesFunc::operator()() {
fees.emplace_back(withdrawFeeDetails["withdrawFee"].get<std::string_view>(), cur);
}
}
return WithdrawalFeesSet(std::move(fees));
return MonetaryAmountByCurrencySet(std::move(fees));
}

MonetaryAmount BinancePrivate::WithdrawFeesFunc::operator()(CurrencyCode currencyCode) {
std::optional<MonetaryAmount> BinancePrivate::WithdrawFeesFunc::operator()(CurrencyCode currencyCode) {
json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/sapi/v1/asset/assetDetail", _queryDelay,
{{"asset", currencyCode.str()}});
if (!result.contains(currencyCode.str())) {
throw exception("Unable to find asset information in assetDetail query to Binance");
return {};
}
const json& withdrawFeeDetails = result[currencyCode.str()];
if (!withdrawFeeDetails["withdrawStatus"].get<bool>()) {
log::error("{} is currently unavailable for withdraw from {}", currencyCode, _exchangePublic.name());
}
return {withdrawFeeDetails["withdrawFee"].get<std::string_view>(), currencyCode};
return MonetaryAmount(withdrawFeeDetails["withdrawFee"].get<std::string_view>(), currencyCode);
}

namespace {
Expand Down
Loading

0 comments on commit dba81d7

Please sign in to comment.