chart/docs/investigate_added_symbols.md
Chris Amow 234b57e8b6 Stamp drawings and alerts with symbol; snap from the instrument profile.
Missing JSON still loads as /ES. No switcher and no second stream.
2026-09-07 04:01:08 -05:00

5.8 KiB
Raw Permalink Blame History

Added symbols — /ES, /NQ, /GC, /CL

Status: placeholders in, switcher not. Agreed 2026-08-31. Profile and symbol stamps are live; still one stream and no UI switcher.

The process is one chart of one contract. Yahoo and Schwab already know the other roots. Almost everything after the stream is this instrument. The likely set is four: ES, NQ, gold, oil. Design for N, not a boolean ES/gold switch.


Decision

Persist symbol now. Do not split Runtime now.

Same move as user_id: "shared" in docs/multi_user.md: cheap while there is one value, expensive after two files exist.

Do first (placeholders, still one live series)

  1. Instrument profile the settings and the browser both see:

    id:            "es" | "nq" | "gc" | "cl"
    yahoo_symbol:  "ES=F" | "NQ=F" | "GC=F" | "CL=F"
    schwab_symbol: "/ES" | "/NQ" | "/GC" | "/CL"
    tick:          0.25 | 0.25 | 0.10 | 0.01
    decimals:      2
    session:       globex_18_17
    rth:           spy_rth | spy_rth | none | nymex_day
    

    Snap, nudge, alert inputs, and the status label read tick / names from here. Kill ConfluenceChart.TICK = 0.25. Session code stays shared. RTH follows the profile (none hides SPY marks on gold).

  2. Stamp persistence. Drawings, alert-state rows, and events get symbol (Schwab root, e.g. /ES). Missing field means /ES. New writes always stamp the current profile. Do not wait for a second chart.

  3. Keep one store, one stream, one seed. Bar.symbol already exists. InMemoryBarStore stays tf → bars until something actually switches.

Today’s env still selects the one live profile (YAHOO_SYMBOL / SCHWAB_SYMBOL or an INSTRUMENT=es key). Default remains ES.

Then (after placeholders have been live)

  1. Prove a second root as a replace: point env at NQ or GC, restart, confirm Yahoo history + Schwab stream + tick snaps. NQ is the cheap proof (same tick and RTH as ES). GC or CL is the proof that tick/RTH actually split.

  2. Switcher last: UI picks the profile; snapshot replace (setBars), not a tick; filter drawings/alerts by symbol; lazy-seed the other series; do not Schwab-sub the hidden root.

Not in this plan

Two live streams (ES and gold on screen together). That is a second tick path and a second 5k-bar store inside Stay cheap, plus an unverified double CHART_FUTURES sub on one token. Not until the switcher has been used.


Instrument table

/ES /NQ /GC /CL
Tick 0.25 0.25 0.10 0.01
Display 2 dp 2 dp 2 dp 2 dp
Yahoo ES=F NQ=F GC=F CL=F
Schwab /ES /NQ /GC /CL
Globex 18:00–17:00 yes yes yes yes
SPY RTH overlay yes yes no no (NYMEX day 9:00–14:30 ET)
Options UI keep hide or later hide hide

NQ is the cheapest second chart. Gold and oil are why tick cannot stay a chart constant. toFixed(2) covers all four.


Why the placeholders

The current process is one Runtime, one Schwab socket, one bar store, one manual_lines.json, one alert-state file, one ntfy topic.

File Today After step 2
data/manual_lines.json no symbol each row symbol: "/ES"
data/alert_state.json zones by price zone + symbol
data/events.json one log tagged or filtered by symbol
data/user_prefs.json global leave global until the switcher
localStorage layers, theme leave until the switcher

Without symbol on drawings, a switcher would mix ES lines onto NQ. Without it on alert state, gold 2650 would be silenced by an old ES 2650. Adding the field later is a migration of production JSON.

ConfluenceChart.TICK = 0.25 feeds every snap, keyboard nudge, and the price-alert step. Gold cannot ship with that literal. Pulling it into the profile is not scaffolding — it is deleting a lie.

Schwab continuous roots (/ES, /NQ, /GC, /CL) should auto-resolve the front month the same way /ES → /ESU26. Verify each with scripts/check_stream.py before trusting it. Singular get_quote("/GC") is still the equity slash trap; always get_quotes.


What stays generic

Aggregator, VWAP, daily MAs, prior-day H/L/C (session is shared Globex), WebSocket snapshot shape, drawing tools, Fibonacci, comments, confluence math, ntfy, auth. They work if the bars and the profile are the instrument’s.

What does not: RTH marks, tick grid, options panel, confluence score (28 and the 4h cooldown were calibrated on ES — re-run scripts/calibrate_alerts.py per tape before turning confluence on).

Yahoo daily bars stay unused. 1h → session 1d, same as ES.


Stay cheap

The tick budget is one series: forming tick = candle + price label. A symbol switch is setBars. Do not subscribe Schwab to a hidden root. Do not 2× the ~82s Yahoo seed; lazy-load the next instrument on first view.

Two symbols on one Schwab socket is unverified. Two processes both opening a stream still kick each other off.


What not to do

  • Do not split Runtime or the bar store until the switcher exists.
  • Do not add a disabled switcher, a second seed, or a second Schwab sub in the placeholder change.
  • Do not add a second package.json, Vue app, or process “for gold.”
  • Do not leave TICK = 0.25 and “just chart gold.”
  • Do not reuse ES confluence calibration.
  • Do not show SPY RTH on metals or oil.
  • Do not build gold/oil/NQ options in the same change as the chart.
  • Do not put two symbols in one manual_lines.json without a symbol key.
  • Do not start two live streams.

Open, before the switcher (not before placeholders)

  1. First extra root to prove as a replace: NQ (easy) or GC (forces tick)?
  2. Does /NQ /GC /CL on this account stream delayed: false?
  3. Does each Yahoo *F 1h series go back far enough for a daily 200 SMA?