feat(market): candlestick chart for per-exchange OHLC
The exchange candle APIs return full OHLC but we only kept the close (a line). Now the per-exchange chart draws real candlesticks; the CoinGecko aggregate stays a line (it's close-only). - Adapter keeps OHLC: parseExchangeOHLC() returns open/high/low/close candles (parseExchangeCandles is now a close-only wrapper over it). New data/candle.h holds the dependency-free Candle + bucketOHLC (5-min -> hourly for the 1D view). - Model stores exchange_ohlc_intraday/daily alongside the close series; refreshExchangeChart populates both. market_series::chartCandles() returns the bucketed OHLC for the range, empty unless the per-exchange series is active. - The chart renders wick (low..high) + body (open..close), green up / red down, with a low..high y-range; the line-only bits (fill, hi/lo labels, hover tooltip) are gated off for candles. Falls back to the line for the aggregate / Live view. Verified: OHLC parsers + bucketOHLC + chartCandles unit-tested; a forced-state render shows correct candlesticks; the aggregate still draws a clean line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "exchange_info.h"
|
||||
#include "candle.h"
|
||||
|
||||
namespace dragonx {
|
||||
|
||||
@@ -182,6 +183,10 @@ struct MarketInfo {
|
||||
std::vector<std::pair<std::time_t, double>> exchange_chart_intraday;
|
||||
std::vector<std::pair<std::time_t, double>> exchange_chart_daily;
|
||||
bool exchange_chart_active = false;
|
||||
// Full OHLC for the same per-exchange candles, backing the candlestick rendering (the aggregate
|
||||
// CoinGecko series is close-only, so it stays a line). Parallel to exchange_chart_* above.
|
||||
std::vector<data::Candle> exchange_ohlc_intraday;
|
||||
std::vector<data::Candle> exchange_ohlc_daily;
|
||||
|
||||
// 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