gloomberb 0.17.6 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/package.json +6 -1
  4. package/patches/electrobun@1.18.1.patch +74 -0
  5. package/src/account/auth-model.ts +3 -2
  6. package/src/account/device-signin-dialog.tsx +38 -13
  7. package/src/account/device-signin.ts +2 -1
  8. package/src/account/upgrade-dialog.tsx +6 -2
  9. package/src/api-client/askg.ts +5 -3
  10. package/src/api-client/bank-figures.ts +73 -0
  11. package/src/api-client/credit-boards.ts +21 -1
  12. package/src/api-client/crypto-markets.ts +88 -1
  13. package/src/api-client/data.ts +104 -4
  14. package/src/api-client/debt-maturities.ts +18 -0
  15. package/src/api-client/equity-screener.ts +3 -0
  16. package/src/api-client/errors.ts +13 -0
  17. package/src/api-client/fund-facts.ts +72 -0
  18. package/src/api-client/futures-curve.ts +26 -3
  19. package/src/api-client/geo.ts +11 -1
  20. package/src/api-client/index.ts +25 -2
  21. package/src/api-client/insider-signals.ts +95 -11
  22. package/src/api-client/market-movers.ts +7 -0
  23. package/src/api-client/normalizers.ts +1 -0
  24. package/src/api-client/paths.ts +20 -1
  25. package/src/api-client/request.ts +11 -3
  26. package/src/api-client/research-activity.ts +15 -8
  27. package/src/api-client/socket.ts +6 -3
  28. package/src/api-client/supply-chain-graph.ts +2 -2
  29. package/src/api-client/supply-chain.ts +8 -0
  30. package/src/api-client/tape.ts +12 -0
  31. package/src/api-client/types.ts +75 -2
  32. package/src/api-client/upgrade-experiment.ts +4 -3
  33. package/src/api-client/wall-experiments.ts +5 -3
  34. package/src/api-client/wall-summary.ts +3 -1
  35. package/src/api-client/web-experiments.ts +5 -2
  36. package/src/api-client/yield-curves.ts +17 -0
  37. package/src/app/command-bar-intro.ts +38 -0
  38. package/src/app/keybindings/actions.ts +1 -1
  39. package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
  40. package/src/app/pane-runtime/plugin-bindings.ts +4 -0
  41. package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
  42. package/src/app/pane-runtime/ticker-open-target.ts +31 -0
  43. package/src/app/runtime/desktop-deeplink.ts +3 -4
  44. package/src/app/runtime/plugin-bindings.ts +3 -2
  45. package/src/app/runtime/startup.ts +3 -4
  46. package/src/app/runtime/ticker-refresh.ts +13 -12
  47. package/src/app/runtime/update.ts +3 -2
  48. package/src/architecture/core-builtin-allowlist.json +0 -3
  49. package/src/architecture/silent-catch-allowlist.json +3 -0
  50. package/src/architecture/ui-literals-allowlist.json +186 -0
  51. package/src/architecture/ui-tokens-allowlist.json +40 -0
  52. package/src/ask-gloom/pane-context.ts +3 -1
  53. package/src/brokers/signed-in/catalog.ts +2 -1
  54. package/src/brokers/signed-in/client.ts +7 -2
  55. package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
  56. package/src/brokers/signed-in/sign-in.ts +22 -20
  57. package/src/brokers/sync-broker-instance.ts +2 -1
  58. package/src/capabilities/chart-series.ts +2 -0
  59. package/src/capabilities/registry.ts +1 -3
  60. package/src/cli/bank-section.ts +147 -0
  61. package/src/cli/base-converter.ts +5 -2
  62. package/src/cli/board-coins.ts +70 -0
  63. package/src/cli/commands/fred-series.ts +105 -5
  64. package/src/cli/commands/market.ts +344 -69
  65. package/src/cli/commands/news-search.ts +35 -2
  66. package/src/cli/commands/options-chain.ts +7 -5
  67. package/src/cli/commands/options-leaps.ts +3 -3
  68. package/src/cli/commands/overview.ts +108 -34
  69. package/src/cli/commands/plugins.ts +1 -0
  70. package/src/cli/commands/search.ts +87 -24
  71. package/src/cli/commands/system.ts +5 -2
  72. package/src/cli/commands/ticker.ts +342 -62
  73. package/src/cli/context.ts +2 -1
  74. package/src/cli/desktop-pane-shot.ts +11 -3
  75. package/src/cli/earnings-calendar.ts +2 -1
  76. package/src/cli/errors.ts +10 -0
  77. package/src/cli/export-source.ts +18 -3
  78. package/src/cli/glossary.ts +196 -14
  79. package/src/cli/history-rows.ts +60 -9
  80. package/src/cli/index-roots.ts +26 -0
  81. package/src/cli/index.ts +34 -9
  82. package/src/cli/known-gaps.ts +156 -22
  83. package/src/cli/listing-arg.ts +156 -12
  84. package/src/cli/listing-suggestion.ts +4 -2
  85. package/src/cli/name-entries.ts +76 -0
  86. package/src/cli/not-a-ticker.ts +15 -6
  87. package/src/cli/pane-functions/access-gate.ts +22 -0
  88. package/src/cli/pane-functions/capabilities.ts +62 -4
  89. package/src/cli/pane-functions/catalog.ts +94 -39
  90. package/src/cli/pane-functions/data.ts +6 -5
  91. package/src/cli/pane-functions/discovery.ts +1 -1
  92. package/src/cli/pane-functions/dom.ts +3 -3
  93. package/src/cli/pane-functions/freshness.ts +49 -8
  94. package/src/cli/pane-functions/function-help.ts +17 -14
  95. package/src/cli/pane-functions/headless.ts +177 -42
  96. package/src/cli/pane-functions/index.ts +64 -8
  97. package/src/cli/pane-functions/options.ts +17 -3
  98. package/src/cli/pane-functions/report-notices.ts +17 -3
  99. package/src/cli/pane-functions/resolver.ts +48 -13
  100. package/src/cli/pane-functions/screenshot.ts +124 -23
  101. package/src/cli/pane-functions/shot-options.ts +68 -0
  102. package/src/cli/perpetual-contract.ts +3 -1
  103. package/src/cli/report-tables.ts +10 -2
  104. package/src/cli/staged-tickers.ts +5 -0
  105. package/src/cli/statement-filings.ts +261 -0
  106. package/src/cli/symbol-args.ts +47 -8
  107. package/src/cli/symbol-list.ts +60 -18
  108. package/src/cli/symbol-rows.ts +269 -29
  109. package/src/cli/ticker-resolution.ts +148 -34
  110. package/src/cli/treasury-yields.ts +86 -0
  111. package/src/cli/types.ts +3 -0
  112. package/src/cli/uncovered-instrument.ts +20 -0
  113. package/src/components/chart/composite/axis-overlays.tsx +16 -9
  114. package/src/components/chart/composite/composite-chart.tsx +96 -11
  115. package/src/components/chart/composite/downsample.ts +19 -3
  116. package/src/components/chart/composite/format.ts +3 -0
  117. package/src/components/chart/composite/legend.tsx +155 -76
  118. package/src/components/chart/composite/panel-bitmap.ts +8 -2
  119. package/src/components/chart/composite/panel-surface.tsx +9 -11
  120. package/src/components/chart/composite/price-axis-labels.tsx +2 -1
  121. package/src/components/chart/composite/toolbar.tsx +12 -7
  122. package/src/components/chart/composite/types.ts +10 -0
  123. package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
  124. package/src/components/chart/curve/curve-surface.tsx +1 -1
  125. package/src/components/chart/static/series.ts +39 -0
  126. package/src/components/chart/static/trail-chart-surface.tsx +2 -1
  127. package/src/components/command-bar/commands/collection-list.ts +45 -15
  128. package/src/components/command-bar/commands/collection.ts +10 -3
  129. package/src/components/command-bar/commands/registry.ts +2 -2
  130. package/src/components/command-bar/list/badge.ts +4 -3
  131. package/src/components/command-bar/list/model.ts +5 -0
  132. package/src/components/command-bar/list/view.tsx +1 -1
  133. package/src/components/command-bar/panel/index.tsx +19 -8
  134. package/src/components/command-bar/panel/native-surface.ts +6 -4
  135. package/src/components/command-bar/panel/prompt-example.ts +22 -0
  136. package/src/components/command-bar/routes/root/provider-search.ts +3 -9
  137. package/src/components/command-bar/routes/root/results.ts +13 -0
  138. package/src/components/command-bar/routes/root/start-here.ts +90 -0
  139. package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
  140. package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
  141. package/src/components/command-bar/theme-picker.tsx +3 -1
  142. package/src/components/command-bar/workflow/builtin.ts +5 -1
  143. package/src/components/command-bar/workflow/collection-actions.ts +25 -12
  144. package/src/components/command-bar/workflow/ops.ts +21 -1
  145. package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
  146. package/src/components/command-bar/workflow/tickers.ts +6 -4
  147. package/src/components/feedback-dialog.tsx +1 -1
  148. package/src/components/form-modal/broker-step.tsx +7 -63
  149. package/src/components/form-modal/content.tsx +7 -2
  150. package/src/components/form-modal/field-row.tsx +6 -8
  151. package/src/components/form-modal/host.tsx +3 -3
  152. package/src/components/form-modal/model.ts +3 -0
  153. package/src/components/form-modal/routes.ts +17 -2
  154. package/src/components/index.ts +6 -6
  155. package/src/components/input-search-bar.tsx +43 -6
  156. package/src/components/layout/detached-pane-shell.tsx +0 -1
  157. package/src/components/layout/floating-pane.tsx +0 -1
  158. package/src/components/layout/header.tsx +8 -7
  159. package/src/components/layout/pane/footer/index.tsx +7 -4
  160. package/src/components/layout/pane/footer/model.ts +28 -2
  161. package/src/components/layout/pane/header.tsx +9 -19
  162. package/src/components/layout/pane/index.tsx +0 -1
  163. package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
  164. package/src/components/layout/pane/pane-tabs.tsx +4 -3
  165. package/src/components/layout/pane/sizing.ts +9 -0
  166. package/src/components/layout/pane/ticker-fate-gate.tsx +8 -2
  167. package/src/components/layout/shell/pane/capture.ts +44 -20
  168. package/src/components/layout/status-bar.tsx +3 -6
  169. package/src/components/markdown-text.tsx +17 -2
  170. package/src/components/market-board/index.tsx +19 -8
  171. package/src/components/metric-treemap/heat-surface.tsx +2 -7
  172. package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
  173. package/src/components/onboarding/onboarding-frame.tsx +24 -21
  174. package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
  175. package/src/components/onboarding/wizard-positions.ts +48 -11
  176. package/src/components/pane-settings-dialog/desktop.tsx +12 -50
  177. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
  178. package/src/components/price-performance.tsx +18 -2
  179. package/src/components/reader/article-reader.tsx +11 -10
  180. package/src/components/reader/detail-reader.tsx +9 -5
  181. package/src/components/reader/reader-text.tsx +51 -24
  182. package/src/components/sign-in-code-panel.tsx +129 -75
  183. package/src/components/ticker/badge/index.tsx +2 -1
  184. package/src/components/ui/action-row.tsx +5 -2
  185. package/src/components/ui/audio-player.tsx +70 -0
  186. package/src/components/ui/card.tsx +75 -0
  187. package/src/components/ui/data-table/index.tsx +4 -2
  188. package/src/components/ui/data-table/types.ts +11 -0
  189. package/src/components/ui/detail-scroll-body.tsx +1 -1
  190. package/src/components/ui/dialog-actions.tsx +1 -21
  191. package/src/components/ui/display.tsx +13 -5
  192. package/src/components/ui/external-link.tsx +4 -2
  193. package/src/components/ui/fields.tsx +12 -0
  194. package/src/components/ui/figure.tsx +5 -3
  195. package/src/components/ui/frame.tsx +40 -6
  196. package/src/components/ui/icon.tsx +4 -0
  197. package/src/components/ui/index.ts +4 -1
  198. package/src/components/ui/list-view.tsx +8 -0
  199. package/src/components/ui/prose.tsx +97 -25
  200. package/src/components/ui/query-bar-keys.tsx +3 -1
  201. package/src/components/ui/query-bar.tsx +6 -0
  202. package/src/components/ui/quote.ts +42 -0
  203. package/src/components/ui/range-track.tsx +15 -2
  204. package/src/components/ui/reveal-in-scroll-box.ts +21 -3
  205. package/src/components/ui/select-button.tsx +38 -3
  206. package/src/components/ui/status.tsx +73 -4
  207. package/src/components/ui/table-layout.ts +20 -0
  208. package/src/components/use-pinned-moment.ts +19 -0
  209. package/src/core/app-runtime.ts +2 -2
  210. package/src/core/state/app/instrument.ts +18 -1
  211. package/src/core/state/app/layout.ts +6 -0
  212. package/src/core/state/app/state.ts +14 -2
  213. package/src/data/cached-query.ts +1 -1
  214. package/src/data/config/chart-settings.ts +3 -1
  215. package/src/data/config/home.ts +4 -1
  216. package/src/data/config/store/node.ts +9 -4
  217. package/src/data/config/store/normalize.ts +9 -0
  218. package/src/data/json-storage.ts +6 -3
  219. package/src/data/json-ticker-repository.ts +3 -1
  220. package/src/data/plugin-cache.ts +5 -1
  221. package/src/data/sqlite/json.ts +3 -1
  222. package/src/data/ticker-repository.ts +5 -2
  223. package/src/docs/snapshot.json +52 -17
  224. package/src/feedback/diagnostics.ts +2 -6
  225. package/src/i18n/es.ts +86 -6
  226. package/src/i18n/index.ts +3 -9
  227. package/src/i18n/ja.ts +86 -6
  228. package/src/i18n/ko.ts +86 -6
  229. package/src/i18n/zh-cn.ts +86 -6
  230. package/src/i18n/zh-tw.ts +86 -6
  231. package/src/layout-marketplace/gallery-desktop.tsx +8 -4
  232. package/src/market-data/bars-per-year.ts +43 -0
  233. package/src/market-data/bond-funds.ts +85 -0
  234. package/src/market-data/coordinator/auxiliary.ts +5 -2
  235. package/src/market-data/coordinator/index.ts +6 -5
  236. package/src/market-data/futures-contract.ts +102 -5
  237. package/src/market-data/hooks.tsx +20 -11
  238. package/src/market-data/market/bar-period.ts +36 -0
  239. package/src/market-data/market/format.ts +5 -13
  240. package/src/market-data/market/freshness.ts +1 -3
  241. package/src/market-data/market/index-level.ts +51 -0
  242. package/src/market-data/model-dividend-yield.ts +57 -16
  243. package/src/market-data/quotes/live-valuation.ts +48 -2
  244. package/src/market-data/realized-volatility.ts +16 -7
  245. package/src/market-data/tax-equivalent.ts +344 -0
  246. package/src/news/aggregator.ts +4 -2
  247. package/src/notifications/notification-log.ts +5 -3
  248. package/src/plugins/auto-update-node.ts +1 -0
  249. package/src/plugins/builtin/account-management/footer.ts +1 -1
  250. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  251. package/src/plugins/builtin/account-management/model.ts +1 -0
  252. package/src/plugins/builtin/account-management/pane.tsx +71 -19
  253. package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
  254. package/src/plugins/builtin/alerts/cli.ts +7 -18
  255. package/src/plugins/builtin/alerts/constants.ts +8 -0
  256. package/src/plugins/builtin/alerts/event-rows.ts +16 -0
  257. package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
  258. package/src/plugins/builtin/alerts/headless.ts +182 -0
  259. package/src/plugins/builtin/alerts/index.tsx +3 -0
  260. package/src/plugins/builtin/alerts/pane.tsx +1 -7
  261. package/src/plugins/builtin/alerts/storage.ts +17 -1
  262. package/src/plugins/builtin/analytics/index.tsx +7 -2
  263. package/src/plugins/builtin/analytics/metrics.ts +47 -9
  264. package/src/plugins/builtin/analytics/risk-client.ts +44 -11
  265. package/src/plugins/builtin/analytics/risk-fx.ts +61 -0
  266. package/src/plugins/builtin/analytics/risk-headless.ts +24 -3
  267. package/src/plugins/builtin/analytics/risk-math.ts +83 -0
  268. package/src/plugins/builtin/analytics/risk-model.ts +175 -19
  269. package/src/plugins/builtin/analytics/risk-pane.tsx +19 -8
  270. package/src/plugins/builtin/analytics/risk-test-data.ts +3 -0
  271. package/src/plugins/builtin/analytics/sector-model.ts +14 -3
  272. package/src/plugins/builtin/awards/headless.ts +6 -5
  273. package/src/plugins/builtin/awards/index.tsx +1 -1
  274. package/src/plugins/builtin/backtest/client.ts +38 -8
  275. package/src/plugins/builtin/backtest/engine.ts +25 -13
  276. package/src/plugins/builtin/backtest/export.ts +27 -0
  277. package/src/plugins/builtin/backtest/format.ts +19 -3
  278. package/src/plugins/builtin/backtest/headless.ts +42 -28
  279. package/src/plugins/builtin/backtest/index.tsx +3 -0
  280. package/src/plugins/builtin/backtest/pane.tsx +39 -10
  281. package/src/plugins/builtin/backtest/report.ts +160 -0
  282. package/src/plugins/builtin/backtest/rules.ts +2 -0
  283. package/src/plugins/builtin/backtest/window.ts +112 -0
  284. package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
  285. package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
  286. package/src/plugins/builtin/catalysts/headless.ts +24 -13
  287. package/src/plugins/builtin/catalysts/index.tsx +4 -2
  288. package/src/plugins/builtin/catalysts/model.ts +18 -1
  289. package/src/plugins/builtin/catalysts/pane.tsx +2 -2
  290. package/src/plugins/builtin/cds/client.ts +28 -5
  291. package/src/plugins/builtin/cds/headless.ts +183 -31
  292. package/src/plugins/builtin/cds/index.tsx +1 -1
  293. package/src/plugins/builtin/cds/model.ts +229 -53
  294. package/src/plugins/builtin/cds/pane.tsx +82 -26
  295. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
  296. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
  297. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
  298. package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
  299. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
  300. package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
  301. package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
  302. package/src/plugins/builtin/chart-composer/headless.ts +99 -21
  303. package/src/plugins/builtin/chart-composer/index.tsx +70 -13
  304. package/src/plugins/builtin/chart-composer/pane.tsx +65 -15
  305. package/src/plugins/builtin/chart-composer/presets.ts +79 -11
  306. package/src/plugins/builtin/chart-composer/series-catalog.ts +50 -14
  307. package/src/plugins/builtin/chart-composer/series-expression.ts +9 -7
  308. package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
  309. package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
  310. package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
  311. package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
  312. package/src/plugins/builtin/chat/content/composer.tsx +22 -1
  313. package/src/plugins/builtin/chat/content/index.tsx +35 -5
  314. package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
  315. package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
  316. package/src/plugins/builtin/chat/content/snapshot.ts +29 -6
  317. package/src/plugins/builtin/chat/ghost-user.ts +11 -3
  318. package/src/plugins/builtin/chat/layout.ts +2 -0
  319. package/src/plugins/builtin/chat/message/desktop.tsx +13 -5
  320. package/src/plugins/builtin/chat/message/header.tsx +26 -4
  321. package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
  322. package/src/plugins/builtin/chat/message/render-state.ts +28 -1
  323. package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
  324. package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
  325. package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
  326. package/src/plugins/builtin/chat/share/flow.tsx +9 -73
  327. package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
  328. package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
  329. package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
  330. package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
  331. package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
  332. package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
  333. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
  334. package/src/plugins/builtin/cloud/plugin.tsx +2 -0
  335. package/src/plugins/builtin/cloud/team/module.tsx +5 -1
  336. package/src/plugins/builtin/cloud/team/pane-sections.tsx +10 -3
  337. package/src/plugins/builtin/cloud/team/pane.tsx +35 -7
  338. package/src/plugins/builtin/cloud/team/views.ts +11 -4
  339. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
  340. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
  341. package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
  342. package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
  343. package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
  344. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
  345. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
  346. package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
  347. package/src/plugins/builtin/commodities-energy/index.tsx +8 -5
  348. package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
  349. package/src/plugins/builtin/company-attention/headless.ts +15 -7
  350. package/src/plugins/builtin/company-attention/index.tsx +1 -1
  351. package/src/plugins/builtin/company-attention/model.ts +49 -4
  352. package/src/plugins/builtin/company-attention/pane.tsx +11 -9
  353. package/src/plugins/builtin/company-kpis/headless.ts +4 -3
  354. package/src/plugins/builtin/company-kpis/index.tsx +2 -2
  355. package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
  356. package/src/plugins/builtin/congress-trades/headless.ts +23 -2
  357. package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
  358. package/src/plugins/builtin/cot/headless.ts +5 -2
  359. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
  360. package/src/plugins/builtin/credit-boards/client.ts +9 -2
  361. package/src/plugins/builtin/credit-boards/headless.ts +93 -27
  362. package/src/plugins/builtin/credit-boards/index.tsx +15 -4
  363. package/src/plugins/builtin/credit-boards/model.ts +105 -6
  364. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
  365. package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
  366. package/src/plugins/builtin/credit-documents/index.tsx +3 -0
  367. package/src/plugins/builtin/credit-documents/model.ts +3 -10
  368. package/src/plugins/builtin/crypto-board/client.ts +152 -2
  369. package/src/plugins/builtin/crypto-board/headless.ts +138 -19
  370. package/src/plugins/builtin/crypto-board/index.tsx +5 -3
  371. package/src/plugins/builtin/crypto-board/model.ts +210 -12
  372. package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
  373. package/src/plugins/builtin/crypto-board/series.ts +52 -1
  374. package/src/plugins/builtin/crypto-board/supply.ts +123 -0
  375. package/src/plugins/builtin/custom-view/loader.ts +3 -2
  376. package/src/plugins/builtin/custom-view/pane.tsx +5 -4
  377. package/src/plugins/builtin/custom-view/view-spec.ts +1 -0
  378. package/src/plugins/builtin/debt-maturities/client.ts +54 -1
  379. package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
  380. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  381. package/src/plugins/builtin/debt-maturities/model.ts +58 -13
  382. package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
  383. package/src/plugins/builtin/dividend-yield/client.ts +42 -36
  384. package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
  385. package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
  386. package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
  387. package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
  388. package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
  389. package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
  390. package/src/plugins/builtin/dividend-yield/types.ts +6 -1
  391. package/src/plugins/builtin/dividend-yield/view.ts +1 -1
  392. package/src/plugins/builtin/docs/blocks.tsx +54 -8
  393. package/src/plugins/builtin/docs/pane.tsx +8 -13
  394. package/src/plugins/builtin/earnings/headless.ts +3 -2
  395. package/src/plugins/builtin/earnings-calls/data.ts +51 -0
  396. package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
  397. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  398. package/src/plugins/builtin/earnings-calls/model.ts +97 -0
  399. package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
  400. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
  401. package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
  402. package/src/plugins/builtin/econ/calendar-model.ts +25 -2
  403. package/src/plugins/builtin/econ/calendar-source.ts +35 -0
  404. package/src/plugins/builtin/econ/fred-catalog.ts +6 -2
  405. package/src/plugins/builtin/econ/fred-series-map.ts +12 -1
  406. package/src/plugins/builtin/econ/index.tsx +40 -8
  407. package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
  408. package/src/plugins/builtin/econ-statistics/detail.tsx +8 -1
  409. package/src/plugins/builtin/econ-statistics/headless.ts +26 -5
  410. package/src/plugins/builtin/econ-statistics/pane.tsx +4 -2
  411. package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
  412. package/src/plugins/builtin/econ-statistics/view.ts +19 -0
  413. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  414. package/src/plugins/builtin/equity-screener/model.ts +46 -4
  415. package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
  416. package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
  417. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  418. package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
  419. package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
  420. package/src/plugins/builtin/executives/data.ts +24 -8
  421. package/src/plugins/builtin/executives/index.tsx +3 -18
  422. package/src/plugins/builtin/executives/pane.tsx +34 -10
  423. package/src/plugins/builtin/exposure/editor.tsx +3 -3
  424. package/src/plugins/builtin/fear-greed/index.tsx +9 -0
  425. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  426. package/src/plugins/builtin/futures/index.tsx +2 -2
  427. package/src/plugins/builtin/futures/model.ts +34 -21
  428. package/src/plugins/builtin/futures/table.tsx +1 -1
  429. package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
  430. package/src/plugins/builtin/futures-curve/headless.ts +4 -2
  431. package/src/plugins/builtin/futures-curve/model.ts +5 -7
  432. package/src/plugins/builtin/help/index.tsx +55 -8
  433. package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
  434. package/src/plugins/builtin/holders/headless.ts +12 -0
  435. package/src/plugins/builtin/insider/headless.ts +311 -41
  436. package/src/plugins/builtin/insider/index.tsx +280 -106
  437. package/src/plugins/builtin/insider/insiders.tsx +224 -0
  438. package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
  439. package/src/plugins/builtin/insider/signals-client.ts +135 -11
  440. package/src/plugins/builtin/insider/signals-model.ts +628 -56
  441. package/src/plugins/builtin/insider/signals.tsx +283 -83
  442. package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
  443. package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
  444. package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
  445. package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
  446. package/src/plugins/builtin/iv-history/headless.ts +2 -0
  447. package/src/plugins/builtin/jobs/headless.ts +1 -0
  448. package/src/plugins/builtin/jobs/index.tsx +1 -0
  449. package/src/plugins/builtin/jodi/headless.ts +2 -0
  450. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  451. package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
  452. package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
  453. package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
  454. package/src/plugins/builtin/market-movers/client.ts +2 -2
  455. package/src/plugins/builtin/market-movers/index.tsx +0 -3
  456. package/src/plugins/builtin/market-movers/session-body.tsx +27 -11
  457. package/src/plugins/builtin/market-movers/session.ts +25 -10
  458. package/src/plugins/builtin/market-valuation/pane.tsx +1 -1
  459. package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
  460. package/src/plugins/builtin/mna/distress/headless.ts +2 -1
  461. package/src/plugins/builtin/mna/headless.ts +14 -2
  462. package/src/plugins/builtin/mna/index.tsx +1 -0
  463. package/src/plugins/builtin/news/headless.ts +4 -0
  464. package/src/plugins/builtin/news/wire/feed-config.ts +4 -1
  465. package/src/plugins/builtin/news/wire/letters/client.ts +1 -0
  466. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +6 -3
  467. package/src/plugins/builtin/news/wire/news/detail-view.tsx +2 -1
  468. package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
  469. package/src/plugins/builtin/news/wire/news/table.tsx +59 -12
  470. package/src/plugins/builtin/news/wire/rss/feed-xml.ts +6 -1
  471. package/src/plugins/builtin/news/wire/rss/managed-feed.ts +1 -0
  472. package/src/plugins/builtin/notes/cli.ts +39 -10
  473. package/src/plugins/builtin/notes/export.ts +49 -3
  474. package/src/plugins/builtin/notes/files.ts +78 -21
  475. package/src/plugins/builtin/notes/index.tsx +3 -3
  476. package/src/plugins/builtin/notes/migration.ts +18 -6
  477. package/src/plugins/builtin/notes/owner.tsx +3 -2
  478. package/src/plugins/builtin/notes/quick-notes-pane.tsx +48 -12
  479. package/src/plugins/builtin/notes/store.ts +13 -3
  480. package/src/plugins/builtin/options-scenario/client.ts +7 -4
  481. package/src/plugins/builtin/options-scenario/headless.ts +5 -3
  482. package/src/plugins/builtin/pe-band/index.tsx +1 -1
  483. package/src/plugins/builtin/pe-band/model.ts +1 -15
  484. package/src/plugins/builtin/perps/headless.ts +30 -13
  485. package/src/plugins/builtin/perps/model.ts +45 -3
  486. package/src/plugins/builtin/perps/pane.tsx +7 -7
  487. package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
  488. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +133 -18
  489. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +268 -55
  490. package/src/plugins/builtin/portfolio-list/cli/render.ts +401 -48
  491. package/src/plugins/builtin/portfolio-list/cli/shared.ts +8 -2
  492. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +25 -35
  493. package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
  494. package/src/plugins/builtin/portfolio-list/headless.ts +153 -29
  495. package/src/plugins/builtin/portfolio-list/income.ts +296 -0
  496. package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
  497. package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
  498. package/src/plugins/builtin/portfolio-list/pane/index.tsx +38 -13
  499. package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
  500. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +3 -2
  501. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +10 -3
  502. package/src/plugins/builtin/portfolio-list/summary/index.tsx +36 -5
  503. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +42 -7
  504. package/src/plugins/builtin/portfolio-list/summary/totals.ts +31 -3
  505. package/src/plugins/builtin/portfolio-list/table.tsx +25 -5
  506. package/src/plugins/builtin/power/prices-headless.ts +2 -1
  507. package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
  508. package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
  509. package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
  510. package/src/plugins/builtin/realized-vol/headless.ts +6 -4
  511. package/src/plugins/builtin/realized-vol/model.ts +5 -1
  512. package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
  513. package/src/plugins/builtin/realized-vol/settings.ts +1 -1
  514. package/src/plugins/builtin/research/analyst-headless.ts +4 -0
  515. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -0
  516. package/src/plugins/builtin/research/event-model.ts +22 -2
  517. package/src/plugins/builtin/research/headless-schema.ts +1 -0
  518. package/src/plugins/builtin/research/headless.ts +3 -0
  519. package/src/plugins/builtin/research/index.tsx +3 -0
  520. package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
  521. package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
  522. package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
  523. package/src/plugins/builtin/reverse-dcf/headless.ts +9 -6
  524. package/src/plugins/builtin/reverse-dcf/index.tsx +2 -2
  525. package/src/plugins/builtin/reverse-dcf/model.ts +51 -4
  526. package/src/plugins/builtin/reverse-dcf/pane.tsx +23 -10
  527. package/src/plugins/builtin/risk-factors/headless.ts +7 -0
  528. package/src/plugins/builtin/risk-factors/index.tsx +1 -0
  529. package/src/plugins/builtin/scanner/feed.ts +5 -3
  530. package/src/plugins/builtin/scanner/headless.ts +9 -57
  531. package/src/plugins/builtin/scanner/index.ts +1 -2
  532. package/src/plugins/builtin/sec/forms.ts +2 -6
  533. package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
  534. package/src/plugins/builtin/sec/fund-facts.ts +328 -0
  535. package/src/plugins/builtin/sec/headless.ts +140 -44
  536. package/src/plugins/builtin/sec/index.tsx +95 -30
  537. package/src/plugins/builtin/sec/model.ts +2 -44
  538. package/src/plugins/builtin/shared/broker-reconnect.ts +105 -0
  539. package/src/plugins/builtin/shared/headless-options.ts +10 -0
  540. package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
  541. package/src/plugins/builtin/shared/move-rank.ts +108 -0
  542. package/src/plugins/builtin/shared/pro-feature-wall.tsx +9 -4
  543. package/src/plugins/builtin/shared/report-freshness.ts +25 -9
  544. package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
  545. package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
  546. package/src/plugins/builtin/shared/use-quote-board.ts +1 -0
  547. package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
  548. package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
  549. package/src/plugins/builtin/short-interest/headless.ts +3 -0
  550. package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
  551. package/src/plugins/builtin/social-mentions/client.ts +8 -1
  552. package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
  553. package/src/plugins/builtin/supply-chain/client.ts +12 -3
  554. package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
  555. package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
  556. package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
  557. package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
  558. package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
  559. package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
  560. package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
  561. package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
  562. package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
  563. package/src/plugins/builtin/supply-chain/headless.ts +69 -27
  564. package/src/plugins/builtin/supply-chain/index.tsx +1 -1
  565. package/src/plugins/builtin/supply-chain/model.ts +76 -15
  566. package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
  567. package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
  568. package/src/plugins/builtin/themes/model.ts +2 -5
  569. package/src/plugins/builtin/thirteenf/api.ts +54 -3
  570. package/src/plugins/builtin/thirteenf/data.ts +255 -12
  571. package/src/plugins/builtin/thirteenf/headless.ts +313 -28
  572. package/src/plugins/builtin/thirteenf/index.tsx +4 -1
  573. package/src/plugins/builtin/thirteenf/model.ts +244 -19
  574. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
  575. package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
  576. package/src/plugins/builtin/thirteenf/pane.tsx +31 -7
  577. package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
  578. package/src/plugins/builtin/thirteenf/types.ts +49 -0
  579. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -8
  580. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +17 -1
  581. package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
  582. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
  583. package/src/plugins/builtin/ticker-detail/headless.ts +23 -10
  584. package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
  585. package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
  586. package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
  587. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
  588. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +36 -3
  589. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
  590. package/src/plugins/builtin/time-sales/client.ts +7 -4
  591. package/src/plugins/builtin/time-sales/headless.ts +71 -22
  592. package/src/plugins/builtin/time-sales/model.ts +12 -0
  593. package/src/plugins/builtin/time-sales/pane.tsx +31 -7
  594. package/src/plugins/builtin/time-sales/window.ts +128 -0
  595. package/src/plugins/builtin/trace-bonds/client.ts +351 -33
  596. package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
  597. package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
  598. package/src/plugins/builtin/trace-bonds/model.ts +27 -25
  599. package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
  600. package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
  601. package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
  602. package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
  603. package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
  604. package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
  605. package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
  606. package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
  607. package/src/plugins/builtin/vol-surface/headless.ts +3 -2
  608. package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
  609. package/src/plugins/builtin/vol-surface/stored.ts +4 -7
  610. package/src/plugins/builtin/volatility/chart-model.ts +16 -15
  611. package/src/plugins/builtin/volatility/charts.tsx +5 -5
  612. package/src/plugins/builtin/volatility/client.ts +73 -2
  613. package/src/plugins/builtin/volatility/evidence.ts +13 -14
  614. package/src/plugins/builtin/volatility/headless.ts +13 -7
  615. package/src/plugins/builtin/volatility/index.tsx +1 -1
  616. package/src/plugins/builtin/volatility/model.ts +104 -38
  617. package/src/plugins/builtin/volatility/pane.tsx +42 -24
  618. package/src/plugins/builtin/volatility/series.ts +22 -13
  619. package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
  620. package/src/plugins/builtin/world-venue-map/headless.ts +8 -5
  621. package/src/plugins/builtin/world-venue-map/index.ts +16 -2
  622. package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
  623. package/src/plugins/builtin/yield-curve/curves.ts +29 -5
  624. package/src/plugins/builtin/yield-curve/headless.ts +41 -8
  625. package/src/plugins/builtin/yield-curve/history.ts +5 -5
  626. package/src/plugins/builtin/yield-curve/index.tsx +30 -13
  627. package/src/plugins/compat.ts +3 -1
  628. package/src/plugins/dependencies.ts +8 -2
  629. package/src/plugins/host-link.ts +12 -5
  630. package/src/plugins/installer.ts +16 -7
  631. package/src/plugins/loader.ts +9 -2
  632. package/src/plugins/marketplace/activation.ts +10 -4
  633. package/src/plugins/registry/host-actions.ts +3 -0
  634. package/src/plugins/registry/index.ts +3 -1
  635. package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +74 -12
  636. package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +140 -53
  637. package/src/portfolio/cost-fx.ts +84 -0
  638. package/src/portfolio/futures-positions.ts +213 -0
  639. package/src/portfolio/futures-terms.ts +75 -0
  640. package/src/portfolio/manual-lots.ts +78 -0
  641. package/src/portfolio/mutations.ts +70 -12
  642. package/src/portfolio/position-metrics.ts +89 -14
  643. package/src/portfolio/position-quantity.ts +43 -0
  644. package/src/portfolio/valuation-basis.ts +31 -4
  645. package/src/public/__snapshots__/public-api.test.ts.snap +4 -0
  646. package/src/public/time-series.ts +2 -1
  647. package/src/remote/confirm-change.tsx +2 -1
  648. package/src/remote/server.ts +1 -1
  649. package/src/remote/watchlist.ts +9 -1
  650. package/src/renderers/dom/data-table/row.tsx +1 -1
  651. package/src/renderers/dom/desktop/audio-player.tsx +312 -0
  652. package/src/renderers/dom/desktop/control-styles.ts +17 -82
  653. package/src/renderers/dom/desktop/controls.tsx +39 -63
  654. package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
  655. package/src/renderers/dom/desktop/icons.tsx +8 -0
  656. package/src/renderers/dom/desktop/list-view.tsx +6 -6
  657. package/src/renderers/dom/desktop/popover.tsx +0 -3
  658. package/src/renderers/dom/desktop/query-bar.tsx +6 -4
  659. package/src/renderers/dom/desktop/select-field.tsx +9 -8
  660. package/src/renderers/dom/desktop/stack-header.ts +3 -0
  661. package/src/renderers/dom/dom-ui-host.tsx +3 -2
  662. package/src/renderers/dom/host/chart-surface.tsx +3 -3
  663. package/src/renderers/dom/host/size-observer.ts +33 -4
  664. package/src/renderers/dom/host/surface-3d.tsx +3 -2
  665. package/src/renderers/dom/host/surface-fit.ts +4 -1
  666. package/src/renderers/dom/host/tabs.tsx +22 -132
  667. package/src/renderers/dom/styles.css +358 -160
  668. package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
  669. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
  670. package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
  671. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
  672. package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
  673. package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
  674. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
  675. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  676. package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
  677. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
  678. package/src/series/capability.ts +1 -0
  679. package/src/series/files.ts +9 -3
  680. package/src/series/registry.ts +40 -14
  681. package/src/series/resolve.ts +121 -18
  682. package/src/series/standalone.ts +3 -2
  683. package/src/series/types.ts +55 -1
  684. package/src/series/validate.ts +39 -0
  685. package/src/shares/api.ts +26 -7
  686. package/src/shares/bug-report-dialog.tsx +2 -2
  687. package/src/shares/bug-report-flow.tsx +4 -7
  688. package/src/shares/capture-flow.ts +5 -4
  689. package/src/shares/capture-preview.tsx +2 -2
  690. package/src/shares/chat.ts +7 -27
  691. package/src/shares/flow.tsx +86 -40
  692. package/src/shares/location.ts +1 -3
  693. package/src/shares/pane-image.ts +11 -9
  694. package/src/shares/pane.ts +5 -2
  695. package/src/shares/payload.ts +1 -1
  696. package/src/shares/personal-pane.ts +3 -3
  697. package/src/shares/portable-layout.ts +9 -2
  698. package/src/shares/ready.ts +42 -0
  699. package/src/shares/test-harness.ts +62 -0
  700. package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
  701. package/src/sources/gloomberb-cloud/fred-series.ts +27 -2
  702. package/src/sources/gloomberb-cloud/index.ts +64 -12
  703. package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
  704. package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
  705. package/src/sources/history-omitted.ts +34 -0
  706. package/src/sources/history-result.ts +3 -0
  707. package/src/sources/history-retention.ts +1 -1
  708. package/src/sources/provider-errors.ts +43 -1
  709. package/src/sources/provider-router/batches.ts +3 -2
  710. package/src/sources/provider-router/cache.ts +2 -1
  711. package/src/sources/provider-router/cached-routes.ts +9 -3
  712. package/src/sources/provider-router/history.ts +9 -8
  713. package/src/sources/provider-router/index.ts +18 -3
  714. package/src/sources/provider-router/primary.ts +5 -4
  715. package/src/sources/provider-router/quote-route.ts +3 -1
  716. package/src/sources/provider-router/routing.ts +2 -1
  717. package/src/sources/provider-router/search.ts +47 -13
  718. package/src/sources/provider-router/streaming.ts +7 -4
  719. package/src/sources/sec-edgar.ts +1 -3
  720. package/src/state/app/context/index.tsx +9 -13
  721. package/src/state/app/tab-cursor.ts +149 -12
  722. package/src/state/hooks/quote-streaming.ts +3 -2
  723. package/src/state/hooks/session-snapshot.ts +3 -2
  724. package/src/state/persist-scheduler.ts +12 -4
  725. package/src/sync/controller.ts +22 -1
  726. package/src/sync/core-contributors.ts +59 -15
  727. package/src/team/collections-sync.ts +14 -4
  728. package/src/team/collections.ts +42 -11
  729. package/src/team/store.ts +5 -4
  730. package/src/telemetry/attention-counts.ts +8 -2
  731. package/src/telemetry/crash-reports-dom.ts +3 -0
  732. package/src/telemetry/crash-reports-node.ts +7 -4
  733. package/src/telemetry/crash-reports.ts +11 -11
  734. package/src/telemetry/usage-counts.ts +16 -12
  735. package/src/theme/colors.ts +2 -0
  736. package/src/theme/font-scale.ts +2 -0
  737. package/src/theme/ui-tokens.ts +71 -0
  738. package/src/tickers/batched-lookups.ts +186 -0
  739. package/src/tickers/company-name-listing.ts +97 -0
  740. package/src/tickers/company-name.ts +13 -0
  741. package/src/tickers/instrument-coverage.ts +112 -0
  742. package/src/tickers/listing-fate.ts +49 -9
  743. package/src/tickers/listing-venues.ts +24 -5
  744. package/src/tickers/metadata.ts +10 -0
  745. package/src/tickers/open-target.ts +13 -5
  746. package/src/tickers/search/index.ts +112 -35
  747. package/src/tickers/search/ranking.ts +49 -1
  748. package/src/tickers/terminal-codes.ts +79 -0
  749. package/src/tickers/ticker-changes.ts +74 -3
  750. package/src/tickers/us-listing.ts +2 -1
  751. package/src/time-series/chart-data.ts +79 -8
  752. package/src/time-series/fundamentals.ts +55 -7
  753. package/src/time-series/ice-credit.ts +17 -2
  754. package/src/time-series/live-bars.ts +21 -8
  755. package/src/time-series/live-quotes.ts +2 -3
  756. package/src/time-series/price-comparison.ts +6 -1
  757. package/src/time-series/resolve.ts +65 -10
  758. package/src/time-series/spec.ts +2 -1
  759. package/src/time-series/studies.ts +3 -3
  760. package/src/time-series/types.ts +22 -0
  761. package/src/time-series/use-chart-resolution.ts +2 -1
  762. package/src/types/config.ts +7 -0
  763. package/src/types/data-provider.ts +20 -0
  764. package/src/types/headless.ts +142 -1
  765. package/src/types/instrument.ts +6 -0
  766. package/src/types/plugin.ts +32 -9
  767. package/src/types/price-history.ts +5 -0
  768. package/src/types/ticker-changes.ts +19 -0
  769. package/src/types/ticker.ts +19 -2
  770. package/src/ui/context-menu.tsx +2 -0
  771. package/src/ui/host.tsx +40 -4
  772. package/src/ui/measured-cells.ts +13 -7
  773. package/src/ui/qr.ts +7 -5
  774. package/src/updater/index.ts +5 -5
  775. package/src/utils/calendar-date.ts +86 -27
  776. package/src/utils/currency-units.ts +26 -0
  777. package/src/utils/debug-log.ts +1 -1
  778. package/src/utils/dividend-cash.ts +48 -0
  779. package/src/utils/dom-screenshot-rasters.ts +3 -1
  780. package/src/utils/dom-screenshot.ts +14 -10
  781. package/src/utils/exchange-rate-snapshot.ts +9 -4
  782. package/src/utils/external-url.ts +1 -0
  783. package/src/utils/fiscal-period.ts +47 -0
  784. package/src/utils/format.ts +5 -2
  785. package/src/utils/forward-dividend.ts +160 -11
  786. package/src/utils/futures-generic.ts +34 -8
  787. package/src/utils/http-proxy-response.ts +2 -1
  788. package/src/utils/local-utc-offset.ts +2 -0
  789. package/src/utils/log-failure.ts +31 -0
  790. package/src/utils/option-expiry.ts +12 -12
  791. package/src/utils/price-history-integrity.ts +56 -0
  792. package/src/utils/price-history.ts +13 -1
  793. package/src/utils/sec-filings.ts +245 -0
  794. package/src/utils/selection-clipboard.ts +5 -2
  795. package/src/utils/throttled-fetch.ts +1 -0
  796. package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
  797. package/src/utils/url.ts +1 -0
  798. package/src/utils/utc-time.ts +11 -0
  799. package/src/plugins/builtin/chat/share/targets.ts +0 -27
  800. package/src/renderers/dom/host/top-surface.ts +0 -119
  801. package/src/shares/dialog.tsx +0 -221
  802. package/src/shares/live.ts +0 -19
