chart/docs/NEXT_STEPS.md

5 KiB

Current recommendations

Last reviewed: 2026-08-11 03:19 CDT.

This file is the short list of work worth considering next. Verified history, measurements and completed work remain in docs/IMPLEMENTATION_PLAN.md.

Fix next

Keep snapping out of the price axes

ConfluenceChart.withinPlot() currently checks plot-relative coordinates against chartEl.clientWidth and clientHeight. The element also contains the price and time axes, so hovering the right price axis can leave the snap dot visible at the plot edge.

Recommended fix:

  1. Compare against the measured plot canvas width and height.
  2. Add a Playwright page-pixel test that moves from a bar into the actual right axis rectangle and expects the snap dot to disappear, then return over the plot and expect it to reappear.
  3. Reuse the same plot-relative conversion for selection and anchor dragging; do not add another coordinate frame.

This was discovered by test research but deliberately not committed as a failing test because it requires production code to correct.

Show unambiguous market freshness

The best location is the status strip directly below the chart. Keep the header for coarse transport state (LIVE · SCHWAB, DELAYED · YAHOO 10m) and replace the ambiguous LAST BAR age with browser-observed receipt time:

UPDATED 3s AGO

On mobile use a compact form:

Updated 3s ago · Live

No additional request is needed. Record Date.now() when an existing WebSocket bar message arrives. A snapshot should initially say LOADED JUST NOW; level, alert and preference messages are not market updates and must not refresh it.

Do not derive update age from bar.t: it is the bucket start, and selected timeframe bar messages currently overwrite status.last_bar_t, making an hourly bar appear stale even when just received.

A later, more complete implementation can add these fields to the existing WebSocket rather than add polling:

  • exact last_trade_t where the source supplies it;
  • last_settled_m1_t, measured from the end of the minute;
  • last_source_received_at;
  • an application heartbeat for transport health.

Stale warnings must distinguish market closure from transport failure and must subtract Yahoo's declared delay before calling delayed data overdue.

Mobile authoring

The detailed plan is in docs/mobile_enhance.md. Recommended first tranche:

  1. Use one plot-relative pointer path for placement, selection and anchor drag.
  2. Add touch-sized invisible hit regions without enlarging the visual marks.
  3. Keep the first tap's trendline anchor visible with price/time, Cancel and Undo anchor.
  4. Add a compact sticky mobile tool rail next to the chart.
  5. Add a selected-drawing action bar so End here and Delete do not require right-click or a hardware keyboard.

Prefer tap-tap trendlines on touch devices. Reserve one-finger vertical movement for page scrolling, retain horizontal chart panning and pinch zoom, and offer a chart-focused landscape/fullscreen mode.

Market-data alternatives

No durable unauthenticated source of free real-time CME /ES data has been identified. CME real-time access is normally broker-subsidized and tied to an authenticated exchange entitlement, not a public free API.

Practical ranking:

  1. Keep Schwab for verified entitled real-time streaming and Yahoo for delayed development/history seeding.
  2. Pilot Tastytrade/dxLink on a live futures-approved account. Confirm actual delay, candle retention, continuous/root symbol behavior and server-side-use terms before integrating it.
  3. Consider IBKR as the strongest low-cost fallback if literal zero cost is not required; resolve and roll the active contract explicitly for live data.
  4. Consider TradeStation only if its account-funding/API-access requirements are already acceptable.
  5. Evaluate Nasdaq Data Link CHRIS only for continuous daily seeding after confirming current freshness and free-key availability.

Do not build a backend around scraped TradingView, CME, Barchart, Investing.com, MarketWatch or Stooq pages. Public display access is not a supported market-data API or a CME redistribution license.

References:

Deferred test tied to production work

When startup seeding is changed to bulk-load bars, add an integration test that asserts expensive level rebuilding happens once and that final stores/levels match incremental ingestion. Do not assert a wall-clock duration and do not add a test that merely codifies today's slow startup.

Test and deployment commands

README is authoritative for local pytest, local Playwright E2E, pre-deploy and production smoke-test commands. Browser E2E creates and deletes drawings, so it must remain pointed at the local stack rather than production.