Skip to content

Commit

Permalink
Refactor hexadecimal char converter
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Mar 29, 2024
1 parent 8714b3d commit c30d045
Show file tree
Hide file tree
Showing 22 changed files with 351 additions and 214 deletions.
2 changes: 2 additions & 0 deletions src/api/common/include/exchangebase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class CacheFreezerRAII {
return *this;
}

void swap(CacheFreezerRAII &rhs) noexcept { std::swap(_pCachedResultVault, rhs._pCachedResultVault); }

~CacheFreezerRAII() {
if (_pCachedResultVault != nullptr) {
_pCachedResultVault->unfreezeAll();
Expand Down
30 changes: 15 additions & 15 deletions src/api/exchanges/src/binanceprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void SetNonceAndSignature(const APIKey& apiKey, CurlPostData& postData, Duration
postData.pop_back();
}

postData.push_back(kSignatureKey, ssl::ShaHex(ssl::ShaType::kSha256, postData.str(), apiKey.privateKey()));
postData.emplace_back(kSignatureKey, ssl::ShaHex(ssl::ShaType::kSha256, postData.str(), apiKey.privateKey()));
}

bool CheckErrorDoRetry(int statusCode, const json& ret, QueryDelayDir& queryDelayDir, Duration& sleepingTime,
Expand Down Expand Up @@ -305,7 +305,7 @@ bool BinancePrivate::checkMarketAppendSymbol(Market mk, CurlPostData& params) {
if (!optMarket) {
return false;
}
params.push_back("symbol", optMarket->assetsPairStrUpper());
params.emplace_back("symbol", optMarket->assetsPairStrUpper());
return true;
}

Expand Down Expand Up @@ -381,10 +381,10 @@ ClosedOrderVector BinancePrivate::queryClosedOrders(const OrdersConstraints& clo
return closedOrders;
}
if (closedOrdersConstraints.isPlacedTimeAfterDefined()) {
params.push_back("startTime", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedAfter()));
params.emplace_back("startTime", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedAfter()));
}
if (closedOrdersConstraints.isPlacedTimeBeforeDefined()) {
params.push_back("endTime", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedBefore()));
params.emplace_back("endTime", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedBefore()));
}
const json result =
PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/api/v3/allOrders", _queryDelay, std::move(params));
Expand Down Expand Up @@ -485,17 +485,17 @@ DepositsSet BinancePrivate::queryRecentDeposits(const DepositsConstraints& depos
Deposits deposits;
CurlPostData options;
if (depositsConstraints.isCurDefined()) {
options.push_back("coin", depositsConstraints.currencyCode().str());
options.emplace_back("coin", depositsConstraints.currencyCode().str());
}
if (depositsConstraints.isTimeAfterDefined()) {
options.push_back("startTime", TimestampToMillisecondsSinceEpoch(depositsConstraints.timeAfter()));
options.emplace_back("startTime", TimestampToMillisecondsSinceEpoch(depositsConstraints.timeAfter()));
}
if (depositsConstraints.isTimeBeforeDefined()) {
options.push_back("endTime", TimestampToMillisecondsSinceEpoch(depositsConstraints.timeBefore()));
options.emplace_back("endTime", TimestampToMillisecondsSinceEpoch(depositsConstraints.timeBefore()));
}
if (depositsConstraints.isIdDefined()) {
if (depositsConstraints.idSet().size() == 1) {
options.push_back("txId", depositsConstraints.idSet().front());
options.emplace_back("txId", depositsConstraints.idSet().front());
}
}
json depositStatus = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/sapi/v1/capital/deposit/hisrec",
Expand Down Expand Up @@ -574,13 +574,13 @@ TimePoint RetrieveTimeStampFromWithdrawJson(const json& withdrawJson) {
CurlPostData CreateOptionsFromWithdrawConstraints(const WithdrawsConstraints& withdrawsConstraints) {
CurlPostData options;
if (withdrawsConstraints.isCurDefined()) {
options.push_back("coin", withdrawsConstraints.currencyCode().str());
options.emplace_back("coin", withdrawsConstraints.currencyCode().str());
}
if (withdrawsConstraints.isTimeAfterDefined()) {
options.push_back("startTime", TimestampToMillisecondsSinceEpoch(withdrawsConstraints.timeAfter()));
options.emplace_back("startTime", TimestampToMillisecondsSinceEpoch(withdrawsConstraints.timeAfter()));
}
if (withdrawsConstraints.isTimeBeforeDefined()) {
options.push_back("endTime", TimestampToMillisecondsSinceEpoch(withdrawsConstraints.timeBefore()));
options.emplace_back("endTime", TimestampToMillisecondsSinceEpoch(withdrawsConstraints.timeBefore()));
}
return options;
}
Expand Down Expand Up @@ -719,8 +719,8 @@ PlaceOrderInfo BinancePrivate::placeOrder(MonetaryAmount from, MonetaryAmount vo
{"symbol", mk.assetsPairStrUpper()}, {"side", buyOrSell}, {"type", orderType}, {"quantity", volume.amountStr()}};

if (!isTakerStrategy) {
placePostData.push_back("timeInForce", "GTC");
placePostData.push_back("price", price.amountStr());
placePostData.emplace_back("timeInForce", "GTC");
placePostData.emplace_back("price", price.amountStr());
}

const std::string_view methodName = isSimulation ? "/api/v3/order/test" : "/api/v3/order";
Expand Down Expand Up @@ -768,7 +768,7 @@ OrderInfo BinancePrivate::queryOrder(OrderIdView orderId, const TradeContext& tr
CurlPostData myTradesOpts{{"symbol", assets}};
auto timeIt = result.find("time");
if (timeIt != result.end()) {
myTradesOpts.push_back("startTime", timeIt->get<int64_t>() - 100L); // -100 just to be sure
myTradesOpts.emplace_back("startTime", timeIt->get<int64_t>() - 100L); // -100 just to be sure
}
result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/api/v3/myTrades", _queryDelay, myTradesOpts);
int64_t integralOrderId = FromString<int64_t>(orderId);
Expand All @@ -786,7 +786,7 @@ InitiatedWithdrawInfo BinancePrivate::launchWithdraw(MonetaryAmount grossAmount,
CurlPostData withdrawPostData{
{"coin", currencyCode.str()}, {"address", destinationWallet.address()}, {"amount", grossAmount.amountStr()}};
if (destinationWallet.hasTag()) {
withdrawPostData.push_back("addressTag", destinationWallet.tag());
withdrawPostData.emplace_back("addressTag", destinationWallet.tag());
}
json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kPost, "/sapi/v1/capital/withdraw/apply",
_queryDelay, std::move(withdrawPostData));
Expand Down
37 changes: 19 additions & 18 deletions src/api/exchanges/src/bithumbprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ template <class CurlPostDataT = CurlPostData>
json PrivateQuery(CurlHandle& curlHandle, const APIKey& apiKey, std::string_view endpoint,
CurlPostDataT&& curlPostData = CurlPostData()) {
CurlPostData postData(std::forward<CurlPostDataT>(curlPostData));
postData.push_front("endpoint", endpoint);
postData.emplace_front("endpoint", endpoint);

CurlOptions opts(HttpRequestType::kPost, postData.urlEncodeExceptDelimiters());

return PrivateQueryProcessWithRetries(curlHandle, apiKey, endpoint, std::move(opts));
Expand Down Expand Up @@ -354,12 +355,12 @@ BalancePortfolio BithumbPrivate::queryAccountBalance(const BalanceOptions& balan
json jsonReply = PrivateQuery(_curlHandle, _apiKey, "/info/balance", {{"currency", "all"}});

BalancePortfolio balancePortfolio;

const auto balanceItemsIt = jsonReply.find("data");
if (jsonReply.is_discarded()) {
log::error("Badly formatted {} reply from balance", exchangeName());
return balancePortfolio;
}

const auto balanceItemsIt = jsonReply.find("data");
if (balanceItemsIt == jsonReply.end()) {
return balancePortfolio;
}
Expand Down Expand Up @@ -448,7 +449,7 @@ auto FillOrderCurrencies(const OrdersConstraints& ordersConstraints, ExchangePub
if (!filterMarket.base().isNeutral()) {
orderCurrencies.push_back(filterMarket.base());
if (!filterMarket.quote().isNeutral()) {
params.push_back(kPaymentCurParamStr, filterMarket.quote().str());
params.emplace_back(kPaymentCurParamStr, filterMarket.quote().str());
}
}
} else {
Expand Down Expand Up @@ -496,7 +497,7 @@ OrderVectorType QueryOrders(const OrdersConstraints& ordersConstraints, Exchange

OrderVectorType orders;
if (ordersConstraints.isPlacedTimeAfterDefined()) {
params.push_back("after", TimestampToMillisecondsSinceEpoch(ordersConstraints.placedAfter()));
params.emplace_back("after", TimestampToMillisecondsSinceEpoch(ordersConstraints.placedAfter()));
}
if (orderCurrencies.size() > 1) {
if constexpr (std::is_same_v<OrderType, ClosedOrder>) {
Expand Down Expand Up @@ -659,16 +660,16 @@ json QueryUserTransactions(BithumbPrivate& exchangePrivate, CurlHandle& curlHand
if (userTransactionEnum == UserTransactionEnum::kClosedOrders) {
if constexpr (std::is_same_v<ConstraintsType, OrdersConstraints>) {
if (constraints.isCur2Defined()) {
options.push_back(kPaymentCurParamStr, constraints.curStr2());
options.emplace_back(kPaymentCurParamStr, constraints.curStr2());
} else {
options.push_back(kPaymentCurParamStr, "KRW");
options.emplace_back(kPaymentCurParamStr, "KRW");
}
}
} else {
// It's not clear what the payment currency option is for user_transactions endpoint for deposits and withdraws.
// For withdraws it seems to have no impact, and even worse, it returns weird output when
// querying withdraws for a specific coin, it can return KRW withdraws to user bank account.
options.push_back(kPaymentCurParamStr, "BTC");
options.emplace_back(kPaymentCurParamStr, "BTC");
}

json allResults;
Expand Down Expand Up @@ -857,8 +858,8 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
endpoint.append(fromCurrencyCode == mk.base() ? "market_sell" : "market_buy");
} else {
endpoint.append("place");
placePostData.push_back(kTypeParamStr, orderType);
placePostData.push_back("price", price.amountStr());
placePostData.emplace_back(kTypeParamStr, orderType);
placePostData.emplace_back("price", price.amountStr());
}

// Volume is gross amount if from amount is in quote currency, we should remove the fees
Expand Down Expand Up @@ -933,7 +934,7 @@ PlaceOrderInfo BithumbPrivate::placeOrder(MonetaryAmount /*from*/, MonetaryAmoun
}
}

placePostData.push_back("units", volume.amountStr());
placePostData.emplace_back("units", volume.amountStr());

placeOrderInfo.setClosed();

Expand Down Expand Up @@ -1025,10 +1026,10 @@ CurlPostData OrderInfoPostData(Market mk, TradeSide side, OrderIdView orderId) {
ret.underlyingBufferReserve(kOrderCurrencyParamStr.size() + kPaymentCurParamStr.size() + kTypeParamStr.size() +
kOrderIdParamStr.size() + baseStr.size() + quoteStr.size() + orderId.size() + 10U);

ret.push_back(kOrderCurrencyParamStr, baseStr);
ret.push_back(kPaymentCurParamStr, quoteStr);
ret.push_back(kTypeParamStr, side == TradeSide::kSell ? "ask" : "bid");
ret.push_back(kOrderIdParamStr, orderId);
ret.emplace_back(kOrderCurrencyParamStr, baseStr);
ret.emplace_back(kPaymentCurParamStr, quoteStr);
ret.emplace_back(kTypeParamStr, side == TradeSide::kSell ? "ask" : "bid");
ret.emplace_back(kOrderIdParamStr, orderId);

return ret;
}
Expand Down Expand Up @@ -1116,14 +1117,14 @@ CurlPostData ComputeLaunchWithdrawCurlPostData(MonetaryAmount netEmittedAmount,
// coincenter can retrieve the account owner name automatically provided that the user filled the fields in the
// destination api key part in the secrets json file.
if (desAccountOwner.isFullyDefined()) {
withdrawPostData.push_back("en_name", desAccountOwner.enName());
withdrawPostData.push_back("ko_name", desAccountOwner.koName());
withdrawPostData.emplace_back("en_name", desAccountOwner.enName());
withdrawPostData.emplace_back("ko_name", desAccountOwner.koName());
} else {
log::error("Bithumb withdrawal needs further information for destination account");
log::error("it needs the English and Korean name of its owner so query will most probably fail");
}
if (destinationWallet.hasTag()) {
withdrawPostData.push_back("destination", destinationWallet.tag());
withdrawPostData.emplace_back("destination", destinationWallet.tag());
}
return withdrawPostData;
}
Expand Down
54 changes: 29 additions & 25 deletions src/api/exchanges/src/huobiprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "tradedamounts.hpp"
#include "tradeinfo.hpp"
#include "tradeside.hpp"
#include "url-encode.hpp"
#include "wallet.hpp"
#include "withdraw.hpp"
#include "withdrawinfo.hpp"
Expand Down Expand Up @@ -81,7 +82,9 @@ CurlOptions::PostDataFormat ComputePostDataFormat(HttpRequestType requestType, c

void SetNonceAndSignature(CurlHandle& curlHandle, const APIKey& apiKey, HttpRequestType requestType,
std::string_view endpoint, CurlPostData& postData, CurlPostData& signaturePostData) {
signaturePostData.set("Timestamp", URLEncode(Nonce_LiteralDate(kTimeYearToSecondTSeparatedFormat)));
auto isNotEncoded = [](char ch) { return isalnum(ch) || ch == '-' || ch == '.' || ch == '_' || ch == '~'; };

signaturePostData.set("Timestamp", URLEncode(Nonce_LiteralDate(kTimeYearToSecondTSeparatedFormat), isNotEncoded));

if (!postData.empty() && requestType == HttpRequestType::kGet) {
// Warning: Huobi expects that all parameters of the query are ordered lexicographically
Expand All @@ -98,11 +101,12 @@ void SetNonceAndSignature(CurlHandle& curlHandle, const APIKey& apiKey, HttpRequ
signaturePostData.pop_back();
}

signaturePostData.push_back(
kSignatureKey, URLEncode(B64Encode(ssl::ShaBin(
ssl::ShaType::kSha256,
BuildParamStr(requestType, curlHandle.getNextBaseUrl(), endpoint, signaturePostData.str()),
apiKey.privateKey()))));
signaturePostData.emplace_back(
kSignatureKey, URLEncode(B64Encode(ssl::ShaBin(ssl::ShaType::kSha256,
BuildParamStr(requestType, curlHandle.getNextBaseUrl(), endpoint,
signaturePostData.str()),
apiKey.privateKey())),
isNotEncoded));
}

json PrivateQuery(CurlHandle& curlHandle, const APIKey& apiKey, HttpRequestType requestType, std::string_view endpoint,
Expand Down Expand Up @@ -241,19 +245,19 @@ ClosedOrderVector HuobiPrivate::queryClosedOrders(const OrdersConstraints& close
CurlPostData params;

if (closedOrdersConstraints.isPlacedTimeBeforeDefined()) {
params.push_back("end-time", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedBefore()));
params.emplace_back("end-time", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedBefore()));
}
if (closedOrdersConstraints.isPlacedTimeAfterDefined()) {
params.push_back("start-time", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedAfter()));
params.emplace_back("start-time", TimestampToMillisecondsSinceEpoch(closedOrdersConstraints.placedAfter()));
}

if (closedOrdersConstraints.isMarketDefined()) {
// we can use the more detailed endpoint that requires the market

// Do not ask for cancelled orders without any matched part
params.push_back("states", "filled");
params.emplace_back("states", "filled");

params.push_back("symbol", closedOrdersConstraints.market().assetsPairStrLower());
params.emplace_back("symbol", closedOrdersConstraints.market().assetsPairStrLower());
} else {
// Only past 48h orders may be retrieved without market
}
Expand Down Expand Up @@ -323,7 +327,7 @@ OpenedOrderVector HuobiPrivate::queryOpenedOrders(const OrdersConstraints& opene
openedOrdersConstraints.cur2());

if (filterMarket.isDefined()) {
params.push_back("symbol", filterMarket.assetsPairStrLower());
params.emplace_back("symbol", filterMarket.assetsPairStrLower());
}
}

Expand Down Expand Up @@ -411,10 +415,10 @@ DepositsSet HuobiPrivate::queryRecentDeposits(const DepositsConstraints& deposit
Deposits deposits;
CurlPostData options;
if (depositsConstraints.isCurDefined()) {
options.push_back("currency", ToLower(depositsConstraints.currencyCode().str()));
options.emplace_back("currency", ToLower(depositsConstraints.currencyCode().str()));
}
options.push_back("size", 500);
options.push_back("type", "deposit");
options.emplace_back("size", 500);
options.emplace_back("type", "deposit");
json data =
PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/v1/query/deposit-withdraw", std::move(options));
const auto dataIt = data.find("data");
Expand Down Expand Up @@ -533,10 +537,10 @@ Withdraw::Status WithdrawStatusFromStatusStr(std::string_view statusStr, bool lo
CurlPostData CreateOptionsFromWithdrawConstraints(const WithdrawsConstraints& withdrawsConstraints) {
CurlPostData options;
if (withdrawsConstraints.isCurDefined()) {
options.push_back("currency", ToLower(withdrawsConstraints.currencyCode().str()));
options.emplace_back("currency", ToLower(withdrawsConstraints.currencyCode().str()));
}
options.push_back("size", 500);
options.push_back("type", "withdraw");
options.emplace_back("size", 500);
options.emplace_back("type", "withdraw");
return options;
}
} // namespace
Expand Down Expand Up @@ -640,10 +644,10 @@ PlaceOrderInfo HuobiPrivate::placeOrder(MonetaryAmount from, MonetaryAmount volu
placePostData.set("amount", from.amountStr());
}
} else {
placePostData.push_back("price", price.amountStr());
placePostData.emplace_back("price", price.amountStr());
}
placePostData.push_back("symbol", lowerCaseMarket);
placePostData.push_back("type", type);
placePostData.emplace_back("symbol", lowerCaseMarket);
placePostData.emplace_back("type", type);

json result =
PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kPost, "/v1/order/orders/place", std::move(placePostData));
Expand Down Expand Up @@ -742,9 +746,9 @@ InitiatedWithdrawInfo HuobiPrivate::launchWithdraw(MonetaryAmount grossAmount, W

CurlPostData withdrawPostData;
if (destinationWallet.hasTag()) {
withdrawPostData.push_back("addr-tag", destinationWallet.tag());
withdrawPostData.emplace_back("addr-tag", destinationWallet.tag());
}
withdrawPostData.push_back("address", destinationWallet.address());
withdrawPostData.emplace_back("address", destinationWallet.address());

MonetaryAmount withdrawFee = _exchangePublic.queryWithdrawalFeeOrZero(currencyCode);
HuobiPublic::WithdrawParams withdrawParams = huobiPublic.getWithdrawParams(currencyCode);
Expand All @@ -764,10 +768,10 @@ InitiatedWithdrawInfo HuobiPrivate::launchWithdraw(MonetaryAmount grossAmount, W
grossAmount.truncate(withdrawParams.withdrawPrecision);
}

withdrawPostData.push_back("amount", netEmittedAmount.amountStr());
withdrawPostData.push_back("currency", lowerCaseCur);
withdrawPostData.emplace_back("amount", netEmittedAmount.amountStr());
withdrawPostData.emplace_back("currency", lowerCaseCur);
// Strange to have the fee as input parameter of a withdraw...
withdrawPostData.push_back("fee", withdrawFee.amountStr());
withdrawPostData.emplace_back("fee", withdrawFee.amountStr());

json result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kPost, "/v1/dw/withdraw/api/create",
std::move(withdrawPostData));
Expand Down
2 changes: 1 addition & 1 deletion src/api/exchanges/src/huobipublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ MarketOrderBook HuobiPublic::OrderBookFunc::operator()(Market mk, int depth) {
if (lb == kAuthorizedDepths.end()) {
log::warn("Invalid depth {}, default to {}", depth, kHuobiStandardOrderBookDefaultDepth);
} else if (*lb != kHuobiStandardOrderBookDefaultDepth) {
postData.push_back("depth", *lb);
postData.emplace_back("depth", *lb);
}
}

Expand Down
Loading

0 comments on commit c30d045

Please sign in to comment.