@@ -5,6 +5,7 @@ import type { HeadlessPaneFreshness } from "../../../types/headless";
5
5
  import type { TickerRecord } from "../../../types/ticker";
6
6
  import { formatCompact } from "../../../utils/format";
7
7
  import { compareSortValues, type SortPreference } from "../../../utils/sort-values";
8
+ import { formatMove } from "../credit-boards/model";
8
9
 
9
10
  export const CDS_PANE_ID = "cds";
10
11
 
@@ -51,8 +52,26 @@ export interface CdsIssuerSummary {
51
52
  /** The latest level of the issuer's 5Y line and its date, where it has one: what the list ranks by. */
52
53
  spread5yBp: number | null;
53
54
  spread5yDate: string | null;
55
+ /** That level's 1W and 1M moves in bp, through the roll, while the level is current. */
56
+ change1wBp: number | null;
57
+ change1mBp: number | null;
58
+ /** How the level is quoted: in bp, or past 2,000bp in points upfront. */
59
+ quote: CdsQuote;
60
+ /** Quoted upfront: the level in points on its running coupon, and its 1W and 1M moves in points. */
61
+ upfrontPts: number | null;
62
+ change1wPts: number | null;
63
+ change1mPts: number | null;
64
+ /** The running coupon of a name quoted upfront, bp. */
65
+ couponBp: number | null;
54
66
  }
