154 auto const& params(context.
params);
157 if (!params.isMember(jss::oracles))
159 if (!params[jss::oracles].isArray() || params[jss::oracles].size() == 0 ||
160 params[jss::oracles].size() > kMaxOracles)
166 if (!params.isMember(jss::base_asset))
169 if (!params.isMember(jss::quote_asset))
175 auto const& jv = params[field];
177 return jv.isUInt() || (jv.isInt() && jv.asInt() >= 0) ||
183 auto getField = [¶ms, &validUInt](
188 if (!validUInt(params, field))
190 return params[field].
asUInt();
201 if (params[field].asString().empty())
204 return params[field];
212 auto const trim = getField(jss::trim);
219 (std::get<std::uint32_t>(trim) == 0 || std::get<std::uint32_t>(trim) >
kMaxTrim))
225 auto const timeThreshold = getField(jss::time_threshold, 0);
232 auto const baseAsset = getCurrency(sfBaseAsset, jss::base_asset);
238 auto const quoteAsset = getCurrency(sfQuoteAsset, jss::quote_asset);
253 for (
auto const& oracle : params[jss::oracles])
255 if (!oracle.isMember(jss::oracle_document_id) || !oracle.isMember(jss::account))
260 auto const documentID = validUInt(oracle, jss::oracle_document_id)
264 if (!account || account->isZero() || !documentID)
270 auto const sle = ledger->read(
keylet::oracle(*account, *documentID));
278 std::get<json::Value>(baseAsset) &&
280 std::get<json::Value>(quoteAsset) &&
283 iter != series.end())
285 auto const price = iter->getFieldU64(sfAssetPrice);
286 auto const scale = iter->isFieldPresent(sfScale)
287 ? -
static_cast<int>(iter->getFieldU8(sfScale))
306 auto const latestTime = prices.left.begin()->first;
307 if (
auto const threshold = std::get<std::uint32_t>(timeThreshold))
312 auto const oldestTime = prices.left.rbegin()->first;
313 auto const upperBound = latestTime > threshold ? (latestTime - threshold) : oldestTime;
314 if (upperBound > oldestTime)
315 prices.left.erase(prices.left.upper_bound(upperBound), prices.left.end());
328 result[jss::time] = latestTime;
331 auto const [avg, sd, size] =
getStats(prices.right.begin(), prices.right.end());
332 result[jss::entire_set][jss::mean] = avg.getText();
333 result[jss::entire_set][jss::size] = size;
334 result[jss::entire_set][jss::standard_deviation] =
to_string(sd);
336 auto itAdvance = [&](
auto it,
int distance) {
341 auto const median = [&prices, &itAdvance, &size = size]() {
342 auto const middle = size / 2;
346 auto it = itAdvance(prices.right.begin(), middle - 1);
347 auto const& a1 = it->first;
348 auto const& a2 = (++it)->first;
351 return itAdvance(prices.right.begin(), middle)->first;
353 result[jss::median] = median.getText();
355 if (std::get<std::uint32_t>(trim) != 0)
357 auto const trimCount = prices.size() * std::get<std::uint32_t>(trim) / 100;
359 auto const [avg, sd, size] =
getStats(
360 itAdvance(prices.right.begin(), trimCount), itAdvance(prices.right.end(), -trimCount));
361 result[jss::trimmed_set][jss::mean] = avg.getText();
362 result[jss::trimmed_set][jss::size] = size;
363 result[jss::trimmed_set][jss::standard_deviation] =
to_string(sd);
std::shared_ptr< STLedgerEntry const > const & const_ref
LedgerMaster & ledgerMaster