Skip to content

Commit

Permalink
Do not throw exception for errors occurring in Upbit / Bithumb single…
Browse files Browse the repository at this point in the history
… market order book queries
  • Loading branch information
sjanel committed Jul 1, 2024
1 parent 9c96c42 commit e863148
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 32 deletions.
35 changes: 20 additions & 15 deletions src/api/exchanges/src/bithumbpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,11 @@ CurrencyExchangeFlatSet BithumbPublic::TradableCurrenciesFunc::operator()() {
}

namespace {
MarketOrderBookMap GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& config,
const ExchangeConfig& exchangeConfig, std::optional<Market> optM = std::nullopt,
std::optional<int> optDepth = std::nullopt) {
MarketOrderBookMap ret;

template <class OutputType>
OutputType GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& config, const ExchangeConfig& exchangeConfig,
std::optional<Market> optM = std::nullopt, std::optional<int> optDepth = std::nullopt) {
OutputType ret;
// 'all' seems to work as default for all public methods
CurrencyCode base("ALL");
CurrencyCode quote;
Expand All @@ -219,6 +220,9 @@ MarketOrderBookMap GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& c
}
CurrencyCode quoteCurrencyCode(config.standardizeCurrencyCode(quoteCurrency));
const CurrencyCodeSet& excludedCurrencies = exchangeConfig.excludedCurrenciesAll();

MarketOrderBookLines orderBookLines;

for (const auto& [baseOrSpecial, asksAndBids] : result.items()) {
if (baseOrSpecial != "payment_currency" && baseOrSpecial != "timestamp") {
const json* asksBids[2];
Expand Down Expand Up @@ -248,7 +252,7 @@ MarketOrderBookMap GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& c
"asks": [{"quantity" : "2.67575", "price" : "506000"},
{"quantity" : "3.54343","price" : "507000"}]
*/
MarketOrderBookLines orderBookLines;
orderBookLines.clear();
orderBookLines.reserve(asksBids[0]->size() + asksBids[1]->size());
for (const json* asksOrBids : asksBids) {
const auto type = asksOrBids == asksBids[0] ? OrderBookLine::Type::kAsk : OrderBookLine::Type::kBid;
Expand All @@ -260,31 +264,32 @@ MarketOrderBookMap GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& c
}
}
Market market(baseCurrencyCode, quoteCurrencyCode);
ret.insert_or_assign(market, MarketOrderBook(nowTime, market, orderBookLines));
if constexpr (std::is_same_v<OutputType, MarketOrderBookMap>) {
ret.insert_or_assign(market, MarketOrderBook(nowTime, market, orderBookLines));
} else {
ret = MarketOrderBook(nowTime, market, orderBookLines);
}
if (singleMarketQuote) {
break;
}
}
}
}
if (ret.size() > 1) {
log::info("Retrieved {} markets (+ order books) from Bithumb", ret.size());
if constexpr (std::is_same_v<OutputType, MarketOrderBookMap>) {
if (ret.size() > 1) {
log::info("Retrieved {} markets (+ order books) from Bithumb", ret.size());
}
}
return ret;
}
} // namespace

MarketOrderBookMap BithumbPublic::AllOrderBooksFunc::operator()() {
return GetOrderBooks(_curlHandle, _coincenterInfo, _exchangeConfig);
return GetOrderBooks<MarketOrderBookMap>(_curlHandle, _coincenterInfo, _exchangeConfig);
}

MarketOrderBook BithumbPublic::OrderBookFunc::operator()(Market mk, int depth) {
MarketOrderBookMap marketOrderBookMap = GetOrderBooks(_curlHandle, _coincenterInfo, _exchangeConfig, mk, depth);
auto it = marketOrderBookMap.find(mk);
if (it == marketOrderBookMap.end()) {
throw exception("Cannot find {} in market order book map", mk);
}
return it->second;
return GetOrderBooks<MarketOrderBook>(_curlHandle, _coincenterInfo, _exchangeConfig, mk, depth);
}