55
67
 
68
+ /**
69
+ * Past 2,000bp a name trades on points upfront over its running coupon, so the
70
+ * server quotes it that way (`58.2 pts`), as the index board quotes HY in price.
71
+ */
72
+ type CdsQuote = "spread" | "upfront";
73
+ export type CdsQuoteUnit = "bp" | "pts";
74
+
56
75
  /**
57
76
  * Legal-name noise the tape spells inconsistently: "Oracle Corporation",
58
77
  * "ORACLE CORPORATION", and "Oracle Cop" are one issuer. Only suffixes and
@@ -260,6 +279,9 @@ export function summarizeIssuers(trades: readonly CdsTrade[]): CdsIssuerSummary[
260
279
  latestSpreadBp: trade.spreadBp,
261
280
  spread5yBp: null,
262
281
  spread5yDate: null,
282
+ change1wBp: null,
283
+ change1mBp: null,
284
+ ...NO_UPFRONT,
263
285
  });
264
286
  if (trade.spreadBp != null) spreadAt.set(trade.issuerKey, trade.eventAt);
265
287
  continue;
@@ -275,8 +297,24 @@ export function summarizeIssuers(trades: readonly CdsTrade[]): CdsIssuerSummary[
275
297
  return [...byIssuer.values()];
276
298
  }
277
299
 
278
- /** The latest 5Y level and its date, by issuer key. */
279
- export type CdsSpreadLevels = ReadonlyMap<string, { spreadBp: number; date: string }>;
300
+ interface CdsSpreadLevel {
301
+ spreadBp: number;
302
+ date: string;
303
+ change1wBp: number | null;
304
+ change1mBp: number | null;
305
+ quote: CdsQuote;
306
+ upfrontPts: number | null;
307
+ change1wPts: number | null;
308
+ change1mPts: number | null;
309
+ couponBp: number | null;
310
+ }
311
+
312
+ const NO_UPFRONT = { quote: "spread", upfrontPts: null, change1wPts: null, change1mPts: null, couponBp: null } as const;
313
+
314
+ /** The latest 5Y level, its date, its 1W and 1M moves and how it is quoted, by issuer key. */
315
+ export type CdsSpreadLevels = ReadonlyMap<string, CdsSpreadLevel>;
316
+
317
+ const finiteOrNull = (value: unknown): number | null => (typeof value === "number" && Number.isFinite(value) ? value : null);
280
318
 
