157 auto const& params(context.
params);
160 if (!params.isMember(jss::oracles))
162 if (!params[jss::oracles].isArray() || params[jss::oracles].size() == 0 ||
163 params[jss::oracles].size() > kMaxOracles)
169 if (!params.isMember(jss::base_asset))
172 if (!params.isMember(jss::quote_asset))
178 auto const& jv = params[field];
180 return jv.isUInt() || (jv.isInt() && jv.asInt() >= 0) ||
186 auto getField = [¶ms, &validUInt](
191 if (!validUInt(params, field))
193 return params[field].
asUInt();
204 if (params[field].asString().empty())
207 return params[field];
215 auto const trim = getField(jss::trim);
222 (std::get<std::uint32_t>(trim) == 0 || std::get<std::uint32_t>(trim) >
kMaxTrim))
228 auto const timeThreshold = getField(jss::time_threshold, 0);
235 auto const baseAsset = getCurrency(sfBaseAsset, jss::base_asset);
241 auto const quoteAsset = getCurrency(sfQuoteAsset, jss::quote_asset);
258 for (
auto const& oracle : params[jss::oracles])
260 if (!oracle.isMember(jss::oracle_document_id) || !oracle.isMember(jss::account))
265 auto const documentID = validUInt(oracle, jss::oracle_document_id)
269 if (!account || account->isZero() || !documentID)
276 if (!seen.
emplace(*account, *documentID).second)
279 auto const sle = ledger->read(
keylet::oracle(*account, *documentID));
287 std::get<json::Value>(baseAsset) &&
289 std::get<json::Value>(quoteAsset) &&
292 iter != series.end())
294 auto const price = iter->getFieldU64(sfAssetPrice);
295 auto const scale = iter->isFieldPresent(sfScale)
296 ? -
static_cast<int>(iter->getFieldU8(sfScale))
315 auto const latestTime = prices.left.
begin()->first;
316 if (
auto const threshold = std::get<std::uint32_t>(timeThreshold))
321 auto const oldestTime = prices.left.rbegin()->first;
322 auto const upperBound = latestTime > threshold ? (latestTime - threshold) : oldestTime;
323 if (upperBound > oldestTime)
324 prices.left.erase(prices.left.upper_bound(upperBound), prices.left.end());
337 result[jss::time] = latestTime;
340 auto const [avg, sd, size] =
getStats(prices.right.begin(), prices.right.end());
341 result[jss::entire_set][jss::mean] = avg.getText();
342 result[jss::entire_set][jss::size] = size;
343 result[jss::entire_set][jss::standard_deviation] =
to_string(sd);
345 auto itAdvance = [&](
auto it,
int distance) {
350 auto const median = [&prices, &itAdvance, &size = size]() {
351 auto const middle = size / 2;
355 auto it = itAdvance(prices.right.begin(), middle - 1);
356 auto const& a1 = it->first;
357 auto const& a2 = (++it)->first;
360 return itAdvance(prices.right.begin(), middle)->first;
362 result[jss::median] = median.getText();
364 if (std::get<std::uint32_t>(trim) != 0)
366 auto const trimCount = prices.size() * std::get<std::uint32_t>(trim) / 100;
368 auto const [avg, sd, size] =
getStats(
369 itAdvance(prices.right.begin(), trimCount), itAdvance(prices.right.end(), -trimCount));
370 result[jss::trimmed_set][jss::mean] = avg.getText();
371 result[jss::trimmed_set][jss::size] = size;
372 result[jss::trimmed_set][jss::standard_deviation] =
to_string(sd);
std::shared_ptr< STLedgerEntry const > const & const_ref
LedgerMaster & ledgerMaster