MonetaryAmount BithumbPublic::TradedVolumeFunc::operator()(Market mk) {
Expand Down
41 changes: 24 additions & 17 deletions src/api/exchanges/src/upbitpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,14 @@ MonetaryAmountByCurrencySet UpbitPublic::WithdrawalFeesFunc::operator()() {
}

namespace {
MarketOrderBookMap ParseOrderBooks(const json& result, int depth) {
MarketOrderBookMap ret;

template <class OutputType>
OutputType ParseOrderBooks(const json& result, int depth) {
OutputType ret;
const auto time = Clock::now();

MarketOrderBookLines orderBookLines;

for (const json& marketDetails : result) {
std::string_view marketStr = marketDetails["market"].get<std::string_view>();
std::size_t dashPos = marketStr.find('-');
Expand All @@ -193,14 +198,13 @@ MarketOrderBookMap ParseOrderBooks(const json& result, int depth) {
}

/// Remember, Upbit markets are inverted, quote first then base
CurrencyCode quote(std::string_view(marketStr.begin(), marketStr.begin() + dashPos));
CurrencyCode base(std::string_view(marketStr.begin() + dashPos + 1, marketStr.end()));
CurrencyCode quote(marketStr.substr(0, dashPos));
CurrencyCode base(marketStr.substr(dashPos + 1));
Market market(base, quote);

const auto& orderBookLinesJson = marketDetails["orderbook_units"];

MarketOrderBookLines orderBookLines;

orderBookLines.clear();
orderBookLines.reserve(orderBookLinesJson.size() * 2U);

for (const json& orderbookDetails : orderBookLinesJson | std::ranges::views::take(depth)) {
Expand All @@ -216,11 +220,18 @@ MarketOrderBookMap ParseOrderBooks(const json& result, int depth) {
if (static_cast<int>(orderBookLines.size() / 2) < depth) {
log::warn("Upbit does not support orderbook depth larger than {}", orderBookLines.size() / 2);
}
ret.insert_or_assign(market, MarketOrderBook(time, market, orderBookLines));
if constexpr (std::is_same_v<OutputType, MarketOrderBookMap>) {
ret.insert_or_assign(market, MarketOrderBook(time, market, orderBookLines));
} else {
ret = MarketOrderBook(time, market, orderBookLines);
}
}
if (ret.size() > 1) {
log::info("Retrieved {} order books from Upbit", ret.size());
if constexpr (std::is_same_v<OutputType, MarketOrderBookMap>) {
if (ret.size() > 1) {
log::info("Retrieved {} order books from Upbit", ret.size());
}
}

return ret;
}
} // namespace
Expand All @@ -235,17 +246,13 @@ MarketOrderBookMap UpbitPublic::AllOrderBooksFunc::operator()(int depth) {
}
marketsStr.append(ReverseMarketStr(mk));
}
return ParseOrderBooks(PublicQuery(_curlHandle, "/v1/orderbook", {{"markets", marketsStr}}), depth);
return ParseOrderBooks<MarketOrderBookMap>(PublicQuery(_curlHandle, "/v1/orderbook", {{"markets", marketsStr}}),
depth);
}

MarketOrderBook UpbitPublic::OrderBookFunc::operator()(Market mk, int depth) {
MarketOrderBookMap marketOrderBookMap =
ParseOrderBooks(PublicQuery(_curlHandle, "/v1/orderbook", {{"markets", ReverseMarketStr(mk)}}), depth);
auto it = marketOrderBookMap.find(mk);
if (it == marketOrderBookMap.end()) {
throw exception("Unexpected answer from get OrderBooks");
}
return it->second;
return ParseOrderBooks<MarketOrderBook>(
PublicQuery(_curlHandle, "/v1/orderbook", {{"markets", ReverseMarketStr(mk)}}), depth);
}

MonetaryAmount UpbitPublic::TradedVolumeFunc::operator()(Market mk) {
Expand Down

0 comments on commit e863148

Please sign in to comment.