Skip to content

Commit

Permalink
Increase maximum number of characters of currency code to 10. Throw i…
Browse files Browse the repository at this point in the history
…nvalid argument if MonetaryAmount is built with a CurrencyCode too long, and in CLI as well
  • Loading branch information
sjanel committed Oct 26, 2022
1 parent d6637ee commit 82f30a7
Show file tree
Hide file tree
Showing 39 changed files with 657 additions and 336 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.15)

project(coincenter VERSION 3.16.1
project(coincenter VERSION 3.17.0
DESCRIPTION "A C++ library centralizing several crypto currencies exchanges REST API into a single all in one tool with a unified interface"
LANGUAGES CXX)

Expand Down
4 changes: 2 additions & 2 deletions src/api-objects/include/ordersconstraints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ class OrdersConstraints {

Market market() const { return Market(_cur1, _cur2); }

std::string_view curStr1() const { return _cur1.str(); }
std::string_view curStr2() const { return _cur2.str(); }
string curStr1() const { return _cur1.str(); }
string curStr2() const { return _cur2.str(); }

CurrencyCode cur1() const { return _cur1; }
CurrencyCode cur2() const { return _cur2; }
Expand Down
4 changes: 2 additions & 2 deletions src/api-objects/src/ordersconstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ OrdersConstraints::OrdersConstraints(CurrencyCode cur1, CurrencyCode cur2, Durat
string OrdersConstraints::str() const {
string ret;
if (isCur1Defined()) {
ret.append(_cur1.str());
_cur1.appendStr(ret);
}
if (isCur2Defined()) {
ret.push_back('-');
ret.append(_cur2.str());
_cur2.appendStr(ret);
}
if (ret.empty()) {
ret.append("any");
Expand Down
2 changes: 1 addition & 1 deletion src/api/common/src/cryptowatchapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ CryptowatchAPI::Fiats CryptowatchAPI::FiatsFunc::operator()() {
auto foundIt = assetDetails.find("fiat");
if (foundIt != assetDetails.end() && foundIt->get<bool>()) {
CurrencyCode fiatCode(assetDetails["symbol"].get<std::string_view>());
log::debug("Storing fiat {}", fiatCode.str());
log::debug("Storing fiat {}", fiatCode);
fiats.insert(std::move(fiatCode));
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/api/common/src/exchangeprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void ExchangePrivate::addBalance(BalancePortfolio &balancePortfolio, MonetaryAmo
if (optConvertedAmountEquiCurrency) {
equivalentInMainCurrency = *optConvertedAmountEquiCurrency;
} else {
log::warn("Cannot convert {} into {} on {}", amount.currencyStr(), equiCurrency.str(), _exchangePublic.name());
log::warn("Cannot convert {} into {} on {}", amount.currencyStr(), equiCurrency, _exchangePublic.name());
equivalentInMainCurrency = MonetaryAmount(0, equiCurrency);
}
log::debug("{} Balance {} (eq. {})", _exchangePublic.name(), amount.str(), equivalentInMainCurrency.str());
Expand All @@ -45,22 +45,22 @@ TradedAmounts ExchangePrivate::trade(MonetaryAmount from, CurrencyCode toCurrenc
const int nbTrades = static_cast<int>(conversionPath.size());
const bool isMultiTradeAllowed = options.isMultiTradeAllowed(exchangeInfo().multiTradeAllowedByDefault());
log::info("{}rade {} -> {} on {}_{} requested", isMultiTradeAllowed && nbTrades > 1 ? "Multi t" : "T", from.str(),
toCurrency.str(), _exchangePublic.name(), keyName());
toCurrency, _exchangePublic.name(), keyName());
TradedAmounts tradedAmounts(from.currencyCode(), toCurrency);
if (conversionPath.empty()) {
log::warn("Cannot trade {} into {} on {}", from.str(), toCurrency.str(), _exchangePublic.name());
log::warn("Cannot trade {} into {} on {}", from.str(), toCurrency, _exchangePublic.name());
return tradedAmounts;
}
if (nbTrades > 1 && !isMultiTradeAllowed) {
log::error("Can only convert {} to {} in {} steps, but multi trade is not allowed, aborting", from.str(),
toCurrency.str(), nbTrades);
toCurrency, nbTrades);
return tradedAmounts;
}
MonetaryAmount avAmount = from;
for (int tradePos = 0; tradePos < nbTrades; ++tradePos) {
Market m = conversionPath[tradePos];
log::info("Step {}/{} - trade {} into {}", tradePos + 1, nbTrades, avAmount.str(),
m.opposite(avAmount.currencyCode()).str());
m.opposite(avAmount.currencyCode()));
TradedAmounts stepTradedAmounts = marketTrade(avAmount, options, m);
avAmount = stepTradedAmounts.tradedTo;
if (avAmount.isZero()) {
Expand Down
6 changes: 3 additions & 3 deletions src/api/common/src/exchangepublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ MarketsPath ExchangePublic::findMarketsPath(CurrencyCode fromCurrency, CurrencyC
const Fiats &fiats, bool considerStableCoinsAsFiats) {
MarketsPath ret;
if (fromCurrency == toCurrency) {
log::warn("Cannot convert {} to itself", fromCurrency.str());
log::warn("Cannot convert {} to itself", fromCurrency);
return ret;
}

Expand Down Expand Up @@ -239,7 +239,7 @@ std::optional<Market> ExchangePublic::determineMarketFromMarketStr(std::string_v

if (!filterCur.isNeutral()) {
std::size_t firstCurLen;
std::string_view curStr = filterCur.str();
auto curStr = filterCur.str();
std::size_t curPos = marketStr.find(curStr);
if (curPos == 0) {
firstCurLen = curStr.size();
Expand Down Expand Up @@ -317,7 +317,7 @@ Market ExchangePublic::determineMarketFromFilterCurrencies(MarketSet &markets, C
if (tryAppendBaseCurrency(filterCur2)) {
tryAppendQuoteCurrency(filterCur2, filterCur1);
} else {
log::debug("Cannot find {} among {} markets", filterCur1.str(), name());
log::debug("Cannot find {} among {} markets", filterCur1, name());
}
}
return ret;
Expand Down
13 changes: 6 additions & 7 deletions src/api/exchanges/src/binanceprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ Orders BinancePrivate::queryOpenedOrders(const OrdersConstraints& openedOrdersCo
}
json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/api/v3/openOrders", std::move(params));

std::string_view cur1Str = openedOrdersConstraints.curStr1();
std::string_view cur2Str = openedOrdersConstraints.curStr2();
auto cur1Str = openedOrdersConstraints.curStr1();
auto cur2Str = openedOrdersConstraints.curStr2();
MarketSet markets;
for (const json& orderDetails : result) {
std::string_view marketStr = orderDetails["symbol"].get<std::string_view>(); // already higher case
Expand Down Expand Up @@ -253,7 +253,7 @@ MonetaryAmount BinancePrivate::WithdrawFeesFunc::operator()(CurrencyCode currenc
}
const json& withdrawFeeDetails = result[string(currencyCode.str())];
if (!withdrawFeeDetails["withdrawStatus"].get<bool>()) {
log::error("{} is currently unavailable for withdraw from {}", currencyCode.str(), _exchangePublic.name());
log::error("{} is currently unavailable for withdraw from {}", currencyCode, _exchangePublic.name());
}
return MonetaryAmount(withdrawFeeDetails["withdrawFee"].get<std::string_view>(), currencyCode);
}
Expand Down Expand Up @@ -314,8 +314,7 @@ PlaceOrderInfo BinancePrivate::placeOrder(MonetaryAmount from, MonetaryAmount vo
static constexpr CurrencyCode kBinanceCoinCur("BNB");
if (!isSimulation && toCurrencyCode == kBinanceCoinCur) {
// Use special Binance Dust transfer
log::info("Volume too low for standard trade, but we can use Dust transfer to trade to {}",
kBinanceCoinCur.str());
log::info("Volume too low for standard trade, but we can use Dust transfer to trade to {}", kBinanceCoinCur);
json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kPost, "/sapi/v1/asset/dust",
{{"asset", from.currencyStr()}});
if (!result.contains("transferResult") || result["transferResult"].empty()) {
Expand All @@ -326,8 +325,8 @@ PlaceOrderInfo BinancePrivate::placeOrder(MonetaryAmount from, MonetaryAmount vo
MonetaryAmount netTransferredAmount(res["transferedAmount"].get<std::string_view>(), kBinanceCoinCur);
placeOrderInfo.tradedAmounts() += TradedAmounts(from, netTransferredAmount);
} else {
log::warn("No trade of {} into {} because min vol order is {} for this market", volume.str(),
toCurrencyCode.str(), sanitizedVol.str());
log::warn("No trade of {} into {} because min vol order is {} for this market", volume.str(), toCurrencyCode,
sanitizedVol.str());
}

placeOrderInfo.setClosed();
Expand Down
8 changes: 4 additions & 4 deletions src/api/exchanges/src/binancepublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ CurrencyExchangeFlatSet BinancePublic::queryTradableCurrencies(const json& data)
const ExchangeInfo::CurrencySet& excludedCurrencies = _commonInfo._exchangeInfo.excludedCurrenciesAll();
for (const json& el : data) {
std::string_view coin = el["coin"].get<std::string_view>();
if (coin.size() > CurrencyCode::kAcronymMaxLen) {
if (coin.size() > CurrencyCode::kMaxLen) {
continue;
}
CurrencyCode cur(coin);
Expand Down Expand Up @@ -165,7 +165,7 @@ BinancePublic::ExchangeInfoFunc::ExchangeInfoDataByMarket BinancePublic::Exchang
log::trace("Discard {}-{} as coincenter does not support leveraged markets", baseAsset, quoteAsset);
continue;
}
if (baseAsset.size() > CurrencyCode::kAcronymMaxLen || quoteAsset.size() > CurrencyCode::kAcronymMaxLen) {
if (baseAsset.size() > CurrencyCode::kMaxLen || quoteAsset.size() > CurrencyCode::kMaxLen) {
log::trace("Discard {}-{} as one asset is too long", baseAsset, quoteAsset);
continue;
}
Expand Down Expand Up @@ -227,7 +227,7 @@ WithdrawalFeeMap BinancePublic::queryWithdrawalFees() {
WithdrawalFeeMap ret;
for (const json& el : _globalInfosCache.get()) {
std::string_view coinStr = el["coin"].get<std::string_view>();
if (coinStr.size() > CurrencyCode::kAcronymMaxLen) {
if (coinStr.size() > CurrencyCode::kMaxLen) {
continue;
}
CurrencyCode cur(coinStr);
Expand All @@ -249,7 +249,7 @@ MonetaryAmount BinancePublic::queryWithdrawalFee(CurrencyCode currencyCode) {
}
}
string ex("Unable to find withdrawal fee for ");
ex.append(currencyCode.str());
currencyCode.appendStr(ex);
throw exception(std::move(ex));
}

Expand Down
26 changes: 13 additions & 13 deletions src/api/exchanges/src/bithumbprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ Wallet BithumbPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode)
json ret = PrivateQuery(_curlHandle, _apiKey, kWalletAddressEndpointStr, {{"currency", currencyCode.str()}});
if (ret.empty()) {
string err("Bithumb wallet is not created for ");
err.append(currencyCode.str());
currencyCode.appendStr(err);
err.append(", it should be done with the UI first (no way to do it via API).");
throw exception(std::move(err));
}
Expand Down Expand Up @@ -315,7 +315,7 @@ Orders BithumbPrivate::queryOpenedOrders(const OrdersConstraints& openedOrdersCo
if (!filterMarket.base().isNeutral()) {
orderCurrencies.push_back(filterMarket.base());
if (!filterMarket.quote().isNeutral()) {
params.append(kPaymentCurParamStr, filterMarket.quoteStr());
params.append(kPaymentCurParamStr, filterMarket.quote().str());
}
}
} else {
Expand Down Expand Up @@ -399,7 +399,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
const Market m = tradeInfo.m;

// It seems Bithumb uses "standard" currency codes, no need to translate them
CurlPostData placePostData{{kOrderCurrencyParamStr, m.baseStr()}, {kPaymentCurParamStr, m.quoteStr()}};
CurlPostData placePostData{{kOrderCurrencyParamStr, m.base().str()}, {kPaymentCurParamStr, m.quote().str()}};
const std::string_view orderType = fromCurrencyCode == m.base() ? "ask" : "bid";

string endpoint("/trade/");
Expand Down Expand Up @@ -430,7 +430,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
volume.truncate(nbMaxDecimalsUnits);
if (volume.isZero()) {
log::warn("No trade of {} into {} because min number of decimals is {} for this market", volume.str(),
toCurrencyCode.str(), static_cast<int>(nbMaxDecimalsUnits));
toCurrencyCode, static_cast<int>(nbMaxDecimalsUnits));
placeOrderInfo.setClosed();
return placeOrderInfo;
}
Expand All @@ -455,8 +455,8 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
}
placePostData.set("price", price.amountStr());
} else {
log::warn("No trade of {} into {} because {} is outside price bounds [{}, {}]", volume.str(),
toCurrencyCode.str(), price.str(), minOrderPrice.str(), maxOrderPrice.str());
log::warn("No trade of {} into {} because {} is outside price bounds [{}, {}]", volume.str(), toCurrencyCode,
price.str(), minOrderPrice.str(), maxOrderPrice.str());
placeOrderInfo.setClosed();
return placeOrderInfo;
}
Expand All @@ -474,7 +474,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
log::error("Unexpected currency for min order size {}", size.str());
}
if (size < currencyOrderInfo.minOrderSize && !isSimulationWithRealOrder) {
log::warn("No trade of {} into {} because {} is lower than min order {}", volume.str(), toCurrencyCode.str(),
log::warn("No trade of {} into {} because {} is lower than min order {}", volume.str(), toCurrencyCode,
size.str(), currencyOrderInfo.minOrderSize.str());
placeOrderInfo.setClosed();
return placeOrderInfo;
Expand Down Expand Up @@ -503,8 +503,8 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
volume = MonetaryAmount(currencyOrderInfo.minOrderSize / price, volume.currencyCode());
placePostData.set("units", volume.amountStr());
} else {
log::warn("No trade of {} into {} because min order size is {} for this market", volume.str(),
toCurrencyCode.str(), currencyOrderInfo.minOrderSize.str());
log::warn("No trade of {} into {} because min order size is {} for this market", volume.str(), toCurrencyCode,
currencyOrderInfo.minOrderSize.str());
break;
}
} else if (LoadCurrencyInfoField(result, kMinOrderPriceJsonKeyStr, currencyOrderInfo.minOrderPrice,
Expand All @@ -516,7 +516,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
}
} else {
log::warn("No trade of {} into {} because min order price is {} for this market", volume.str(),
toCurrencyCode.str(), currencyOrderInfo.minOrderPrice.str());
toCurrencyCode, currencyOrderInfo.minOrderPrice.str());
break;
}
} else if (LoadCurrencyInfoField(result, kMaxOrderPriceJsonKeyStr, currencyOrderInfo.maxOrderPrice,
Expand All @@ -528,7 +528,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
}
} else {
log::warn("No trade of {} into {} because max order price is {} for this market", volume.str(),
toCurrencyCode.str(), currencyOrderInfo.maxOrderPrice.str());
toCurrencyCode, currencyOrderInfo.maxOrderPrice.str());
break;
}
} else {
Expand Down Expand Up @@ -557,8 +557,8 @@ OrderInfo BithumbPrivate::cancelOrder(const OrderRef& orderRef) {
namespace {
CurlPostData OrderInfoPostData(Market m, TradeSide side, std::string_view id) {
CurlPostData ret;
std::string_view baseStr = m.baseStr();
std::string_view quoteStr = m.quoteStr();
auto baseStr = m.base().str();
auto quoteStr = m.quote().str();
ret.reserve(kOrderCurrencyParamStr.size() + kPaymentCurParamStr.size() + kTypeParamStr.size() +
kOrderIdParamStr.size() + baseStr.size() + quoteStr.size() + id.size() + 10U);
ret.append(kOrderCurrencyParamStr, baseStr);
Expand Down
6 changes: 3 additions & 3 deletions src/api/exchanges/src/bithumbpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ json PublicQuery(CurlHandle& curlHandle, std::string_view endpoint, CurrencyCode
CurrencyCode quote = CurrencyCode(), std::string_view urlOpts = "") {
string methodUrl(endpoint);
methodUrl.push_back('/');
methodUrl.append(base.str());
base.appendStr(methodUrl);
if (!quote.isNeutral()) {
methodUrl.push_back('_');
methodUrl.append(quote.str());
quote.appendStr(methodUrl);
}
if (!urlOpts.empty()) {
methodUrl.push_back('?');
Expand Down Expand Up @@ -216,7 +216,7 @@ MarketOrderBookMap GetOrderbooks(CurlHandle& curlHandle, const CoincenterInfo& c
baseCurrencyCode = CurrencyCode(config.standardizeCurrencyCode(baseOrSpecial));
if (excludedCurrencies.contains(baseCurrencyCode)) {
// Forbidden currency, do not consider its market
log::trace("Discard {} excluded by config", baseCurrencyCode.str());
log::trace("Discard {} excluded by config", baseCurrencyCode);
continue;
}
asksBids[0] = std::addressof(asksAndBids["asks"]);
Expand Down
10 changes: 5 additions & 5 deletions src/api/exchanges/src/huobiprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ PlaceOrderInfo HuobiPrivate::placeOrder(MonetaryAmount from, MonetaryAmount volu
MonetaryAmount sanitizedVol = huobiPublic.sanitizeVolume(m, fromCurrencyCode, volume, price, isTakerStrategy);
const bool isSimulationWithRealOrder = tradeInfo.options.isSimulation() && placeSimulatedRealOrder;
if (volume < sanitizedVol && !isSimulationWithRealOrder) {
log::warn("No trade of {} into {} because min vol order is {} for this market", volume.str(), toCurrencyCode.str(),
log::warn("No trade of {} into {} because min vol order is {} for this market", volume.str(), toCurrencyCode,
sanitizedVol.str());
placeOrderInfo.setClosed();
return placeOrderInfo;
Expand Down Expand Up @@ -367,16 +367,16 @@ InitiatedWithdrawInfo HuobiPrivate::launchWithdraw(MonetaryAmount grossAmount, W
MonetaryAmount netEmittedAmount = grossAmount - fee;
if (!withdrawParams.minWithdrawAmt.isDefault() && netEmittedAmount < withdrawParams.minWithdrawAmt) {
string err("Minimum withdraw amount for ");
err.append(currencyCode.str())
.append(" on Huobi is ")
currencyCode.appendStr(err);
err.append(" on Huobi is ")
.append(withdrawParams.minWithdrawAmt.amountStr())
.append(", cannot withdraw ")
.append(netEmittedAmount.str());
throw exception(std::move(err));
} else if (!withdrawParams.maxWithdrawAmt.isDefault() && netEmittedAmount > withdrawParams.maxWithdrawAmt) {
string err("Maximum withdraw amount for ");
err.append(currencyCode.str())
.append(" on Huobi is ")
currencyCode.appendStr(err);
err.append(" on Huobi is ")
.append(withdrawParams.maxWithdrawAmt.amountStr())
.append(", cannot withdraw ")
.append(netEmittedAmount.str());
Expand Down
8 changes: 5 additions & 3 deletions src/api/exchanges/src/huobipublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ CurrencyExchangeFlatSet HuobiPublic::queryTradableCurrencies() {
break;
}
if (!foundChainWithSameName) {
log::debug("Cannot find {} main chain in Huobi, discarding currency", cur.str());
log::debug("Cannot find {} main chain in Huobi, discarding currency", cur);
}
}
CurrencyExchangeFlatSet ret(std::move(currencies));
Expand Down Expand Up @@ -150,7 +150,7 @@ std::pair<MarketSet, HuobiPublic::MarketsFunc::MarketInfoMap> HuobiPublic::Marke
log::trace("Trading is {} for market {}-{}", stateStr, baseAsset, quoteAsset);
continue;
}
if (baseAsset.size() > CurrencyCode::kAcronymMaxLen || quoteAsset.size() > CurrencyCode::kAcronymMaxLen) {
if (baseAsset.size() > CurrencyCode::kMaxLen || quoteAsset.size() > CurrencyCode::kMaxLen) {
log::trace("Discard {}-{} as one asset is too long", baseAsset, quoteAsset);
continue;
}
Expand Down Expand Up @@ -247,7 +247,9 @@ MonetaryAmount HuobiPublic::queryWithdrawalFee(CurrencyCode currencyCode) {
}
}
}
throw exception("Unable to find withdrawal fee for " + string(currencyCode.str()));
string msg("Unable to find withdrawal fee for ");
currencyCode.appendStr(msg);
throw exception(std::move(msg));
}

MarketOrderBookMap HuobiPublic::AllOrderBooksFunc::operator()(int depth) {
Expand Down
Loading

0 comments on commit 82f30a7

Please sign in to comment.