Skip to content

Commit

Permalink
Clean-up and make MarketOrderBook creation more user friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Mar 16, 2024
1 parent 27366b9 commit b9817b2
Show file tree
Hide file tree
Showing 14 changed files with 273 additions and 203 deletions.
4 changes: 2 additions & 2 deletions src/api/common/src/commonapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ vector<CurrencyCode> CommonAPI::FiatsFunc::retrieveFiatsSource1() {

std::string_view data = _curlHandle1.query("", CurlOptions(HttpRequestType::kGet));
if (data.empty()) {
log::error("Error parsing currency codes, no fiats found from first source");
log::warn("Error parsing currency codes, no fiats found from first source");
return fiatsVec;
}
static constexpr bool kAllowExceptions = false;
json dataCSV = json::parse(data, nullptr, kAllowExceptions);
if (dataCSV.is_discarded()) {
log::error("Error parsing json data of currency codes from source 1");
log::warn("Error parsing json data of currency codes from source 1");
return fiatsVec;
}
for (const json& fiatData : dataCSV) {
Expand Down
16 changes: 9 additions & 7 deletions src/api/exchanges/src/binancepublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "runmodes.hpp"
#include "timedef.hpp"
Expand Down Expand Up @@ -485,28 +486,29 @@ MarketOrderBook BinancePublic::OrderBookFunc::operator()(Market mk, int depth) {
lb = std::next(kAuthorizedDepths.end(), -1);
log::error("Invalid depth {}, default to {}", depth, *lb);
}
using OrderBookVec = vector<OrderBookLine>;
OrderBookVec orderBookLines;

CurlPostData postData{{"symbol", mk.assetsPairStrUpper()}, {"limit", *lb}};
json asksAndBids = PublicQuery(_commonInfo._curlHandle, "/api/v3/depth", postData);
MarketOrderBookLines orderBookLines;

const CurlPostData postData{{"symbol", mk.assetsPairStrUpper()}, {"limit", *lb}};
const json asksAndBids = PublicQuery(_commonInfo._curlHandle, "/api/v3/depth", postData);
const auto nowTime = Clock::now();
const auto asksIt = asksAndBids.find("asks");
const auto bidsIt = asksAndBids.find("bids");

if (asksIt != asksAndBids.end() && bidsIt != asksAndBids.end()) {
orderBookLines.reserve(static_cast<OrderBookVec::size_type>(asksIt->size() + bidsIt->size()));
orderBookLines.reserve(asksIt->size() + bidsIt->size());
for (const auto& asksOrBids : {asksIt, bidsIt}) {
const auto type = asksOrBids == asksIt ? OrderBookLine::Type::kAsk : OrderBookLine::Type::kBid;
for (const auto& priceQuantityPair : *asksOrBids) {
MonetaryAmount amount(priceQuantityPair.back().get<std::string_view>(), mk.base());
MonetaryAmount price(priceQuantityPair.front().get<std::string_view>(), mk.quote());

orderBookLines.emplace_back(amount, price, type);
orderBookLines.push(amount, price, type);
}
}
}

return MarketOrderBook(Clock::now(), mk, orderBookLines);
return MarketOrderBook(nowTime, mk, orderBookLines);
}

MonetaryAmount BinancePublic::TradedVolumeFunc::operator()(Market mk) {
Expand Down
21 changes: 10 additions & 11 deletions src/api/exchanges/src/bithumbpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "cct_json.hpp"
#include "cct_log.hpp"
#include "cct_string.hpp"
#include "cct_vector.hpp"
#include "coincenterinfo.hpp"
#include "commonapi.hpp"
#include "curlhandle.hpp"
Expand All @@ -35,6 +34,7 @@
#include "market.hpp"
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "stringhelpers.hpp"
#include "timedef.hpp"
Expand Down Expand Up @@ -173,7 +173,7 @@ CurrencyExchangeFlatSet BithumbPublic::TradableCurrenciesFunc::operator()() {
}

namespace {
MarketOrderBookMap GetOrderbooks(CurlHandle& curlHandle, const CoincenterInfo& config,
MarketOrderBookMap GetOrderBooks(CurlHandle& curlHandle, const CoincenterInfo& config,
const ExchangeConfig& exchangeConfig, std::optional<Market> optM = std::nullopt,
std::optional<int> optDepth = std::nullopt) {
MarketOrderBookMap ret;
Expand All @@ -195,11 +195,11 @@ MarketOrderBookMap GetOrderbooks(CurlHandle& curlHandle, const CoincenterInfo& c
if (!result.empty()) {
// Note: as of 2021-02-24, Bithumb payment currency is always KRW. Format of json may change once it's not the case
// anymore
const auto nowTime = Clock::now();
std::string_view quoteCurrency = result["payment_currency"].get<std::string_view>();
if (quoteCurrency != "KRW") {
log::error("Unexpected Bithumb reply for orderbook. May require code api update");
}
const auto time = Clock::now();
CurrencyCode quoteCurrencyCode(config.standardizeCurrencyCode(quoteCurrency));
const CurrencyCodeSet& excludedCurrencies = exchangeConfig.excludedCurrenciesAll();
for (const auto& [baseOrSpecial, asksAndBids] : result.items()) {
Expand Down Expand Up @@ -231,37 +231,36 @@ MarketOrderBookMap GetOrderbooks(CurlHandle& curlHandle, const CoincenterInfo& c
"asks": [{"quantity" : "2.67575", "price" : "506000"},
{"quantity" : "3.54343","price" : "507000"}]
*/
using OrderBookVec = vector<OrderBookLine>;
OrderBookVec orderBookLines;
orderBookLines.reserve(static_cast<OrderBookVec::size_type>(asksBids[0]->size() + asksBids[1]->size()));
MarketOrderBookLines orderBookLines;
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;
for (const json& priceQuantityPair : *asksOrBids) {
MonetaryAmount amount(priceQuantityPair["quantity"].get<std::string_view>(), baseCurrencyCode);
MonetaryAmount price(priceQuantityPair["price"].get<std::string_view>(), quoteCurrencyCode);

orderBookLines.emplace_back(amount, price, type);
orderBookLines.push(amount, price, type);
}
}
Market market(baseCurrencyCode, quoteCurrencyCode);
ret.insert_or_assign(market, MarketOrderBook(time, market, orderBookLines));
ret.insert_or_assign(market, MarketOrderBook(nowTime, market, orderBookLines));
if (singleMarketQuote) {
break;
}
}
}
}
log::info("Retrieved {} markets (+ orderbooks) from Bithumb", ret.size());
log::info("Retrieved {} markets (+ order books) from Bithumb", ret.size());
return ret;
}
} // namespace

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

MarketOrderBook BithumbPublic::OrderBookFunc::operator()(Market mk, int depth) {
MarketOrderBookMap marketOrderBookMap = GetOrderbooks(_curlHandle, _coincenterInfo, _exchangeConfig, mk, 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);
Expand Down
9 changes: 5 additions & 4 deletions src/api/exchanges/src/huobipublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "timedef.hpp"
#include "toupperlower-string.hpp"
Expand Down Expand Up @@ -378,10 +379,10 @@ MarketOrderBook HuobiPublic::OrderBookFunc::operator()(Market mk, int depth) {
postData.append("depth", *lb);
}
}
using OrderBookVec = vector<OrderBookLine>;
OrderBookVec orderBookLines;
MarketOrderBookLines orderBookLines;

const json asksAndBids = PublicQuery(_curlHandle, "/market/depth", postData);
const auto nowTime = Clock::now();
const auto asksIt = asksAndBids.find("asks");
const auto bidsIt = asksAndBids.find("bids");
if (asksIt != asksAndBids.end() && bidsIt != asksAndBids.end()) {
Expand All @@ -393,7 +394,7 @@ MarketOrderBook HuobiPublic::OrderBookFunc::operator()(Market mk, int depth) {
MonetaryAmount amount(priceQuantityPair.back().get<double>(), mk.base());
MonetaryAmount price(priceQuantityPair.front().get<double>(), mk.quote());

orderBookLines.emplace_back(amount, price, type);
orderBookLines.push(amount, price, type);
if (++currentDepth == depth) {
if (depth < static_cast<int>(asksOrBids->size())) {
log::debug("Truncate number of {} prices in order book to {}",
Expand All @@ -404,7 +405,7 @@ MarketOrderBook HuobiPublic::OrderBookFunc::operator()(Market mk, int depth) {
}
}
}
return MarketOrderBook(Clock::now(), mk, orderBookLines);
return MarketOrderBook(nowTime, mk, orderBookLines);
}

MonetaryAmount HuobiPublic::sanitizePrice(Market mk, MonetaryAmount pri) {
Expand Down
19 changes: 8 additions & 11 deletions src/api/exchanges/src/krakenpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "cct_json.hpp"
#include "cct_log.hpp"
#include "cct_string.hpp"
#include "cct_vector.hpp"
#include "coincenterinfo.hpp"
#include "commonapi.hpp"
#include "curlhandle.hpp"
Expand All @@ -32,6 +31,7 @@
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "timedef.hpp"
#include "tradeside.hpp"
Expand Down Expand Up @@ -299,32 +299,29 @@ MarketOrderBook KrakenPublic::OrderBookFunc::operator()(Market mk, int count) {
string krakenAssetPair = krakenCurrencyExchangeBase.altStr();
krakenAssetPair.append(krakenCurrencyExchangeQuote.altStr());

using OrderBookVec = vector<OrderBookLine>;
OrderBookVec orderBookLines;
MarketOrderBookLines orderBookLines;

json result = PublicQuery(_curlHandle, "/public/Depth", {{"pair", krakenAssetPair}, {"count", count}});
const auto nowTime = Clock::now();
if (!result.empty()) {
const json& entry = result.front();
const auto asksIt = entry.find("asks");
const auto bidsIt = entry.find("bids");

orderBookLines.reserve(static_cast<OrderBookVec::size_type>(asksIt->size() + bidsIt->size()));
orderBookLines.reserve(asksIt->size() + bidsIt->size());
for (const auto& asksOrBids : {asksIt, bidsIt}) {
const auto type = asksOrBids == asksIt ? OrderBookLine::Type::kAsk : OrderBookLine::Type::kBid;
for (const auto& priceQuantityTuple : *asksOrBids) {
std::string_view priceStr = priceQuantityTuple[0].get<std::string_view>();
std::string_view amountStr = priceQuantityTuple[1].get<std::string_view>();
MonetaryAmount amount(priceQuantityTuple[1].get<std::string_view>(), mk.base());
MonetaryAmount price(priceQuantityTuple[0].get<std::string_view>(), mk.quote());

MonetaryAmount amount(amountStr, mk.base());
MonetaryAmount price(priceStr, mk.quote());

orderBookLines.emplace_back(amount, price, type);
orderBookLines.push(amount, price, type);
}
}
}

const auto volAndPriNbDecimals = _marketsCache.get().second.find(mk)->second.volAndPriNbDecimals;
return MarketOrderBook(Clock::now(), mk, orderBookLines, volAndPriNbDecimals);
return MarketOrderBook(nowTime, mk, orderBookLines, volAndPriNbDecimals);
}

KrakenPublic::TickerFunc::Last24hTradedVolumeAndLatestPricePair KrakenPublic::TickerFunc::operator()(Market mk) {
Expand Down
13 changes: 7 additions & 6 deletions src/api/exchanges/src/kucoinpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "stringhelpers.hpp"
#include "timedef.hpp"
Expand Down Expand Up @@ -262,13 +263,13 @@ MarketOrderBookMap KucoinPublic::AllOrderBooksFunc::operator()(int depth) {
namespace {
template <class InputIt>
void FillOrderBook(Market mk, int depth, OrderBookLine::Type type, InputIt beg, InputIt end,
vector<OrderBookLine>& orderBookLines) {
MarketOrderBookLines& orderBookLines) {
int currentDepth = 0;
for (auto it = beg; it != end; ++it) {
MonetaryAmount price((*it)[0].template get<std::string_view>(), mk.quote());
MonetaryAmount amount((*it)[1].template get<std::string_view>(), mk.base());

orderBookLines.emplace_back(amount, price, type);
orderBookLines.push(amount, price, type);
if (++currentDepth == depth) {
if (++it != end) {
log::debug("Truncate number of {} prices in order book to {}",
Expand All @@ -292,10 +293,10 @@ MarketOrderBook KucoinPublic::OrderBookFunc::operator()(Market mk, int depth) {
string endpoint("/api/v1/market/orderbook/level2_");
AppendString(endpoint, *lb);

using OrderBookVec = vector<OrderBookLine>;
OrderBookVec orderBookLines;
MarketOrderBookLines orderBookLines;

json asksAndBids = PublicQuery(_curlHandle, endpoint, GetSymbolPostData(mk));
const json asksAndBids = PublicQuery(_curlHandle, endpoint, GetSymbolPostData(mk));
const auto nowTime = Clock::now();
const auto asksIt = asksAndBids.find("asks");
const auto bidsIt = asksAndBids.find("bids");
if (asksIt != asksAndBids.end() && bidsIt != asksAndBids.end()) {
Expand All @@ -305,7 +306,7 @@ MarketOrderBook KucoinPublic::OrderBookFunc::operator()(Market mk, int depth) {
FillOrderBook(mk, depth, OrderBookLine::Type::kAsk, asksIt->begin(), asksIt->end(), orderBookLines);
}

return MarketOrderBook(Clock::now(), mk, orderBookLines);
return MarketOrderBook(nowTime, mk, orderBookLines);
}

MonetaryAmount KucoinPublic::sanitizePrice(Market mk, MonetaryAmount pri) {
Expand Down
17 changes: 11 additions & 6 deletions src/api/exchanges/src/upbitpublicapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "cct_exception.hpp"
#include "cct_json.hpp"
#include "cct_log.hpp"
#include "cct_smallvector.hpp"
#include "cct_string.hpp"
#include "cct_vector.hpp"
#include "coincenterinfo.hpp"
Expand All @@ -33,6 +32,7 @@
#include "marketorderbook.hpp"
#include "monetaryamount.hpp"
#include "monetaryamountbycurrencyset.hpp"
#include "order-book-line.hpp"
#include "permanentcurloptions.hpp"
#include "timedef.hpp"
#include "tradeside.hpp"
Expand Down Expand Up @@ -190,21 +190,26 @@ MarketOrderBookMap ParseOrderBooks(const json& result, int depth) {
continue;
}

SmallVector<OrderBookLine, 10> orderBookLines;

/// 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()));
Market market(base, quote);
for (const json& orderbookDetails : marketDetails["orderbook_units"]) {

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

MarketOrderBookLines orderBookLines;

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

for (const json& orderbookDetails : orderBookLinesJson) {
// Amounts are not strings, but doubles
MonetaryAmount askPri(orderbookDetails["ask_price"].get<double>(), quote);
MonetaryAmount bidPri(orderbookDetails["bid_price"].get<double>(), quote);
MonetaryAmount askVol(orderbookDetails["ask_size"].get<double>(), base);
MonetaryAmount bidVol(orderbookDetails["bid_size"].get<double>(), base);

orderBookLines.emplace_back(askVol, askPri, OrderBookLine::Type::kAsk);
orderBookLines.emplace_back(bidVol, bidPri, OrderBookLine::Type::kBid);
orderBookLines.pushAsk(askVol, askPri);
orderBookLines.pushBid(bidVol, bidPri);

if (static_cast<int>(orderBookLines.size() / 2) == depth) {
// Upbit does not have a depth parameter, the only thing we can do is to truncate it manually
Expand Down
1 change: 1 addition & 0 deletions src/engine/src/exchangesorchestrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ BalancePerExchange ExchangesOrchestrator::getBalance(std::span<const ExchangeNam
_exchangeRetriever.select(ExchangeRetriever::Order::kInitial, privateExchangeNames);

SmallVector<BalancePortfolio, kTypicalNbPrivateAccounts> balancePortfolios(selectedExchanges.size());

_threadPool.parallelTransform(
selectedExchanges.begin(), selectedExchanges.end(), balancePortfolios.begin(),
[&balanceOptions](Exchange *exchange) { return exchange->apiPrivate().getAccountBalance(balanceOptions); });
Expand Down
6 changes: 3 additions & 3 deletions src/engine/src/queryresultprinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ json TickerInformationJson(const ExchangeTickerMaps &exchangeTickerMaps) {

void AppendOrderbookLine(const MarketOrderBook &marketOrderBook, int pos,
std::optional<MonetaryAmount> optConversionRate, json &data) {
auto [p, a] = marketOrderBook[pos];
auto [amount, price] = marketOrderBook[pos];
json &line = data.emplace_back();
line.emplace("a", a.amountStr());
line.emplace("p", p.amountStr());
line.emplace("a", amount.amountStr());
line.emplace("p", price.amountStr());
if (optConversionRate) {
line.emplace("eq", optConversionRate->amountStr());
}
Expand Down
12 changes: 12 additions & 0 deletions src/objects/include/amount-price.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include "monetaryamount.hpp"

namespace cct {

struct AmountPrice {
MonetaryAmount amount;
MonetaryAmount price;
};

} // namespace cct
Loading

0 comments on commit b9817b2

Please sign in to comment.