[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-105394":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":10,"trendingCount":15,"starSnapshotCount":15,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},105394,"terminal","michaelshimeles\u002Fterminal","michaelshimeles","Bloomberg-style trading terminal in Rust with GPU charts and congressional trades","https:\u002F\u002Fterminal-rs.vercel.app",null,"Rust",317,80,1,0,3,9,46.53,false,"master",[],"2026-11-01 00:15:43","# Terminal\n\nA fast, keyboard-driven market terminal in pure Rust: TradingView-class GPU charting with a\nBloomberg Terminal look (dense tiled panes, monospace numbers, a command line like `AAPL \u003CGO>`)\nacross **stocks, ETFs, indices, FX, crypto, US Treasuries, futures\u002Fcommodities and options**,\nplus **congressional trade tracking ingested directly from the official STOCK Act disclosure\nsystems** and **your own brokerage accounts through [SnapTrade](https:\u002F\u002Fsnaptrade.com)**\n(read-only by default, with opt-in order entry). Native compact UI, themes from Bloomberg amber\nto Solarized, and a fully dockable\nworkspace with saved layouts.\n\n![Terminal: AAPL chart with congress trade markers and RSI, the Congress trades feed, world markets and a multi-asset watchlist](docs\u002Fimg\u002Foverview.png)\n\n> **Built from reverse-engineering research.** Chart UX was studied behaviourally on\n> tradingview.com with [REA](https:\u002F\u002Fgithub.com\u002Fmorluto\u002Frea) in website mode (passive captures of\n> the public, logged-out chart page), then given a Bloomberg Terminal look. Findings, evidence IDs\n> and their design implications are in [`docs\u002Fanalysis\u002F`](docs\u002Fanalysis\u002FREADME.md). Only behaviour\n> was studied: no TradingView or Bloomberg code, scripts, icons, fonts or other assets are used or\n> included here. The disclosure parsers were likewise built by examining the public Senate eFD and\n> House Clerk sites and their filings.\n\n## Screenshots\n\n| | |\n|---|---|\n| ![Bloomberg theme: NVDA chart with congress markers and Nancy Pelosi's trade history with estimated returns](docs\u002Fimg\u002Fbloomberg-politician.png) | ![Options chain (OMON) for AAPL with bid\u002Fask, IV and delta per strike beside the chart](docs\u002Fimg\u002Foptions-omon.png) |\n| **Bloomberg theme** — `NVDA`, `POL PELOSI`: party-coloured B\u002FS markers and a politician profile with estimated return, hit rate and disclosure lag | **Options** — `AAPL OMON`: every expiry, calls and puts by strike, IV and greeks, spot line |\n| ![Terminal Light theme with the latest congressional trades feed](docs\u002Fimg\u002Flight-congress.png) | ![Nord theme, sidebar on the right, dragging a Watchlist tab onto the chart pane's dock compass](docs\u002Fimg\u002Fdocking-nord.png) |\n| **Terminal Light** — the latest STOCK Act filings with party, chamber, owner and amount filters | **Docking** (Nord theme, sidebar on the right) — drag a tab onto the compass to tab or split |\n| ![Live theme editor: Monokai applied to the chart while its colours are shown in Settings](docs\u002Fimg\u002Ftheme-editor.png) | ![Theme gallery in Settings › Appearance](docs\u002Fimg\u002Ftheme-gallery.png) ![Congress marker hover card with disclosure lag](docs\u002Fimg\u002Fhover-card.png) |\n| **Theme editor** — edit any colour, font or density live; save, duplicate, import\u002Fexport TOML or JSON | **Theme gallery** and the **marker hover card** (politician, amount, traded\u002Ffiled, disclosure lag) |\n| ![Portfolio summary: total value, unrealised P&L, cash, buying power, allocation bar, top holdings and accounts beside an AAPL chart](docs\u002Fimg\u002Fportfolio.png) | ![Positions table with quantity, live last price, average cost, value and unrealised P&L](docs\u002Fimg\u002Fpositions.png) |\n| **Portfolio** — `PORT`: value, unrealised P&L, cash and buying power, allocation, top holdings, accounts (simulated sample shown) | **Positions** — `POS`: live terminal quotes (cyan) reprice holdings; click a row to chart it |\n\nScreenshots are from the Linux build under Xvfb with live data (October 2026); on macOS the same UI\ngets the native title bar with traffic lights, window vibrancy behind the sidebar and SF fonts.\n\n## Features\n\n- **Multi-asset with Bloomberg-style market keys** — `AAPL \u003CEQUITY>`, `SPY \u003CEQUITY>`,\n  `SPX \u003CINDEX>`, `BTCUSD \u003CCRNCY>`, `EURUSD \u003CCRNCY>`, `US10Y \u003CGOVT>`, `CL1 \u003CCMDTY>` (keys display\n  as `AAPL US Equity`, `BTCUSD Curncy`, `US10Y Govt`, `CL1 Comdty`). The yellow key is optional for\n  known tickers. A built-in catalog covers ~120 instruments (regional indices, equity index futures,\n  energy\u002Fmetals\u002Fgrains, the full Treasury curve, majors and crosses, top crypto, popular ETFs and\n  large caps); anything else resolves by convention.\n- **Command line and search** — `\u003CSECURITY> [\u003CFUNCTION>] \u003CGO>` (Enter is `\u003CGO>`); typing anywhere\n  starts a command, with a live interpretation underneath (`5` → \"Interval 5 minutes\") and symbol\n  matches across all asset classes (catalog instantly, plus Yahoo search after a short pause);\n  ↑\u002F↓, Tab, Enter; history with ↑\u002F↓. `SECF gold cmdty` opens a full search panel.\n- **Charts** — GPU-rendered candles, OHLC bars, line and area; 1m, 5m, 15m, 30m, 1H, 4H, 1D, 1W,\n  1M plus quick ranges (1D … ALL); volume; 151 indicators; `CMP \u003CSYM>` compare; log scale;\n  crosshair with OHLC legend; smooth pan and zoom over a million bars. Live crypto bars from the\n  Binance websocket (Coinbase fallback).\n- **Indicators** — 151 built-in studies: 23 moving averages (SMA, EMA, WMA, Hull, DEMA\u002FTEMA, KAMA,\n  ALMA, T3, McGinley, VIDYA, FRAMA, MAMA\u002FFAMA, Ehlers filters, GMMA…), 8 bands and channels\n  (Bollinger, Keltner, Donchian, STARC, standard-error and VWAP bands…), 43 momentum oscillators\n  (RSI, MACD, Stochastic, StochRSI, CCI, Williams %R, TSI, KST, Fisher, Schaff, QQE, WaveTrend,\n  Connors RSI…), 22 trend tools (ADX\u002FDMI, Aroon, Vortex, Parabolic SAR, SuperTrend, Ichimoku,\n  Alligator, ZigZag, fractals, Chandelier and Chande Kroll stops…), 16 volatility measures (ATR,\n  close-to-close and Parkinson, Garman-Klass, Rogers-Satchell and Yang-Zhang estimators, Ulcer,\n  Mass index, squeeze momentum…), 23 volume studies (OBV, A\u002FD, CMF, MFI, Klinger, NVI\u002FPVI, VZO…),\n  11 rolling statistics and five pivot-point families. Type a code with optional parameters\n  (`RSI`, `SMA 200`, `BB 20 2.5`), browse and search with `IND`, or right-click the chart.\n  Oscillators get their own panes (up to six) with reference levels; moving averages can be added\n  several times; indicators are saved with the layout.\n- **Drawings** — trendline (Alt+T), horizontal (Alt+H), vertical (Alt+V) and fib retracement\n  (Alt+F), stored in (time, price) so they survive zoom and timeframe changes; magnet (Alt+M) snaps\n  to OHLC; click to select, Del to remove.\n- **Options** (`AAPL OMON`, ⌘⇧O) — full chains from Yahoo for US equities, ETFs and indices\n  (SPX via ^SPX): every expiration, calls and puts by strike with bid\u002Fask\u002Flast, change, volume,\n  open interest and IV, plus Black-Scholes greeks (Δ, Γ, Θ\u002Fday, vega) from each contract's IV, the\n  dividend yield and the 3-month T-bill rate; in-the-money shading, spot line, ±10\u002F±20\u002Fall\n  strikes; offline mode shows a flagged simulated chain.\n- **Markets** — `WEI` world markets (Americas\u002FEMEA\u002FAsia-Pacific indices, futures, Treasuries, FX,\n  crypto and commodities with sparklines), `GC` US Treasury yield curve (now vs 1M and 1Y ago,\n  2s10s \u002F 3m10y \u002F 5s30s), **news** (`AAPL CN`; Yahoo headlines, CoinDesk for crypto) and\n  **order book** depth (`BTCUSD CRNCY OB`; live Binance book, Coinbase fallback; markets without a\n  free public book show a clearly marked simulation).\n- **Market data behind a trait** (`tr_data::MarketData`), routed per asset class to free sources:\n\n  | Asset class | History | Quotes | Live |\n  |---|---|---|---|\n  | Crypto | Binance public REST (`data-api.binance.vision`, then `api.binance.com`), Coinbase Exchange fallback | Binance 24h ticker | Binance kline websocket, Coinbase ticker fallback |\n  | US Treasuries | Treasury.gov daily par yield curve CSV (FRED fallback); Yahoo `^IRX\u002F^FVX\u002F^TNX\u002F^TYX` intraday | Treasury.gov | — |\n  | FX, indices, futures | Yahoo Finance (`EURUSD=X`, `^GSPC`, `CL=F`) | Yahoo spark (batched) | — |\n  | Stocks, ETFs | Alpaca when `APCA_API_KEY_ID`\u002F`APCA_API_SECRET_KEY` are set, else Yahoo | Yahoo spark | — |\n\n  No keys are required. `TR_PROVIDER=sample` runs fully offline on deterministic, class-aware sample\n  data (BTCUSD near 65,000, EURUSD near 1.09, US10Y near 4.2%) **with simulated live ticks**, and\n  the live router falls back to sample data when a source is unreachable. Bars are cached in SQLite\n  so charts paint from disk on start. Older history pages in as you scroll left.\n- **Congress trades** (key feature)\n  - Ingests Periodic Transaction Reports from the **Senate eFD** (efdsearch.senate.gov: agreement\n    + CSRF session, DataTables search API, HTML transaction tables) and the **House Clerk**\n    (disclosures-clerk.house.gov: yearly `{year}FD.zip` XML index, PTR PDFs parsed with pure-Rust\n    text extraction). Scanned paper filings are detected and recorded as such.\n  - Normalises politician, party, chamber, state, ticker, buy\u002Fsell, amount range, transaction date\n    and filed date into SQLite. Party comes from the official rosters (clerk.house.gov\n    `MemberData.xml`, senate.gov `senators_cfm.xml`); politicians are keyed by bioguide ID, which\n    also repairs typos in the source index.\n  - Refreshed on a schedule (every 30 minutes by default, `TR_CONGRESS_REFRESH_MIN`, `0` disables;\n    `REFRESH`\u002FF6 forces one), incrementally — only unseen filings are fetched.\n  - Panels: latest trades feed with party\u002Fchamber\u002Fside filters (`CONG`); per-ticker \"who in\n    Congress traded it\" (`NVDA CONG`, or right-click any ticker); politician profile with trade\n    history and **estimated performance** (amount-weighted directional return, hit rate, average\n    disclosure lag) (`POL PELOSI`); directory (`POL`).\n  - **Chart overlay**: B\u002FS markers at transaction dates coloured by party (blue D, red R, purple\n    I); hover for a card with politician, amount, owner, traded\u002Ffiled dates and the disclosure lag.\n  - **Alerts**: `TRACK \u003Cname>` (or ☆ in the directory\u002Fprofile); when a tracked politician files a\n    new PTR you get a toast, an `ALERTS n` badge and an entry in `ALERTS`.\n\n- **Dockable workspace and saved layouts**\n  - Any panel (chart, watchlist, news, order book, world markets, yield curve, options, Congress\n    feed, politicians, alerts, search, settings, help) docks anywhere: drag a tab (or a pane's\n    header) onto another pane and drop on the compass (centre adds a tab, arrows split), with a\n    ghost preview and a labelled landing highlight, or drag to a window edge. Resize with\n    dividers (double-click to equalise), tabs in every pane, grid presets (`LAYOUT 1|2|2H|3|4|6`\n    or the toolbar), and pop any pane out into its own native window (close it to dock back).\n    Add panels from each pane's **+** menu, `NEW \u003CPANEL>` \u002F `SPLIT [DOWN] \u003CPANEL>` or ⌘1…⌘0.\n  - **Link groups**: give panes a colour (`LINK BLUE`, or the tab menu) and one security change\n    drives every linked chart, order book, news, options and per-ticker Congress pane; clicking a\n    row in a linked watchlist or world-markets pane loads it into the group.\n  - **Saved layouts**: save, name, rename, duplicate, delete and switch (`LAYOUT \u003Cname>`, the\n    sidebar list, ⌥1…⌥9); the active layout autosaves and is restored on launch. Each layout is a\n    JSON file in `~\u002FLibrary\u002FApplication Support\u002Fterminal\u002Flayouts` (`$XDG_DATA_HOME` on Linux)\n    and can be imported or exported (`LAYOUT EXPORT`\u002F`IMPORT`, or Settings › Layouts). Per-pane\n    settings (chart type, indicators, drawings, filters, depth, link, tab title) and, optionally,\n    the theme (`LAYOUT THEME ON`) save with the layout.\n- **Themes** — built-in Terminal Dark, Terminal Light, Bloomberg (amber on black, monospace,\n  compact), High Contrast, Solarized Dark\u002FLight, Nord and Monokai. A theme sets every colour\n  (backgrounds, panels, text, accent, up\u002Fdown, candles, grid, series), the interface and number\n  fonts and size, and density (compact, regular, comfortable). Pick one from the gallery in\n  Settings › Appearance, the View menu, `THEME \u003Cname>` (prefix match), `THEME NEXT|PREV|LIST` or\n  ⌘⌥T; `THEME SYSTEM` follows the OS with a chosen dark and light theme. Settings › Themes is a\n  live editor: editing a built-in makes a copy (built-ins stay read-only); duplicate, rename,\n  delete, import or export as TOML or JSON. Custom themes are TOML files in the `themes` folder\n  next to `layouts`; a partial file inherits everything else from Terminal Dark or Light.\n- **Native, compact UI** — a macOS unified compact toolbar with the traffic lights inset, a\n  translucent source-list sidebar with window vibrancy (`NSVisualEffectView` via `objc2`, in\n  `crates\u002Fmacos`) that can sit on either side (`SIDEBAR LEFT|RIGHT`, ⌘⌥S; the toolbar toggle moves\n  and mirrors with it, right-click it for the View menu), SF Pro for chrome and SF Mono for\n  numbers, segmented controls, spring animations, hover states and context menus. The System\n  theme follows the OS appearance and accent colour; charts render at native retina scale with\n  4x MSAA.\n- **Brokerage accounts (SnapTrade)** — connect your brokers once through SnapTrade's\n  Connection Portal (opened in your browser) and the terminal shows real accounts and balances\n  (`ACCT`), positions with unrealised P&L (`POS`), orders from the last 30 days (`ORD`), activity\n  such as trades, dividends, interest and transfers (`ACTV`) and a portfolio summary with\n  allocation (`PORT`). Holdings are repriced with the terminal's own live quotes; clicking a\n  position, order or activity row charts it, and right-click offers the option chain, news,\n  Congress trades and watchlist. `AAPL POS` \u002F `AAPL ORD` filter to one security, the account picker\n  to one account. Stocks, ETFs, funds, crypto and options (OCC symbols shown as `AAPL 350C`) are\n  supported. Read-only unless you turn on trading (below); Connect Brokerage requests read-only\n  access. Without credentials the panes show a setup screen; offline (`TR_PROVIDER=sample` or\n  `TR_BROKER=sample`) they show a clearly labelled simulated portfolio. See\n  [Brokerage setup](#brokerage-setup-snaptrade).\n- **Demo account and easy trading** — a **DEMO** paper-trading account ($100,000 virtual cash) is\n  selected by default; the toolbar badge shows DEMO or a red **LIVE** and switches between them\n  (switching to live asks first and is remembered). Buy\u002FSell buttons sit on charts, watchlist rows\n  and positions (plus **Close**), ⇧B \u002F ⇧S trade the security in focus, and `BUY AAPL 10`,\n  `SELL ALL TSLA`, `BUY NVDA $500`, `SELL MSFT 5 LMT 410` work from the command line or ⌘K. One\n  compact ticket: side, shares or dollars, market\u002Flimit (stops under More), live estimated cost\n  against buying power. Demo orders fill in one click at the live quote (limits and stops when\n  the quote crosses) and persist in the app data folder; Settings › Trading resets the account.\n  Live orders stay opt-in and go through SnapTrade's preview and a single confirmation. See\n  [Trading](#trading-opt-in).\n- **Command palette** — ⌘K (Ctrl+K on Linux and Windows) opens a centred, theme-matched palette\n  that fuzzy-searches every function code (`PORT`, `POS`, `ORD`, `OMON`, `THEME`, …), tickers\n  (load the quote and chart), new panels, layout presets and saved layouts, themes, Settings tabs\n  and workspace actions (move the sidebar, open Brokerage settings). Each row shows its shortcut;\n  recent picks come first. ↑↓ select, ↵ open, Esc close.\n- **Hotkeys and preferences** — every hotkey is rebindable from a native shortcut table in\n  Settings › Hotkeys and Help (click a binding, press the new keys); defaults for new charts and\n  order books; everything persists in `prefs.json`.\n\n## Running\n\n```sh\ncargo run --release                  # Yahoo data, congress ingest in the background\nTR_PROVIDER=sample cargo run --release   # offline\nAPCA_API_KEY_ID=… APCA_API_SECRET_KEY=… cargo run --release   # Alpaca\n```\n\nData lives in `~\u002FLibrary\u002FApplication Support\u002Fterminal` (macOS) or\n`$XDG_DATA_HOME\u002Fterminal` (Linux), or `TR_DATA_DIR`. Versions from before the project was renamed\nused a `terminal-rs` folder in the same place; the first launch moves it to `terminal` and leaves\na link at the old path, so builds that still use the old name find the same files. The first\ncongress ingest covers the current and previous year (a few minutes; it runs in the background\nwhile you work).\n`cargo run -p tr-congress --example ingest -- congress.sqlite3` runs one ingest from the CLI.\n\nAppearance: `TR_THEME=light|dark|\u003Ctheme name>` overrides the saved theme, `TR_MSAA=1|2|4|8` sets\nchart anti-aliasing (default 4 on macOS), `TR_VIBRANCY=0` disables the translucent sidebar, and\n⌃⌘S (Ctrl+Shift+S elsewhere) toggles the sidebar. `scripts\u002Fbundle-macos.sh` builds a retina-capable\n`Terminal.app` (icon from `scripts\u002Fbuild-icon.sh`); `scripts\u002Frelease-macos.sh` builds the universal (Apple Silicon + Intel) app,\nsigns it with a Developer ID certificate, notarizes it and packages `Terminal.dmg`,\nplus the zip and signed `appcast.xml` that installed copies update from (one-time credential\nsetup is at the top of the script). The app checks that feed once a day through\n[Sparkle](https:\u002F\u002Fsparkle-project.org) and offers to install a newer release; Terminal › Check\nfor Updates… or `UPDATE` checks at once. `scripts\u002Fcheck-macos-cross.sh` compiles\nand lints the whole workspace for aarch64-apple-darwin from Linux (zig as the C cross-compiler;\nlinking needs the macOS SDK).\n\n## In the browser\n\nThe same code also builds for WebAssembly and runs in a browser tab on WebGPU:\n\n```sh\nrustup target add wasm32-unknown-unknown\ncargo install wasm-bindgen-cli --version 0.2.129 --locked   # must match Cargo.lock\nbrew install binaryen                                       # wasm-opt\nscripts\u002Fbuild-web.sh                                        # writes site\u002Fstatic\u002Fapp\ncd site && npm run dev                                      # then open http:\u002F\u002Flocalhost:5173\u002Fapp\u002Findex.html\n```\n\n`scripts\u002Fbuild-web.sh \u003Cdir>` writes somewhere else instead; any static file server works. Add\n`?sample` to the URL to run offline on sample data, or `?fps` for the frame-time readout.\nEvery push to `master` builds it and deploys it with the site to\n[terminal.rasmic.xyz\u002Fapp](https:\u002F\u002Fterminal.rasmic.xyz\u002Fapp\u002F). Pull requests get a preview;\n[site\u002FREADME.md](site\u002FREADME.md#deploys) covers the workflow and the secrets it needs.\n\n![The browser build in Chrome: a live BTCUSD chart from Binance beside a demo-account position](docs\u002Fimg\u002Fweb-live-crypto.png)\n\nWhat the browser build can and can't do yet:\n\n- Crypto is live, because Binance and Coinbase allow cross-origin requests. History, quotes, order\n  books and websocket bars all come from them. Yahoo, Treasury.gov, Alpaca and CoinDesk don't allow\n  them, so every other market shows sample data and the toolbar says \"Crypto live\". A same-origin\n  proxy can fix that later.\n- Congress disclosures, SnapTrade accounts and live order entry need the desktop app. The paper\n  trading demo account works.\n- Layouts, settings, themes and the demo account are saved in `localStorage` under `terminal\u002F`.\n  The first load copies anything saved under the old `terminal-rs\u002F` prefix, without overwriting\n  newer entries.\n- Charts need WebGPU, since they read bars from storage buffers in the vertex shader. Browsers\n  without a WebGPU adapter get a second, larger build on WebGL2 where everything except the chart\n  series works.\n\nMeasured with Playwright driving Chrome 155 on an Apple M4 Pro:\n\n| | WebGPU build | WebGL2 build |\n|---|---|---|\n| `.wasm` | 5.60 MB (2.26 MB gzip, 1.69 MB brotli) | 7.48 MB (2.99 MB gzip, 2.22 MB brotli) |\n| JS glue | 115 KB | 169 KB |\n\n- A cold load from localhost draws its first frame 91 to 97 ms after navigation, the medians of\n  three runs of 9 loads, two headless and one in a Retina window. On a 50 Mbit\u002Fs link with 40 ms\n  of latency it takes 446 ms, and 1.64 s on 10 Mbit\u002Fs with 80 ms.\n- Panning and zooming a chart costs 1.3 to 1.5 ms of CPU in the UI code and 2.4 to 3.3 ms for the\n  whole frame (medians across runs), and holds the display's 60 Hz.\n- egui's two emoji fonts, 740 KB together, load after the first frame instead of inside the `.wasm`.\n\n## Brokerage setup (SnapTrade)\n\nEverything happens in **Settings › Brokerage**, with no commands needed. Open it from the sidebar\n(Portfolio › **Brokerage Settings**), the toolbar's View menu (**Brokerage Accounts…**), the gear\nbutton on any portfolio pane, or the setup screen; `PORT SETUP` still works too.\n\n1. Create API keys (a client ID and consumer key) in the\n   [SnapTrade dashboard](https:\u002F\u002Fdashboard.snaptrade.com). Personal keys work too.\n2. Enter the **Client ID** and **Consumer Key** (masked; **Show secrets** reveals them) and click\n   **Save**.\n3. Click **Register User**. This creates a SnapTrade user for this installation and saves its user\n   secret, which SnapTrade only returns once. With personal keys, leave the user fields empty.\n4. Click **Connect Brokerage…**. SnapTrade's Connection Portal opens in your browser with\n   read-only access; sign in to your broker there. New accounts appear within a minute.\n\nThe status card at the top always says where you are and what to do next (\"Not set up\",\n\"Connected · 3 accounts at 2 brokerages · synced 14:32\", or the API's error). **Test Connection**\nreloads accounts and connections on demand. **Connected brokerages** lists every connection with\nits accounts; a connection the broker has expired shows **Reconnect…**, which re-authenticates it in\nthe portal, and **Disconnect** removes a connection and its accounts from SnapTrade after an\nexplicit confirmation.\n\n**Where credentials live.** On macOS the client ID, consumer key, user ID and user secret are\nstored together in the **Keychain** (generic password, service `terminal`, account\n`snaptrade`); credentials saved under the old service, `terminal-rs`, move there the first time\nthe app reads them. Elsewhere they go in `\u003Cdata dir>\u002Fsecrets\u002Fsnaptrade.json` with owner-only permissions\n(0600 in a 0700 directory). They are never written to the repository, layouts, prefs or logs;\nrequest errors are scrubbed of the URL (which carries the user secret), and the settings screen\nmasks secrets. **Forget Credentials** removes them. `SNAPTRADE_CLIENT_ID`,\n`SNAPTRADE_CONSUMER_KEY`, `SNAPTRADE_USER_ID` and `SNAPTRADE_USER_SECRET` override the saved\nvalues field by field (useful for CI or a shell profile), and `TR_SECRET_STORE=file` uses the\nfile store on macOS.\n\n**How it talks to SnapTrade.** Requests go to `https:\u002F\u002Fapi.snaptrade.com` and are signed as the\nSnapTrade docs specify: `clientId` and a Unix `timestamp` in the query, and a `Signature` header\nholding a base64 HMAC-SHA256 (keyed with the consumer key) of the canonical JSON\n`{\"content\",\"path\",\"query\"}`. Portfolios refresh every two minutes while a portfolio pane is\nvisible (every 20 s for five minutes after opening the portal); `PORT REFRESH` reloads on demand.\nBrokerage data can be delayed or cached by SnapTrade depending on your plan, which is why holdings\nare repriced with the terminal's live quotes where a market key exists.\n\n## Trading (opt-in)\n\nThe **demo account** needs no setup: it is a local paper-trading account (`demo-account.json` in\nthe app data folder) with no commissions, no short selling and Day orders expiring at the 4 p.m.\nNew York close. Switch to your brokerage accounts with the toolbar badge, `MODE LIVE`, or\nSettings › Trading (`DEMO` switches back).\n\nLive trading is **off** until you enable it in **Settings › Trading**, which asks you to\nacknowledge that confirmed orders are real. Then:\n\n1. Make sure the connection allows trading. Connections made with **Connect Brokerage** are\n   read-only; **Reconnect with Trading Access…** in Settings › Trading opens the Connection Portal\n   asking for trading access where the broker supports it (`trade-if-available`). Settings ›\n   Trading lists, per brokerage, whether trading is available, from SnapTrade's\n   `allows_trading` flag and each connection's access type.\n2. Open a ticket (`BUY AAPL 10`, a Buy\u002FSell button, ⇧B \u002F ⇧S), pick the account and order type,\n   and click **Review**. The broker checks the order through SnapTrade's\n   [order impact](https:\u002F\u002Fdocs.snaptrade.com\u002Freference\u002FTrading\u002FTrading_getOrderImpact) endpoint;\n   nothing is placed.\n3. The broker's estimate opens one confirmation dialog. **Send** places exactly the previewed trade\n   (`POST \u002Ftrade\u002F{tradeId}`). Editing the ticket after previewing, or waiting past the preview's\n   validity (SnapTrade expires it after five minutes), requires a new preview.\n   A preview is used up when it is sent. If the answer is lost (network error, timeout, 5xx),\n   the ticket reports the status as **unknown** and opens `ORD`, because the broker may have\n   accepted the order; only a 4xx is reported as a rejection.\n\nWhich order types a broker accepts varies and SnapTrade does not publish it per broker, so the\npreview is where unsupported combinations are rejected. Dollar amounts work only for market\u002Fday\norders at brokers that support notional orders; fractional share quantities are refused up front\nat brokers SnapTrade reports as not supporting them. Settings › Trading also has an optional\n**maximum order value** and a default account.\n\nTrading access is read once per brokerage connection (`\u002Fauthorizations`), cached for an hour (on\ndisk too) with a **Refresh** button. SnapTrade requests are limited to four at a time; a\nrate-limited read waits for `Retry-After` and retries, and a rate limit is shown as a quiet\n\"retrying\" note rather than an error. Orders are never retried automatically.\n\nTests never place real orders: the trading client is exercised only against a local mock server,\nand the app's flows against the simulated portfolio and the demo account.\n\n## Keyboard shortcuts and commands\n\nPress **F1** (or type `HELP`) for the full, searchable list; every hotkey can be rebound in\nSettings › Hotkeys. On Linux and Windows ⌘ is Ctrl and ⌥ is Alt.\n\n| Keys | Action |\n|---|---|\n| ⌘K (Ctrl+K) | command palette: fuzzy search over commands, tickers, panels, layouts, themes, settings and actions |\n| F1 · F2 · F3 · F4 · F5 · F6 · F12 | help · Congress feed · politicians · alerts · watchlist · refresh filings · frame timing |\n| F7 · F8 · F9 | brokerage portfolio · positions · orders |\n| Tab · ⇧Tab | next · previous pane |\n| ⌘1 … ⌘0 · ⌘⇧O | new chart, watchlist, news, order book, world markets, yield curve, Congress, politicians, alerts, search pane · options chain |\n| ⌘D · ⌘⇧D · ⌘T · ⌘W · ⌘⇧P | split right · split down · new tab · close pane · pop out |\n| ⌘S · ⌥1 … ⌥9 | save layout · switch to saved layout 1–9 |\n| ⌃⌘S (Ctrl+Shift+S) · ⌘⌥S | toggle sidebar · move sidebar to the other side |\n| ⌘⌥T · ⌘, | cycle theme · settings |\n| ⌥T · ⌥H · ⌥V · ⌥F · ⌥M | draw trendline · horizontal · vertical · fib · magnet |\n| ⌥R · ⌥L · Esc · Del | reset chart view · log scale · cancel · delete selected drawing |\n| wheel · drag · drag axes · double-click | zoom · pan · stretch · reset |\n\n| Command | Action |\n|---|---|\n| `AAPL` · `AAPL US EQUITY \u003CGO>` | load a security in the focused chart |\n| `BTCUSD \u003CCRNCY>` · `EURUSD \u003CCRNCY>` · `US10Y \u003CGOVT>` · `CL1 \u003CCMDTY>` · `SPX \u003CINDEX>` | other asset classes |\n| `5` `1H` `D` `1W` `1M` · `YTD` `5Y` `ALL` | interval · quick range |\n| `RSI` `MACD` `SMA 200` `BB 20 2.5` · `IND` `IND VOLUME` · `CLEAR` | toggle any of the 151 indicators (optional parameters) · indicator picker · remove all |\n| `CMP MSFT` · `LOG` · `CANDLE` `BAR` `LINE` `AREA` | compare · log scale · chart type |\n| `AAPL OMON` · `AAPL CN` · `BTCUSD CRNCY OB` · `WEI` · `GC` · `SECF \u003Cquery>` | options · news · order book · world markets · yield curve · search |\n| `CONG` · `NVDA CONG` · `POL PELOSI` · `TRACK PELOSI` · `ALERTS` · `REFRESH` | Congress feed · who traded it · profile · track · alerts · refresh |\n| `NEW BOOK` · `SPLIT DOWN NEWS` · `POP` · `LINK GREEN` · `TITLE Desk` · `CLOSE` | add, split, pop out, link, rename, close panes |\n| `LAYOUT 4` · `LAYOUT SAVE Macro` · `LAYOUT Macro` · `LAYOUT RENAME Rates` · `LAYOUT DUP` · `LAYOUT DEL` · `LAYOUT EXPORT` | grid preset · saved layouts |\n| `THEME BLOOMBERG` · `THEME NEXT` · `THEME SYSTEM` · `THEME EDIT` · `THEME COMPACT` · `LAYOUT THEME ON` | themes |\n| `PORT` · `ACCT` · `POS` · `ORD` · `ACTV` · `AAPL POS` · `AAPL ORD` | brokerage portfolio · accounts and balances · positions · orders · activity · one security |\n| `PORT REFRESH` · `PORT CONNECT` · `PORT SETUP` (`BROKER`) | reload accounts · connect a broker in the browser · SnapTrade keys |\n| `BUY AAPL 10` · `SELL ALL TSLA` · `SELL MSFT 5 LMT 410` · `SELL TSLA 3 STP 250 LMT 245` · `BUY NVDA $500` · `TRADE` | order ticket, prefilled (demo: one click; live: review and confirm) |\n| `DEMO` · `MODE LIVE` · ⇧B · ⇧S | switch account mode · buy \u002F sell the security in focus |\n| `SIDEBAR RIGHT` · `SIDEBAR` · `PREFS` · `HELP` | sidebar side or visibility · settings · help |\n| right-click chart \u002F watchlist \u002F feed row \u002F sidebar toggle | context menu (chart type, indicators, draw, add to watchlist, who traded it, View menu) |\n\n## Architecture\n\n```\napp\u002F            eframe shell: command line, docked panes, chart widget, panels\n  dock.rs       docking tree (splits + tab groups): insert\u002Fmove\u002Fremove, layout, resize, presets\n  layouts.rs    saved layout documents (JSON) and the layouts folder store\n  prefs.rs      appearance, keymap and panel defaults (prefs.json)\n  themes.rs     theme model, built-in themes, TOML\u002FJSON theme files and the themes folder\n  app\u002F          workspace (drag and drop, pop-out windows, link groups), panels, settings, chrome\n  worker.rs     tokio runtime: all network, SQLite, pyramid and indicator work (UI never blocks)\n  storage.rs    saved files: the data folder on desktop, localStorage in the browser\n  web.rs        browser entry point (eframe web runner), console logging, frame timings\n  web\u002F          the page that hosts the browser build\ncrates\u002Fcore     Bar\u002FSeries, timeframes, market keys + security catalog, indicators and their\n                registry (codes, parameters, panes, levels), sample data\ncrates\u002Fdata     MarketData trait; per-class router (Binance\u002FCoinbase, Treasury.gov\u002FFRED, Yahoo,\n                Alpaca), websocket live feeds, sample provider with simulated ticks; bar cache;\n                the browser router (crypto live, the rest sampled) and a tokio\u002Fbrowser task shim\ncrates\u002Fchart    wgpu renderer, LOD pyramids, viewport math, axes, drawings, egui paint callback\ncrates\u002Fcongress Senate eFD + House Clerk parsers, rosters, SQLite store, refresh, alerts, performance\ncrates\u002Fbroker   SnapTrade client (request signing, accounts, balances, positions, orders, activity),\n                order entry (impact preview, place, cancel, capabilities), portfolio model and P&L,\n                Keychain \u002F owner-only credential store, simulated sample and order simulator\ndocs\u002Fanalysis   REA research notes on TradingView chart UX\n```\n\n**Rendering.** Bars are uploaded once per data version into a storage buffer as a level-of-detail\npyramid (level *k* merges 2^k bars), and geometry is generated in the vertex shader (one instance\nper bar or line segment). Each frame picks the level that keeps instances at ≥ 2 px, so the work per\nframe is bounded by the plot width, not the series length: a 1M-bar chart fully zoomed out draws\nabout 800 instances. Pan and zoom only rewrite a few hundred bytes of uniforms; bar indices are split\ninto integer and fraction for f32 precision at millions of bars. Axes, legend, crosshair, drawings and\nmarkers are cheap egui shapes.\n\n**Threading.** The UI thread sends requests to the worker and drains responses each frame; history\nfetches, pyramid building (≈ 200 ms for 1M bars), indicators, SQLite queries and the congress ingest\nall run on tokio tasks. The worker owns each chart's bar series, so initial history, paging and live\nwebsocket ticks merge into one copy; live updates are coalesced to at most four GPU re-uploads a\nsecond.\n\n## Performance\n\nMeasured on Linux with Mesa **llvmpipe (a CPU software rasterizer)** — a real GPU is much faster:\n\n- **Cold start**: window and GPU ready in **143 ms**; charts paint from the SQLite cache as soon as\n  the worker answers.\n- **1M-bar pan\u002Fzoom** (`cargo run --release -p tr-chart --example framebench`, 1600×900, candles +\n  volume + 2 overlays, 300 frames per phase):\n\n  | phase | CPU per frame p50 \u002F p99 | until GPU done p50 \u002F p99 |\n  |---|---|---|\n  | zoom out to all 1M bars | 0.07 \u002F 0.20 ms | 3.09 \u002F 5.27 ms |\n  | pan across history | 0.06 \u002F 0.18 ms | 1.40 \u002F 3.93 ms |\n  | zoom in to 8 px\u002Fbar | 0.05 \u002F 0.19 ms | 1.34 \u002F 2.63 ms |\n\n  All within the 8.33 ms budget for 120 fps even on the software rasterizer. Criterion versions:\n  `cargo bench -p tr-chart --bench frame`.\n- **In the app** (F12 readout, interactive wheel-zoom + drag): UI CPU ≈ 0.2 ms per frame, 118 fps.\n  To try a million bars interactively:\n  `TR_PROVIDER=sample TR_SAMPLE_BARS=1000000 TR_HISTORY_LIMIT=1000000 TR_FPS=1 cargo run --release`, then `1 \u003CGO>`.\n  With all 1M one-minute bars visible on llvmpipe under Xvfb the app measured UI CPU 0.36 ms and\n  76 fps for the whole window (software rasterization and presentation bound; the chart pass itself\n  is the benchmark above).\n- **Indicators over 1M bars** (`cargo bench -p tr-core`): SMA 1.8 ms, EMA 2.2 ms, VWAP 7.0 ms,\n  Bollinger 29 ms; RSI and MACD are single-pass (≈ 12 ms and 26 ms including first-touch of their\n  output memory). The whole 151-indicator catalogue at default parameters over 100k one-minute\n  bars takes ≈ 134 ms on macOS (Ichimoku, the slowest, 6.6 ms).\n\n## Tests\n\n```sh\ncargo test --workspace                       # unit + fixture tests (parsers, indicators, chart, app)\ncargo test -p tr-data -- --ignored           # live tests: every asset class, quotes, curve, search, websocket\ncargo bench -p tr-core && cargo bench -p tr-chart\n```\n\n- Parsers are tested against real filings captured from the official sources\n  (`crates\u002Fcongress\u002Ftests\u002Ffixtures`): multi-page House PDFs with partial sales and page-break rows,\n  spouse\u002Fjoint owners, wrapped and open-ended amounts, CUSIP vs ticker, exchanges, private holdings,\n  a scanned paper filing, Senate search JSON (electronic, paper and amended reports) and PTR tables.\n  An end-to-end refresh test covers discovery, roster joins, idempotency and alerts.\n- Data-source parsers are tested against captured responses: Binance klines\u002F24h ticker\u002Fwebsocket\n  kline frames, Coinbase candles\u002Fstats\u002Fwebsocket ticker, Treasury.gov curve CSV, FRED CSV, Yahoo\n  chart\u002Fspark\u002Fsearch. Market-key parsing, catalog search and symbol mapping per source are unit\n  tested; opt-in live tests hit the real sources for every asset class.\n- Indicators are checked against reference values (Wilder's RSI example, hand-computed EMA, MACD,\n  population-SD Bollinger, session VWAP) and hand-computed windows (stochastic, %R, CCI, WMA,\n  true range, Donchian, envelopes, %B, OBV and A\u002FD, CMF, Aroon, pivots). Every catalogue entry\n  runs on intraday and daily random walks and on degenerate input (no bars, one to three bars,\n  flat zero-volume bars) at its default, minimum and maximum parameters, checking alignment,\n  declared ranges and no panics; layouts saved in the old indicator format still load.\n- Layouts: the dock tree (insert, split, tab, move, remove\u002Fnormalise, resize clamping, presets,\n  JSON round trip and repair of hand-edited files), layout documents (every panel kind and its\n  settings, links, popped windows, older formats), the store (save, list, rename, duplicate,\n  delete, import, export, safe file names), migration from pre-docking settings, prefs and\n  keymap parsing\u002Frebinding.\n- Themes: every built-in round-trips through TOML and JSON, partial theme files inherit from the\n  dark\u002Flight base, the themes folder store (save, rename, delete, name collisions), copy-on-write\n  names and migration of older appearance preferences.\n- Brokerage: request signatures match values computed independently with Python's `hmac` over the\n  documented canonical JSON; an end-to-end test runs the client against a local mock SnapTrade\n  server that verifies every request's signature, timestamp and auth parameters and serves\n  fixtures shaped like the API's responses (stocks, ETFs, crypto, options, cash equivalents,\n  string and numeric decimals, a failing account); P&L for longs, shorts and option multipliers;\n  market-key mapping; OCC symbols; credential storage permissions and redaction; errors never\n  echo the user secret; every portfolio view renders.\n- Trading: order validation (prices per order type, stop-limit direction, notional rules,\n  path-safe ids); a mock SnapTrade trading server checks the signed symbol lookup, order impact,\n  placement of the previewed trade, cancel and portal requests; expired or simulated previews are\n  never sent; per-account capabilities from brokerage and connection; `BUY`\u002F`SELL`\u002F`TRADE`\n  parsing; edited tickets invalidate their preview; the simulator fills, rests and cancels orders.\n- The chart renders real frames offscreen on whatever adapter is present and checks pixels.\n\n## Platform notes and limitations\n\n- macOS is the primary target (wgpu Metal backend); Linux works with Vulkan or GL. This repository\n  was developed and run on Linux (X11, software Vulkan). For macOS, the GPU and UI stack (`tr-core`,\n  `tr-chart`, `tr-macos`, eframe\u002Fwinit) is cross-checked for `aarch64-apple-darwin`, and CI\n  (`.github\u002Fworkflows\u002Fci.yml`) builds, tests, lints and launches the app with screenshots on macOS\n  arm64 and Intel runners.\n- Scanned paper filings (some House PTRs and Senate `\u002Fpaper\u002F` reports) are recorded and alerted but\n  not OCR'd, so their trades are not itemised.\n- Estimated performance uses disclosed value bands (midpoints), so it is an estimate of trade-level\n  skill, not a reconstruction of anyone's portfolio.\n- Yahoo's chart endpoint is unofficial and rate-limited; use Alpaca for a supported free source.\n  Senate eFD terms prohibit using the data for commercial purposes or credit decisions; the terminal\n  accepts the eFD agreement on your behalf for personal research use.\n",2,"2026-10-31 04:26:40","CREATED_QUERY"]