Shared chart-data presentation layer for FX Spot and CRM plots

Table of Contents

This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

What

FxSpotChartWindow (projects/ores.qt/mktdata/src/FxSpotChartWindow.cpp) currently does all of its candle-bucketing, rolling-sample retention, visible-window trimming (k_max_candles=/=k_max_line_points), and axis-range computation inline, as Qt-only logic with no non-Qt consumer. Extract this into a new plain-C++ presentation-layer class — e.g. fx_chart_series_builder in ores.marketdata.client/presentation/ — that takes raw (timestamp, value) samples plus a requested window/interval and returns ready-to-render candle=/=line_point vectors and their visible {x_min,x_max}=/={y_min,y_max} ranges. No Qt or NATS dependency, same shape as the existing crm_rate_display_service / crm_rate_formatter facade (ores.marketdata.client/presentation/) that already does this for CRM rate tables/matrices.

Concrete behaviour to move into the builder (raised while triaging Model or document market_observation's hand-written repository/service overrides, where a QA scenario found the FX Spot chart "hard to make sense of"):

  • Default the visible window to a recent slice (e.g. last 5 minutes) instead of everything fetched, for both line and candle modes.
  • Recompute X/Y axis range from the visible window only, not the full retained history.
  • Roll the window forward as live ticks arrive rather than fixing it once at load.
  • Pixel-stride downsampling / moving-average smoothing for the line view (see the related, narrower capture below) — a natural fit for the same builder rather than a one-off in FxSpotChartWindow.

Once built, wire FxSpotChartWindow to it (candles and line both), add an ASCII renderer for ores.shell consuming the same candle=/=line_point output (mirroring presentation/crm_rate_table.hpp's console-table pattern), and apply the same builder to CRM cross-rate plots so both use cases share one tested aggregation/windowing implementation instead of parallel Qt-only logic.

Why

Chart usability logic (windowing, bucketing, axis scaling) is currently Qt-only, untested outside manual QA, and would have to be re-implemented from scratch for any non-Qt consumer (e.g. an ASCII chart in ores.shell) or for CRM plots, which have the same underlying need. The crm_rate_display_service / crm_rate_formatter split already establishes the pattern this codebase uses to keep formatting/aggregation logic Qt-free and Catch2-testable, shared across Qt/shell/future consumers — this is the same pattern applied to chart series data instead of rate-table rows.

References

  • projects/ores.qt/mktdata/src/FxSpotChartWindow.cpp — current Qt-only candle/line bucketing, sample retention, and axis logic to extract.
  • projects/ores.marketdata/client/include/ores.marketdata.client/presentation/crm_rate_display_service.hpp and sibling files — the existing presentation-layer pattern to mirror.
  • projects/ores.qt/mktdata/src/CrmCrossRatesMatrixMdiWindow.* (or equivalent) — CRM plot use case to fold into the same builder.

See also

Emacs 29.3 (Org mode 9.6.15)