281
319
  /**
282
320
  * The backend's levels under the key the list groups issuers by, so every
@@ -285,7 +323,7 @@ export type CdsSpreadLevels = ReadonlyMap<string, { spreadBp: number; date: stri
285
323
  * list would show keeps it. Malformed entries are left out.
286
324
  */
287
325
  export function spreadLevelsOf(levels: readonly CloudCdsLevelPayload[]): CdsSpreadLevels {
288
- const byKey = new Map<string, { issuer: string; spreadBp: number; date: string }>();
326
+ const byKey = new Map<string, { issuer: string; level: CdsSpreadLevel }>();
289
327
  for (const level of levels) {
290
328
  if (typeof level.issuer !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(level.date) || !Number.isFinite(level.spreadBp)) continue;
291
329
  const issuer = displayIssuerName(level.issuer);
@@ -293,17 +331,36 @@ export function spreadLevelsOf(levels: readonly CloudCdsLevelPayload[]): CdsSpre
293
331
  const key = issuerGroupKey(issuer);
294
332
  const current = byKey.get(key);
295
333
  if (current && preferredIssuerName(current.issuer, issuer) === current.issuer) continue;
296
- byKey.set(key, { issuer, spreadBp: level.spreadBp, date: level.date });
334
+ const upfrontPts = finiteOrNull(level.upfrontPts);
335
+ byKey.set(key, {
336
+ issuer,
337
+ level: {
338
+ spreadBp: level.spreadBp,
339
+ date: level.date,
340
+ change1wBp: finiteOrNull(level.change1W),
341
+ change1mBp: finiteOrNull(level.change1M),
342
+ // A server before points upfront, or a level it could not convert, stays in bp.
343
+ ...(level.quote === "upfront" && upfrontPts != null ? {
344
+ quote: "upfront",
345
+ upfrontPts,
346
+ change1wPts: finiteOrNull(level.change1WPts),
347
+ change1mPts: finiteOrNull(level.change1MPts),
348
+ couponBp: finiteOrNull(level.couponBp),
349
+ } : NO_UPFRONT),
350
+ },
351
+ });
297
352
  }
298
- return new Map([...byKey].map(([key, { spreadBp, date }]) => [key, { spreadBp, date }]));
353
+ return new Map([...byKey].map(([key, { level }]) => [key, level]));
299
354
  }
