feat(market): real historical sparklines via CoinGecko market_chart
Portfolio-group sparklines previously resampled the ~24-minute in-session price
buffer, so the hour/day/week/month intervals could never fill. Fetch real
historical USD series from CoinGecko /market_chart and back each interval with
appropriately-grained data.
- MarketInfo gains two timestamped series: price_chart_intraday (days=1, 5-min)
and price_chart_daily (days=365, daily), plus a fetch timestamp.
- App::refreshMarketChart() fetches both on the RPC worker via the TLS-verifying
util::httpGetString helper, self-throttled to ~30 min (historical data moves
slowly). Gated by getFetchPrices(); triggered on connect and each price tick.
- Pure NetworkRefreshService::parseCoinGeckoMarketChart() parses {"prices":
[[ms,price],...]} into (unix-seconds, price); malformed rows skipped. Unit-tested.
- market_tab pfSparklineSeries() maps interval -> series+bucket: minute = live
buffer; hour = intraday bucketed to 1h; day/week/month = daily bucketed to
1d/7d/30d. Falls back to the in-session buffer until the fetch populates.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <utility>
|
||||
|
||||
#include "exchange_info.h"
|
||||
|
||||
@@ -159,9 +161,19 @@ struct MarketInfo {
|
||||
bool price_loading = false;
|
||||
std::string price_error;
|
||||
|
||||
// Price history for chart
|
||||
// Live in-session price history: ~1 sample/minute, capped at MAX_HISTORY samples.
|
||||
// Backs the main chart and the "minute" portfolio-sparkline interval.
|
||||
std::vector<double> price_history;
|
||||
static constexpr int MAX_HISTORY = 24; // 24 hours
|
||||
static constexpr int MAX_HISTORY = 24; // 24 samples (~24 minutes at the 60s refresh)
|
||||
|
||||
// Historical USD price series fetched from CoinGecko market_chart, so the portfolio-group
|
||||
// sparklines can show real hour/day/week/month trends instead of resampling the ~24-minute
|
||||
// in-session buffer. Timestamped (unix seconds), oldest->newest; empty until the first fetch.
|
||||
// Refreshed on a slow cadence (~30 min) since historical data moves slowly.
|
||||
std::vector<std::pair<std::time_t, double>> price_chart_intraday; // ~24h @ 5-minute granularity
|
||||
std::vector<std::pair<std::time_t, double>> price_chart_daily; // ~1yr @ daily granularity
|
||||
std::chrono::steady_clock::time_point chart_last_fetch_time{};
|
||||
bool chart_loaded = false;
|
||||
|
||||
// Exchanges/pairs fetched live from CoinGecko (empty until fetched; the Market tab
|
||||
// falls back to data::getExchangeRegistry() while empty).
|
||||
|
||||
Reference in New Issue
Block a user