Building a XAUUSD dashboard: syncing live prices with slower market context
I have been building Gold Dashboard, a research-first XAUUSD dashboard that combines live prices, multi-timeframe candles, gold news, support and resistance observations, macro drivers, and trader context. The engineerin
I have been building Gold Dashboard, a research-first XAUUSD dashboard that combines live prices, multi-timeframe candles, gold news, support and resistance observations, macro drivers, and trader context. The engineering challenge is that these data sources update at different speeds, so refreshing the entire page on one timer wastes requests and disrupts reading.
The first version was too easy to over-refresh
The initial design treated the dashboard as one large page and reloaded everything whenever new data arrived. That meant a price update could regenerate unrelated news and timeline markup, while every open tab created unnecessary requests.
The better model was to treat each section as a small data product with its own freshness requirement: live quotes refresh frequently, the active candle refreshes on a short tail, and support levels, news, and the trader timeline refresh more slowly.
Different sections, different clocks
The current refresh model uses separate server-rendered fragments:
| Section | Client refresh | Why |
|---|---|---|
| Price and macro-driver strip | 15 seconds | Quotes and driver values can change quickly |
| Active candle tail | 60 seconds | The current candle needs to move without reloading all history |
| Support and resistance watch | 15 minutes | The source data is aggregated more slowly |
| Gold news | 15 minutes | Reloading every few seconds adds no value |
| Trader timeline | 15 minutes | New posts are collected in batches |
The browser requests only the fragment it needs:
The browser requests only the required fragment, such as GET /wp-json/copi/v1/gold-dashboard-html?section=price, GET /wp-json/copi/v1/gold-dashboard-html?section=news, or GET /wp-json/copi/v1/gold-dashboard-html?section=trends.
The important part is the separation of concerns: a price refresh does not need to know how the news card is rendered.
Keeping the chart responsive while history stays cached
The chart supports M1, M5, M15, H1, H4, and D1. The server aggregates stored M1 bars for the requested timeframe, while the browser caches each loaded timeframe so switching back is immediate.
The active timeframe still needs a live edge. Instead of downloading the entire history every minute, the dashboard fetches only a short recent tail and merges it into the existing series.
This avoids repeatedly downloading historical data while keeping the forming candle current.
The chart also preserves the user's zoom and scroll position. If the user is already looking at the live edge, the window can follow it. If they are inspecting older candles, a refresh should not force them back to the present.
Server-rendered HTML with progressive enhancement
The dashboard is a WordPress plugin, so the first render is server-side HTML. JavaScript enhances that HTML with charts, fragment refreshes, PWA navigation, and theme changes.
This gives the page meaningful content before JavaScript finishes, keeps temporary API failures from blanking the page, and lets the same renderer provide English, Traditional Chinese, and Vietnamese labels.
The client-side refresher uses a fail-soft approach. If a fragment request fails, the current content remains visible and the next attempt is delayed with backoff. A background tab is also treated differently from a visible tab: hidden sections can wait until the page becomes visible again.
For a market dashboard, this matters more than making every request look real-time. A stale label is easier to understand than a blank card.
Dark mode across CSS and canvas
Most of the interface uses CSS custom properties, so the dark palette can be applied with a prefers-color-scheme media query.
The candlestick chart is different because it draws on a canvas. Canvas rendering cannot read CSS custom properties in the same way as normal DOM elements, so the chart theme is calculated from the same media-query state and reapplied when the operating-system theme changes.
The important lesson was to keep one source of truth for the palette, even when the rendering technologies are different.
What I am deliberately not building
The dashboard shows market information, but it does not promise a direction or outcome.
I am avoiding features and copy that turn a research interface into a signal product:
- No guaranteed predictions.
- No automated trade execution.
- No claim that a support or resistance level will hold.
- No performance promises.
The product is more useful when it helps someone compare context before making their own decision.
What I am still learning
The hardest part has not been drawing a chart. It has been deciding what should update, how often it should update, and what the interface should do when the update cannot happen.
The current questions I am exploring are:
- Which information should be visible in the first few seconds?
- Is a compact market-context summary more useful than another chart?
- How should a multilingual dashboard explain the same data without making every layout identical?
- Which sections deserve a dedicated mobile view in the PWA?
If you build dashboards or data-heavy WordPress interfaces, I would be interested in how you separate freshness, caching, and user control.
You can try the current version here: Gold Dashboard
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.