300
355
 
301
- /** Each issuer with the latest level of its 5Y line, where it has one, so the list ranks by it. */
356
+ /** Each issuer with the latest level of its 5Y line and its moves, where it has one, so the list ranks by them. */
302
357
  export function withSpreadLevels(rows: readonly CdsIssuerSummary[], levels: CdsSpreadLevels | null): CdsIssuerSummary[] {
303
358
  if (!levels?.size) return [...rows];
304
359
  return rows.map((row) => {
305
360
  const level = levels.get(row.key);
306
- return level ? { ...row, spread5yBp: level.spreadBp, spread5yDate: level.date } : row;
361
+ if (!level) return row;
362
+ const { spreadBp, date, ...moves } = level;
363
+ return { ...row, spread5yBp: spreadBp, spread5yDate: date, ...moves };
307
364
  });
308
365
  }
309
366
 
@@ -406,6 +463,41 @@ export function formatBp(value: number | null): string {
406
463
  return `${Math.abs(value) >= 100 ? Math.round(value) : Math.round(value * 10) / 10}bp`;
407
464
  }
408
465
 
466
+ /** Points upfront to a tenth: `58.2 pts`. */
467
+ export function formatPoints(value: number | null): string {
468
+ if (value == null || !Number.isFinite(value)) return "--";
469
+ return `${value.toFixed(1)} pts`;
470
+ }
471
+
472
+ /** A move in points upfront, signed as the bp moves are: `+10.9 pts`. */
473
+ export function formatPointsMove(value: number | null): string {
474
+ if (value == null || !Number.isFinite(value)) return "--";
475
+ const rounded = Number(value.toFixed(1));
476
+ return `${rounded > 0 ? "+" : ""}${(rounded === 0 ? 0 : rounded).toFixed(1)} pts`;
477
+ }
478
+
479
+ /** A level in the unit it is quoted in. */
480
+ export function formatQuoted(unit: CdsQuoteUnit, value: number | null): string {
481
+ return unit === "pts" ? formatPoints(value) : formatBp(value);
482
+ }
483
+
484
+ /** A 1W or 1M move in the unit its level is quoted in. */
485
+ export function formatQuotedMove(unit: CdsQuoteUnit, value: number | null): string {
486
+ return unit === "pts" ? formatPointsMove(value) : formatSpreadMove(value);
487
+ }
488
+
489
+ /** A listed issuer's level and moves as quoted: bp, or points upfront for a name quoted upfront. */
490
+ export function quotedLevel(row: CdsIssuerSummary): {
491
+ unit: CdsQuoteUnit;
492
+ level: number | null;
493
+ change1w: number | null;
494
+ change1m: number | null;
495
+ } {
496
+ return row.quote === "upfront"
497
+ ? { unit: "pts", level: row.upfrontPts, change1w: row.change1wPts, change1m: row.change1mPts }
498
+ : { unit: "bp", level: row.spread5yBp, change1w: row.change1wBp, change1m: row.change1mBp };
499
+ }
500
+
409
501
  export function formatNotional(trade: Pick<CdsTrade, "notional" | "notionalCapped">): string {
410
502
  if (trade.notional == null) return "--";
411
503
  return `${formatCompact(trade.notional)}${trade.notionalCapped ? "+" : ""}`;
@@ -440,21 +532,40 @@ export function formatMaturity(maturity: string | null): string {
440
532
  return maturity ?? "--";
441
533
  }
442
534
 
443
- export type IssuerColumnId = "issuer" | "trades" | "last" | "spread";
535
+ export type IssuerColumnId = "issuer" | "trades" | "last" | "spread" | "1w" | "1m";
444
536
  export type IssuerColumn = DataTableColumn & { id: IssuerColumnId };
445
537
  export type IssuerSortPreference = SortPreference<IssuerColumnId>;
446
538
 
447
- export const ISSUER_SORT_COLUMN_IDS: readonly IssuerColumnId[] = ["issuer", "trades", "last", "spread"];
539
+ export const ISSUER_SORT_COLUMN_IDS: readonly IssuerColumnId[] = ["issuer", "trades", "last", "spread", "1w", "1m"];
448
540
  /** "Most active" is the reason the market-wide view exists. */
449
541
  export const DEFAULT_ISSUER_SORT: IssuerSortPreference = { columnId: "trades", direction: "desc" };
450
542
 
451
- /** The issuer takes the room the figures leave; the table lays it out. */
543
+ /**
544
+ * What `fn CDS --sort` ranks the list by, each largest first: the most
545
+ * active, the widest, the widest move. By level or move, the names quoted in
546
+ * bp come first, then those quoted in points, then those without one.
547
+ */
548
+ export const ISSUER_LIST_SORTS = ["trades", "spread", "1w", "1m"] as const;
549
+
550
+ /** The list's order for a `--sort` value; an unknown one keeps the default. */
551
+ export function issuerListSort(value: unknown): IssuerSortPreference {
552
+ return (ISSUER_LIST_SORTS as readonly unknown[]).includes(value)
553
+ ? { columnId: value as (typeof ISSUER_LIST_SORTS)[number], direction: "desc" }
554
+ : DEFAULT_ISSUER_SORT;
555
+ }
556
+
557
+ /**
558
+ * The issuer takes the room the figures leave; the level and its moves sit as
559
+ * the index board's do, under `5Y` since a name can be quoted in points.
560
+ */
452
561
  export function buildIssuerColumns(): IssuerColumn[] {
453
562
  return [
454
563
  { id: "issuer", label: "ISSUER", width: 16, align: "left", flexGrow: 1 },
455
564
  { id: "trades", label: "TRADES", width: 7, align: "right" },
456
565
  { id: "last", label: "LAST UTC", width: 16, align: "left" },
457
- { id: "spread", label: "5Y SPREAD", width: 10, align: "right" },
566
+ { id: "spread", label: "5Y", width: 10, align: "right" },
567
+ { id: "1w", label: "1W", width: 10, align: "right" },
568
+ { id: "1m", label: "1M", width: 10, align: "right" },
458
569
  ];
459
570
  }
460
571
 
@@ -467,10 +578,21 @@ function issuerSortValue(columnId: IssuerColumnId, row: CdsIssuerSummary): strin
467
578
  case "last":
468
579
  return row.lastTradeAt;
469
580
  case "spread":
470
- return row.spread5yBp;
581
+ return quotedLevel(row).level;
582
+ case "1w":
583
+ return quotedLevel(row).change1w;
584
+ case "1m":
585
+ return quotedLevel(row).change1m;
471
586
  }
472
587
  }
473
588
 
589
+ /** By level or move: bp first, then points (another unit), then none, whichever way the column sorts. */
590
+ function quoteGroup(columnId: IssuerColumnId, row: CdsIssuerSummary): number {
591
+ if (columnId !== "spread" && columnId !== "1w" && columnId !== "1m") return 0;
592
+ if (issuerSortValue(columnId, row) == null) return 2;
593
+ return row.quote === "upfront" ? 1 : 0;
594
+ }
595
+
474
596
  export function sortIssuers(
475
597
  rows: readonly CdsIssuerSummary[],
476
598
  sort: IssuerSortPreference,
@@ -478,7 +600,7 @@ export function sortIssuers(
478
600
  const columnId = sort.columnId;
479
601
  if (!columnId) return [...rows];
480
602
  return [...rows].sort((left, right) => {
481
- const compared = compareSortValues(
603
+ const compared = quoteGroup(columnId, left) - quoteGroup(columnId, right) || compareSortValues(
482
604
  issuerSortValue(columnId, left),
483
605
  issuerSortValue(columnId, right),
484
606
  sort.direction,
@@ -552,7 +674,8 @@ const DAY_MS = 86_400_000;
552
674
  /** Three weeks without a level breaks the line instead of drawing one nobody traded. */
553
675
  const CHART_GAP_MS = 21 * DAY_MS;
554
676
 
555
- export function spreadChartPoints(points: readonly CloudCdsHistoryPointPayload[]): TimeSeriesPoint[] {
677
+ /** The line's daily levels in the unit it is quoted in, dated at UTC midnight, with a break across a long gap. */
678
+ export function spreadChartPoints(points: readonly CdsQuotedPoint[]): TimeSeriesPoint[] {
556
679
  const out: TimeSeriesPoint[] = [];
557
680
  let previous: number | null = null;
558
681
  for (const point of points) {
@@ -563,76 +686,129 @@ export function spreadChartPoints(points: readonly CloudCdsHistoryPointPayload[]
563
686
  out.push({ date: gap, observedAt: gap, value: null });
564
687
  }
565
688
  const date = new Date(time);
566
- out.push({ date, observedAt: date, value: point.spreadBp });
689
+ out.push({ date, observedAt: date, value: point.value });
567
690
  previous = time;
568
691
  }
569
692
  return out;
570
693
  }
571
694
 
572
- /** The 1M move as the pane shows it: whole basis points, signed. */
573
- export function formatSpreadChange(value: number): string {
574
- const rounded = Math.round(value);
575
- return `${rounded > 0 ? "+" : ""}${rounded}bp`;
695
+ /** A 1W or 1M move as the index board shows one: `+36.7bp`, `--` without one. */
696
+ export function formatSpreadMove(value: number | null): string {
697
+ return formatMove("spread", value);
698
+ }
699
+
700
+ /** An issuer's 5Y line as the server sends it: the daily levels, the latest one's moves and how it is quoted. */
701
+ export interface CdsSpreadLine {
702
+ points: readonly CloudCdsHistoryPointPayload[];
703
+ /** bp, on one contract and chained through the contract before across a roll; null unless the level is current. */
704
+ change1W: number | null;
705
+ change1M: number | null;
706
+ quote: CdsQuote;
707
+ /** Quoted upfront: the running coupon, the latest level in points and its moves in points. */
708
+ couponBp: number | null;
709
+ upfrontPts: number | null;
710
+ change1WPts: number | null;
711
+ change1MPts: number | null;
712
+ }
713
+
714
+ export interface CdsQuotedPoint {
715
+ date: string;
716
+ value: number;
576
717
  }
577
718
 
578
- function dayTime(date: string): number {
579
- return Date.parse(`${date}T00:00:00Z`);
719
+ /** Each day's level as the line is quoted: bp, or points upfront, leaving out a day the server could not convert. */
720
+ export function quotedPoints(line: CdsSpreadLine): CdsQuotedPoint[] {
721
+ return line.quote === "upfront"
722
+ ? line.points.flatMap((point) => (
723
+ typeof point.upfrontPts === "number" && Number.isFinite(point.upfrontPts) ? [{ date: point.date, value: point.upfrontPts }] : []
724
+ ))
725
+ : line.points.map((point) => ({ date: point.date, value: point.spreadBp }));
580
726
  }
581
727
 
582
728
  /** The figures of an issuer's 5Y line, the ones the pane heads its chart with and a report carries. */
583
729
  export interface CdsSpreadSummary {
584
- /** The latest level, bp, and the New York trade date it is from. */
585
- spreadBp: number;
730
+ unit: CdsQuoteUnit;
731
+ /** The latest level in that unit, and the New York trade date it is from. */
732
+ level: number;
586
733
  date: string;
587
- /** The move over a month on the same contract; null across a roll or a gap. */
588
- change1mBp: number | null;
589
- /** Lowest and highest level since the first date charted; null with a single level. */
590
- range: { lowBp: number; highBp: number; since: string } | null;
734
+ /** The same level in bp. */
735
+ spreadBp: number;
736
+ /** The running coupon of a name quoted upfront, bp. */
737
+ couponBp: number | null;
738
+ /** Its moves over a week and a month in that unit, through the roll; null unless the level is current. */
739
+ change1w: number | null;
740
+ change1m: number | null;
741
+ /** Lowest and highest level in that unit since the first date charted; null with a single level. */
742
+ range: { low: number; high: number; since: string } | null;
591
743
  }
592
744
 
593
745
  /**
594
- * The latest level, its move over a month, and the range of what the chart
595
- * shows. The month compares against the last level 30 to 45 days older on the
596
- * same contract, so neither a gap nor a roll to the next contract, which
597
- * trades wider, passes for a move.
746
+ * The latest level, its 1W and 1M moves, and the range of what the chart
747
+ * shows. The moves are the server's, by the index board's rule: on one
748
+ * contract, and across the March and September rolls chained through the
749
+ * contract before, which keeps trading off the run, so the roll to a contract
750
+ * that trades wider is not a move. They are left out once the level is more
751
+ * than 5 trading days behind the tape. Past 2,000bp all of it is in points
752
+ * upfront.
598
753
  */
599
- export function spreadSummary(points: readonly CloudCdsHistoryPointPayload[]): CdsSpreadSummary | null {
600
- const latest = points.at(-1);
754
+ export function spreadSummary(line: CdsSpreadLine): CdsSpreadSummary | null {
755
+ const latest = line.points.at(-1);
601
756
  if (!latest) return null;
602
- const latestTime = dayTime(latest.date);
603
- const monthAgo = points.findLast((point) => {
604
- if (point.maturity !== latest.maturity) return false;
605
- const age = latestTime - dayTime(point.date);
606
- return age >= 30 * DAY_MS && age <= 45 * DAY_MS;
607
- });
608
- const levels = points.map((point) => point.spreadBp);
757
+ const upfront = line.quote === "upfront" && line.upfrontPts != null;
758
+ const quoted = upfront ? quotedPoints(line) : line.points.map((point) => ({ date: point.date, value: point.spreadBp }));
759
+ const values = quoted.map((point) => point.value);
609
760
  return {
610
- spreadBp: latest.spreadBp,
761
+ unit: upfront ? "pts" : "bp",
762
+ level: upfront ? line.upfrontPts! : latest.spreadBp,
611
763
  date: latest.date,
612
- // A tenth of a basis point is the line's own precision; the rest is float noise.
613
- change1mBp: monthAgo ? Math.round((latest.spreadBp - monthAgo.spreadBp) * 10) / 10 : null,
614
- range: points.length >= 2
615
- ? { lowBp: Math.min(...levels), highBp: Math.max(...levels), since: points[0]!.date }
764
+ spreadBp: latest.spreadBp,
765
+ couponBp: upfront ? line.couponBp : null,
766
+ change1w: upfront ? line.change1WPts : line.change1W,
767
+ change1m: upfront ? line.change1MPts : line.change1M,
768
+ range: quoted.length >= 2
769
+ ? { low: Math.min(...values), high: Math.max(...values), since: quoted[0]!.date }
616
770
  : null,
617
771
  };
618
772
  }
619
773
 
620
- /** `129 to 276bp`: the low keeps the level's precision, so the level never falls outside it. */
621
- export function formatSpreadRange(range: NonNullable<CdsSpreadSummary["range"]>): string {
622
- return `${formatBp(range.lowBp).slice(0, -2)} to ${formatBp(range.highBp)}`;
774
+ export type CdsNoLevelReason = "upfront-side-unknown";
775
+
776
+ /**
777
+ * Why the view has no current 5Y level, in one line, when the server knows:
778
+ * after the last level there is, or at all.
779
+ */
780
+ export function noLevelMessage(reason: CdsNoLevelReason | null, lastLevel: string | null): string | null {
781
+ if (reason !== "upfront-side-unknown") return null;
782
+ return `5Y level not derivable${lastLevel ? ` after ${lastLevel}` : ""}: DTCC prints carry upfront without payer side`;
783
+ }
784
+
785
+ /** `129 to 276bp`, or `20.1 to 60.3 pts`: the low keeps the level's precision, so the level never falls outside it. */
786
+ export function formatSpreadRange(unit: CdsQuoteUnit, range: NonNullable<CdsSpreadSummary["range"]>): string {
787
+ return unit === "pts"
788
+ ? `${range.low.toFixed(1)} to ${formatPoints(range.high)}`
789
+ : `${formatBp(range.low).slice(0, -2)} to ${formatBp(range.high)}`;
623
790
  }
624
791
 
625
792
  /** The pane's figures over its 5Y chart, from `spreadSummary`. */
626
- export function spreadFigures(points: readonly CloudCdsHistoryPointPayload[]): StatItem[] {
627
- const summary = spreadSummary(points);
793
+ export function spreadFigures(line: CdsSpreadLine): StatItem[] {
794
+ const summary = spreadSummary(line);
628
795
  if (!summary) return [];
796
+ const { unit } = summary;
629
797
  return [
630
- { id: "spread", label: "5Y spread", value: formatBp(summary.spreadBp), detail: summary.date },
631
- ...(summary.change1mBp != null ? [{ id: "change", label: "1M", value: formatSpreadChange(summary.change1mBp) }] : []),
798
+ unit === "pts"
799
+ ? {
800
+ id: "spread",
801
+ label: "5Y upfront",
802
+ value: formatPoints(summary.level),
803
+ detail: summary.couponBp == null ? summary.date : `${summary.date} · ${formatBp(summary.couponBp)} coupon`,
804
+ }
805
+ : { id: "spread", label: "5Y spread", value: formatBp(summary.level), detail: summary.date },
806
+ ...(summary.change1w != null ? [{ id: "1w", label: "1W", value: formatQuotedMove(unit, summary.change1w) }] : []),
807
+ ...(summary.change1m != null ? [{ id: "1m", label: "1M", value: formatQuotedMove(unit, summary.change1m) }] : []),
632
808
  ...(summary.range ? [{
633
809
  id: "range",
634
810
  label: "Range",
635
- value: formatSpreadRange(summary.range),
811
+ value: formatSpreadRange(unit, summary.range),
636
812
  detail: `since ${summary.range.since}`,
637
813
  }] : []),
638
814
  ];
@@ -3,7 +3,7 @@ import {
3
3
  ChartTableHeader,
4
4
  DataTableStackView,
5
5
  DataTableView,
6
- EmptyState, formatBpAxis, PaneStatusBody, staticSeries,
6
+ EmptyState, formatBpAxis, PaneStatusBody, spanAxisFormatter, staticSeries,
7
7
  useChartTableSelection,
8
8
  usePaneMenuItems,
9
9
  usePaneNoticeFooter,
@@ -13,7 +13,9 @@ import {
13
13
  type StatItem
14
14
  } from "../../../components";
15
15
  import type { CloudCdsHistoryPointPayload } from "../../../api-client";
16
+ import { signedMoveColor } from "../../../components/market-board";
16
17
  import { useAsyncResource } from "../../../react/async-resource";
18
+ import { usePaneSettingValue } from "../../../public/react";
17
19
  import { colors } from "../../../theme/colors";
18
20
  import type { PaneProps } from "../../../types/plugin";
19
21
  import { TextAttributes } from "../../../ui";
@@ -30,6 +32,7 @@ import {
30
32
  loadCdsSpreadHistory,
31
33
  loadCdsSpreadLevels,
32
34
  type CdsActivityLoader,
35
+ type CdsSpreadHistory,
33
36
  type CdsSpreadHistoryLoader,
34
37
  type CdsSpreadLevelsLoader,
35
38
  } from "./client";
@@ -45,18 +48,25 @@ import {
45
48
  formatEventTime,
46
49
  formatMaturity,
47
50
  formatNotional,
51
+ formatQuoted,
52
+ formatQuotedMove,
48
53
  formatUpfront,
54
+ issuerListSort,
49
55
  lastTradeOf,
56
+ noLevelMessage,
50
57
  noTradesMessage,
51
58
  resolveIssuerQuery,
52
59
  sortIssuers,
53
60
  sortTrades,
61
+ quotedLevel,
62
+ quotedPoints,
54
63
  spreadChartPoints,
55
64
  spreadFigures,
56
65
  summarizeIssuers,
57
66
  tradesForIssuer,
58
67
  withSpreadLevels,
59
68
  type CdsIssuerSummary,
69
+ type CdsQuoteUnit,
60
70
  type CdsTrade,
61
71
  type IssuerColumn,
62
72
  type IssuerColumnId,
@@ -82,14 +92,26 @@ function renderIssuerCell(
82
92
  return { text: String(row.trades), color: colors.text };
83
93
  case "last":
84
94
  return { text: formatEventTime(row.lastTradeAt), color: colors.textMuted };
85
- case "spread":
86
- return {
87
- text: formatBp(row.spread5yBp),
88
- color: row.spread5yBp == null ? colors.textDim : colors.text,
89
- };
95
+ case "spread": {
96
+ const { unit, level } = quotedLevel(row);
97
+ return { text: formatQuoted(unit, level), color: level == null ? colors.textDim : colors.text };
98
+ }
99
+ case "1w":
100
+ return moveCell(quotedLevel(row).unit, quotedLevel(row).change1w);
101
+ case "1m":
102
+ return moveCell(quotedLevel(row).unit, quotedLevel(row).change1m);
90
103
  }
91
104
  }
92
105
 
106
+ /**
107
+ * A 1W or 1M move as the index board draws one: wider (more points upfront)
108
+ * is adverse, and a move that prints as 0.0 is not coloured.
109
+ */
110
+ function moveCell(unit: CdsQuoteUnit, value: number | null): DataTableCell {
111
+ const shown = value == null ? null : Number(value.toFixed(1));
112
+ return { text: formatQuotedMove(unit, value), color: signedMoveColor(shown, "up", colors) };
113
+ }
114
+
93
115
  // Table-shaped adapters live at module level so memoized rows keep their
94
116
  // identity between pane renders.
95
117
  const issuerKey = (row: CdsIssuerSummary) => row.key;
@@ -183,9 +205,24 @@ function CdsTradeTable({
183
205
  );
184
206
  }
185
207
 
208
+ /** Points upfront on the chart's axis: `58pts`, `57.6pts`. */
209
+ const formatPointsAxis = spanAxisFormatter((value, digits) => `${value.toFixed(digits)}pts`);
210
+
186
211
  const NO_TRADES: CdsTrade[] = [];
187
212
  const NO_ISSUERS: CdsIssuerSummary[] = [];
188
213
  const NO_POINTS: CloudCdsHistoryPointPayload[] = [];
214
+ const NO_LINE: CdsSpreadHistory = {
215
+ issuer: null,
216
+ points: NO_POINTS,
217
+ change1W: null,
218
+ change1M: null,
219
+ quote: "spread",
220
+ couponBp: null,
221
+ upfrontPts: null,
222
+ change1WPts: null,
223
+ change1MPts: null,
224
+ noLevelReason: null,
225
+ };
189
226
  /**
190
227
  * The 5Y line has one point per New York trade date, dated at UTC midnight, so
191
228
  * a trade's cursor is its New York day, not its time: an afternoon print would
@@ -196,12 +233,13 @@ const tradeDate = (trade: CdsTrade) =>
196
233
 
197
234
  /**
198
235
  * The issuer's figures, then its 5Y line over the trades, sized by the chart
199
- * table layout. The selected trade is the chart's cursor.
236
+ * table layout. The selected trade is the chart's cursor. A name without a
237
+ * level says why in the chart's band, when the server can say.
200
238
  */
201
- function IssuerHeader({ issuer, points, trades, width, height, focused, loading, selectedId, onSelect }: {
239
+ function IssuerHeader({ issuer, line, trades, width, height, focused, loading, selectedId, onSelect }: {
202
240
  /** Left out in the stack detail, whose title already names the issuer. */
203
241
  issuer?: string;
204
- points: readonly CloudCdsHistoryPointPayload[];
242
+ line: CdsSpreadHistory;
205
243
  trades: readonly CdsTrade[];
206
244
  width: number;
207
245
  height: number;
@@ -210,20 +248,27 @@ function IssuerHeader({ issuer, points, trades, width, height, focused, loading,
210
248
  selectedId: string | null;
211
249
  onSelect: (id: string) => void;
212
250
  }) {
213
- // The level, then whose spread it is: in a short pane the figures at the end
214
- // give way. While the history loads the level holds its place, so the trades
215
- // do not move when it lands.
216
- const [level, ...rest] = loading && !points.length
251
+ // The level and its moves, as the index board heads its detail, then whose
252
+ // spread it is and the range: in a short pane the figures at the end give
253
+ // way. While the history loads the level holds its place, so the trades do
254
+ // not move when it lands.
255
+ const { points } = line;
256
+ // A name quoted upfront charts in points, as its figures read.
257
+ const unit: CdsQuoteUnit = line.quote === "upfront" && line.upfrontPts != null ? "pts" : "bp";
258
+ const charted = useMemo(() => unit === "pts" ? quotedPoints(line) : points.map((point) => ({ date: point.date, value: point.spreadBp })), [line, points, unit]);
259
+ const shown = loading && !points.length
217
260
  ? [{ id: "spread", label: "5Y spread", value: "--" }]
218
- : spreadFigures(points);
261
+ : spreadFigures(line);
262
+ const why = !points.length ? noLevelMessage(line.noLevelReason, null) : null;
263
+ const moves = shown.filter((item) => item.id === "spread" || item.id === "1w" || item.id === "1m");
219
264
  const figures: StatItem[] = [
220
- ...(level ? [level] : []),
265
+ ...moves,
221
266
  ...(issuer ? [{ id: "issuer", label: "Issuer", value: issuer }] : []),
222
- ...rest,
267
+ ...shown.filter((item) => !moves.includes(item)),
223
268
  ];
224
- const series = useMemo(() => [staticSeries(spreadChartPoints(points), {
225
- id: "cds-5y", label: "5Y spread", color: colors.positive, calendarSpaced: true,
226
- })], [points]);
269
+ const series = useMemo(() => [staticSeries(spreadChartPoints(charted), {
270
+ id: "cds-5y", label: unit === "pts" ? "5Y upfront" : "5Y spread", color: colors.positive, calendarSpaced: true,
271
+ })], [charted, unit]);
227
272
  const link = useChartTableSelection({
228
273
  rows: trades, getId: tradeKey, getDate: tradeDate,
229
274
  selectedId: selectedId && trades.some((trade) => trade.id === selectedId) ? selectedId : trades[0]?.id ?? null,
@@ -232,8 +277,12 @@ function IssuerHeader({ issuer, points, trades, width, height, focused, loading,
232
277
  return (
233
278
  <ChartTableHeader width={width} height={height} tableRows={trades.length} figures={figures}
234
279
  tableColumns={buildTradeColumns(width)}
235
- chart={points.length >= 2 || loading ? {
236
- series, formatValue: formatBp, formatAxisValue: formatBpAxis, remoteKind: "cds-spread-history", loading, ...link,
280
+ chart={points.length >= 2 || loading || why ? {
281
+ series,
282
+ formatValue: (value: number) => formatQuoted(unit, value),
283
+ formatAxisValue: unit === "pts" ? formatPointsAxis : formatBpAxis,
284
+ remoteKind: "cds-spread-history", loading, ...link,
285
+ ...(why ? { empty: why } : {}),
237
286
  } : null} />
238
287
  );
239
288
  }
@@ -268,7 +317,10 @@ export function CdsPane({
268
317
  const { symbol, ticker } = usePaneTickerIdentity();
269
318
  const issuerQuery = useMemo(() => resolveIssuerQuery(symbol, ticker), [symbol, ticker]);
270
319
 
271
- const [issuerSort, setIssuerSort] = useState<IssuerSortPreference>(DEFAULT_ISSUER_SORT);
320
+ // `CDS --sort 1m` (and its shot) opens the list on that order; the headers re-sort it from there, and a reload keeps theirs.
321
+ const [openingSort] = usePaneSettingValue<string>("sort", "trades");
322
+ const openingIssuerSort = useMemo(() => issuerListSort(openingSort), [openingSort]);
323
+ const [issuerSort, setIssuerSort] = usePluginPaneState<IssuerSortPreference>("issuerSort", openingIssuerSort);
272
324
  const [tradeSort, setTradeSort] = useState<TradeSortPreference>(DEFAULT_TRADE_SORT);
273
325
  // Selection and the open issuer live in pane state so a reload or a shared
274
326
  // layout comes back to the same row.
@@ -311,16 +363,20 @@ export function CdsPane({
311
363
  const historyRequest = useCallback(() => loadHistoryRef.current(historyIssuer!), [historyIssuer]);
312
364
  const history = useAsyncResource(historyIssuer ? historyRequest : null);
313
365
  useAutoRefresh(history.updatedAt, history.load);
314
- const spreadPoints = history.data?.points ?? NO_POINTS;
366
+ const spreadLine = history.data ?? NO_LINE;
367
+ const spreadPoints = spreadLine.points;
315
368
  // The band holds its rows while the first history loads, so the trades do not jump.
316
369
  const historyLoading = !!historyIssuer && history.loading && !history.data;
317
370
  const lineMaturity = spreadPoints.at(-1)?.maturity ?? null;
371
+ // A level older than the prints after it says why those prints set none; with no level at all the chart band says it.
372
+ const staleLevel = spreadPoints.length ? noLevelMessage(spreadLine.noLevelReason, spreadPoints.at(-1)!.date) : null;
318
373
  // Without it a failed request reads as a name with no 5Y line.
319
374
  usePaneNoticeFooter({
320
375
  registrationId: `${paneId}:cds-history`,
321
376
  focused,
322
377
  notices: [
323
378
  ...(historyIssuer && history.error && !history.data ? ["5Y spread history unavailable."] : []),
379
+ ...(historyIssuer && staleLevel ? [`${staleLevel}.`] : []),
324
380
  ...(summaries.length && levels.error && !levels.data ? ["5Y spreads unavailable."] : []),
325
381
  ],
326
382
  });
@@ -412,7 +468,7 @@ export function CdsPane({
412
468
  // issuer name the backend was actually queried for, which is the expanded
413
469
  // company name once instrument search has resolved a bare symbol.
414
470
  const header = (
415
- <IssuerHeader issuer={activity.issuer ?? issuerQuery} points={spreadPoints} trades={visibleTrades}
471
+ <IssuerHeader issuer={activity.issuer ?? issuerQuery} line={spreadLine} trades={visibleTrades}
416
472
  width={width} height={height} focused={focused} loading={historyLoading}
417
473
  selectedId={selectedTradeId} onSelect={setSelectedTradeId} />
418
474
  );
@@ -446,8 +502,8 @@ export function CdsPane({
446
502
  trades={visibleTrades}
447
503
  focused={focused && detailOpen}
448
504
  width={width}
449
- before={spreadPoints.length || historyLoading ? (
450
- <IssuerHeader points={spreadPoints} trades={visibleTrades} width={width}
505
+ before={spreadPoints.length || historyLoading || spreadLine.noLevelReason ? (
506
+ <IssuerHeader line={spreadLine} trades={visibleTrades} width={width}
451
507
  height={Math.max(0, height - 1)} focused={focused && detailOpen} loading={historyLoading}
452
508
  selectedId={selectedTradeId} onSelect={setSelectedTradeId} />
453
509
  ) : undefined}
@@ -21,7 +21,7 @@ export const centralBankRatesHeadless: HeadlessPaneDefinition<"bundle"> = {
21
21
  limitations: ["Published policy observations with individual dates.", "Policy instruments differ.",
22
22
  "Next meetings come from each bank's published calendar; SAMA publishes none, and China's date is the monthly LPR fixing."] },
23
23
  shape: "bundle",
24
- options: [{ key: "history", type: "boolean", defaultValue: false, description: "Add each row's one-year daily history to the JSON metadata." }],
24
+ options: [{ key: "history", shot: { reportOnly: "adds each row's one-year history to the JSON report" }, type: "boolean", defaultValue: false, description: "Add each row's one-year daily history to the JSON metadata." }],
25
25
  argument: { kind: "none" }, describe: "Policy rates of the G20, SNB, Norges Bank, Riksbank and RBNZ",
26
26
  // Each row is dated apart (BIS reports weekly, some banks weeks late), so exports cite the oldest as well.
27
27
  freshness: { source: "BIS and FRED", publisher: "each row's central_bank, via BIS and FRED", status: "not-a-feed",