gloomberb 0.17.6 → 0.18.0

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 (768) 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/normalizers.ts +1 -0
  23. package/src/api-client/paths.ts +20 -1
  24. package/src/api-client/request.ts +11 -3
  25. package/src/api-client/research-activity.ts +15 -8
  26. package/src/api-client/socket.ts +6 -3
  27. package/src/api-client/supply-chain-graph.ts +2 -2
  28. package/src/api-client/supply-chain.ts +8 -0
  29. package/src/api-client/tape.ts +12 -0
  30. package/src/api-client/types.ts +66 -2
  31. package/src/api-client/upgrade-experiment.ts +4 -3
  32. package/src/api-client/wall-experiments.ts +5 -3
  33. package/src/api-client/wall-summary.ts +3 -1
  34. package/src/api-client/web-experiments.ts +5 -2
  35. package/src/api-client/yield-curves.ts +17 -0
  36. package/src/app/command-bar-intro.ts +38 -0
  37. package/src/app/keybindings/actions.ts +1 -1
  38. package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
  39. package/src/app/pane-runtime/plugin-bindings.ts +4 -0
  40. package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
  41. package/src/app/pane-runtime/ticker-open-target.ts +31 -0
  42. package/src/app/runtime/desktop-deeplink.ts +3 -4
  43. package/src/app/runtime/plugin-bindings.ts +3 -2
  44. package/src/app/runtime/startup.ts +3 -4
  45. package/src/app/runtime/ticker-refresh.ts +13 -12
  46. package/src/app/runtime/update.ts +3 -2
  47. package/src/architecture/core-builtin-allowlist.json +0 -3
  48. package/src/architecture/silent-catch-allowlist.json +3 -0
  49. package/src/architecture/ui-literals-allowlist.json +186 -0
  50. package/src/architecture/ui-tokens-allowlist.json +40 -0
  51. package/src/ask-gloom/pane-context.ts +3 -1
  52. package/src/brokers/signed-in/catalog.ts +2 -1
  53. package/src/brokers/signed-in/client.ts +7 -2
  54. package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
  55. package/src/brokers/signed-in/sign-in.ts +22 -20
  56. package/src/brokers/sync-broker-instance.ts +2 -1
  57. package/src/capabilities/chart-series.ts +2 -0
  58. package/src/capabilities/registry.ts +1 -3
  59. package/src/cli/bank-section.ts +147 -0
  60. package/src/cli/base-converter.ts +5 -2
  61. package/src/cli/board-coins.ts +70 -0
  62. package/src/cli/commands/fred-series.ts +90 -0
  63. package/src/cli/commands/market.ts +340 -69
  64. package/src/cli/commands/news-search.ts +35 -2
  65. package/src/cli/commands/options-chain.ts +7 -5
  66. package/src/cli/commands/options-leaps.ts +3 -3
  67. package/src/cli/commands/overview.ts +78 -29
  68. package/src/cli/commands/plugins.ts +1 -0
  69. package/src/cli/commands/search.ts +87 -24
  70. package/src/cli/commands/system.ts +5 -2
  71. package/src/cli/commands/ticker.ts +337 -60
  72. package/src/cli/context.ts +2 -1
  73. package/src/cli/desktop-pane-shot.ts +11 -3
  74. package/src/cli/earnings-calendar.ts +2 -1
  75. package/src/cli/errors.ts +10 -0
  76. package/src/cli/export-source.ts +18 -3
  77. package/src/cli/glossary.ts +196 -14
  78. package/src/cli/history-rows.ts +60 -9
  79. package/src/cli/index-roots.ts +26 -0
  80. package/src/cli/index.ts +34 -9
  81. package/src/cli/known-gaps.ts +156 -22
  82. package/src/cli/listing-arg.ts +156 -12
  83. package/src/cli/listing-suggestion.ts +4 -2
  84. package/src/cli/name-entries.ts +76 -0
  85. package/src/cli/not-a-ticker.ts +15 -6
  86. package/src/cli/pane-functions/access-gate.ts +22 -0
  87. package/src/cli/pane-functions/capabilities.ts +62 -4
  88. package/src/cli/pane-functions/catalog.ts +94 -39
  89. package/src/cli/pane-functions/data.ts +6 -5
  90. package/src/cli/pane-functions/discovery.ts +1 -1
  91. package/src/cli/pane-functions/dom.ts +3 -3
  92. package/src/cli/pane-functions/freshness.ts +49 -8
  93. package/src/cli/pane-functions/function-help.ts +13 -10
  94. package/src/cli/pane-functions/headless.ts +177 -42
  95. package/src/cli/pane-functions/index.ts +64 -8
  96. package/src/cli/pane-functions/options.ts +17 -3
  97. package/src/cli/pane-functions/report-notices.ts +17 -3
  98. package/src/cli/pane-functions/resolver.ts +48 -13
  99. package/src/cli/pane-functions/screenshot.ts +124 -23
  100. package/src/cli/pane-functions/shot-options.ts +68 -0
  101. package/src/cli/perpetual-contract.ts +3 -1
  102. package/src/cli/report-tables.ts +10 -2
  103. package/src/cli/staged-tickers.ts +5 -0
  104. package/src/cli/statement-filings.ts +261 -0
  105. package/src/cli/symbol-args.ts +47 -8
  106. package/src/cli/symbol-list.ts +9 -2
  107. package/src/cli/symbol-rows.ts +269 -29
  108. package/src/cli/ticker-resolution.ts +148 -34
  109. package/src/cli/treasury-yields.ts +86 -0
  110. package/src/cli/types.ts +3 -0
  111. package/src/cli/uncovered-instrument.ts +20 -0
  112. package/src/components/chart/composite/axis-overlays.tsx +16 -9
  113. package/src/components/chart/composite/composite-chart.tsx +85 -6
  114. package/src/components/chart/composite/downsample.ts +19 -3
  115. package/src/components/chart/composite/format.ts +3 -0
  116. package/src/components/chart/composite/legend.tsx +155 -76
  117. package/src/components/chart/composite/panel-bitmap.ts +8 -2
  118. package/src/components/chart/composite/panel-surface.tsx +3 -3
  119. package/src/components/chart/composite/toolbar.tsx +12 -7
  120. package/src/components/chart/composite/types.ts +6 -0
  121. package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
  122. package/src/components/chart/curve/curve-surface.tsx +1 -1
  123. package/src/components/chart/static/series.ts +39 -0
  124. package/src/components/chart/static/trail-chart-surface.tsx +2 -1
  125. package/src/components/command-bar/commands/collection-list.ts +45 -15
  126. package/src/components/command-bar/commands/collection.ts +10 -3
  127. package/src/components/command-bar/commands/registry.ts +2 -2
  128. package/src/components/command-bar/list/badge.ts +4 -3
  129. package/src/components/command-bar/list/model.ts +5 -0
  130. package/src/components/command-bar/list/view.tsx +1 -1
  131. package/src/components/command-bar/panel/index.tsx +19 -8
  132. package/src/components/command-bar/panel/native-surface.ts +6 -4
  133. package/src/components/command-bar/panel/prompt-example.ts +22 -0
  134. package/src/components/command-bar/routes/root/provider-search.ts +3 -9
  135. package/src/components/command-bar/routes/root/results.ts +13 -0
  136. package/src/components/command-bar/routes/root/start-here.ts +90 -0
  137. package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
  138. package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
  139. package/src/components/command-bar/theme-picker.tsx +3 -1
  140. package/src/components/command-bar/workflow/builtin.ts +5 -1
  141. package/src/components/command-bar/workflow/collection-actions.ts +21 -12
  142. package/src/components/command-bar/workflow/ops.ts +21 -1
  143. package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
  144. package/src/components/command-bar/workflow/tickers.ts +6 -4
  145. package/src/components/feedback-dialog.tsx +1 -1
  146. package/src/components/form-modal/broker-step.tsx +7 -63
  147. package/src/components/form-modal/content.tsx +7 -2
  148. package/src/components/form-modal/field-row.tsx +6 -8
  149. package/src/components/form-modal/host.tsx +3 -3
  150. package/src/components/form-modal/model.ts +3 -0
  151. package/src/components/form-modal/routes.ts +17 -2
  152. package/src/components/index.ts +6 -6
  153. package/src/components/input-search-bar.tsx +43 -6
  154. package/src/components/layout/detached-pane-shell.tsx +0 -1
  155. package/src/components/layout/floating-pane.tsx +0 -1
  156. package/src/components/layout/header.tsx +8 -7
  157. package/src/components/layout/pane/footer/index.tsx +7 -4
  158. package/src/components/layout/pane/footer/model.ts +28 -2
  159. package/src/components/layout/pane/header.tsx +9 -19
  160. package/src/components/layout/pane/index.tsx +0 -1
  161. package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
  162. package/src/components/layout/pane/pane-tabs.tsx +4 -3
  163. package/src/components/layout/pane/sizing.ts +9 -0
  164. package/src/components/layout/pane/ticker-fate-gate.tsx +8 -2
  165. package/src/components/layout/shell/pane/capture.ts +44 -20
  166. package/src/components/layout/status-bar.tsx +3 -6
  167. package/src/components/markdown-text.tsx +17 -2
  168. package/src/components/market-board/index.tsx +19 -8
  169. package/src/components/metric-treemap/heat-surface.tsx +2 -7
  170. package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
  171. package/src/components/onboarding/onboarding-frame.tsx +24 -21
  172. package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
  173. package/src/components/onboarding/wizard-positions.ts +40 -11
  174. package/src/components/pane-settings-dialog/desktop.tsx +12 -50
  175. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
  176. package/src/components/price-performance.tsx +18 -2
  177. package/src/components/reader/article-reader.tsx +11 -10
  178. package/src/components/reader/detail-reader.tsx +9 -5
  179. package/src/components/reader/reader-text.tsx +51 -24
  180. package/src/components/sign-in-code-panel.tsx +129 -75
  181. package/src/components/ticker/badge/index.tsx +2 -1
  182. package/src/components/ui/action-row.tsx +5 -2
  183. package/src/components/ui/audio-player.tsx +70 -0
  184. package/src/components/ui/card.tsx +75 -0
  185. package/src/components/ui/data-table/index.tsx +4 -2
  186. package/src/components/ui/data-table/types.ts +11 -0
  187. package/src/components/ui/detail-scroll-body.tsx +1 -1
  188. package/src/components/ui/dialog-actions.tsx +1 -21
  189. package/src/components/ui/display.tsx +13 -5
  190. package/src/components/ui/external-link.tsx +4 -2
  191. package/src/components/ui/fields.tsx +12 -0
  192. package/src/components/ui/figure.tsx +5 -3
  193. package/src/components/ui/frame.tsx +40 -6
  194. package/src/components/ui/icon.tsx +4 -0
  195. package/src/components/ui/index.ts +4 -1
  196. package/src/components/ui/list-view.tsx +8 -0
  197. package/src/components/ui/prose.tsx +97 -25
  198. package/src/components/ui/query-bar-keys.tsx +3 -1
  199. package/src/components/ui/query-bar.tsx +6 -0
  200. package/src/components/ui/quote.ts +42 -0
  201. package/src/components/ui/range-track.tsx +15 -2
  202. package/src/components/ui/reveal-in-scroll-box.ts +21 -3
  203. package/src/components/ui/select-button.tsx +38 -3
  204. package/src/components/ui/status.tsx +73 -4
  205. package/src/components/ui/table-layout.ts +20 -0
  206. package/src/components/use-pinned-moment.ts +19 -0
  207. package/src/core/app-runtime.ts +2 -2
  208. package/src/core/state/app/instrument.ts +18 -1
  209. package/src/core/state/app/layout.ts +6 -0
  210. package/src/core/state/app/state.ts +14 -2
  211. package/src/data/cached-query.ts +1 -1
  212. package/src/data/config/chart-settings.ts +3 -1
  213. package/src/data/config/home.ts +4 -1
  214. package/src/data/config/store/node.ts +9 -4
  215. package/src/data/config/store/normalize.ts +9 -0
  216. package/src/data/json-storage.ts +6 -3
  217. package/src/data/json-ticker-repository.ts +3 -1
  218. package/src/data/plugin-cache.ts +5 -1
  219. package/src/data/sqlite/json.ts +3 -1
  220. package/src/data/ticker-repository.ts +5 -2
  221. package/src/feedback/diagnostics.ts +2 -6
  222. package/src/i18n/es.ts +86 -6
  223. package/src/i18n/index.ts +3 -9
  224. package/src/i18n/ja.ts +86 -6
  225. package/src/i18n/ko.ts +86 -6
  226. package/src/i18n/zh-cn.ts +86 -6
  227. package/src/i18n/zh-tw.ts +86 -6
  228. package/src/layout-marketplace/gallery-desktop.tsx +8 -4
  229. package/src/market-data/bars-per-year.ts +43 -0
  230. package/src/market-data/bond-funds.ts +85 -0
  231. package/src/market-data/coordinator/auxiliary.ts +5 -2
  232. package/src/market-data/coordinator/index.ts +6 -5
  233. package/src/market-data/futures-contract.ts +102 -5
  234. package/src/market-data/hooks.tsx +20 -11
  235. package/src/market-data/market/bar-period.ts +36 -0
  236. package/src/market-data/market/format.ts +5 -13
  237. package/src/market-data/market/freshness.ts +1 -3
  238. package/src/market-data/market/index-level.ts +51 -0
  239. package/src/market-data/model-dividend-yield.ts +57 -16
  240. package/src/market-data/quotes/live-valuation.ts +48 -2
  241. package/src/market-data/realized-volatility.ts +16 -7
  242. package/src/market-data/tax-equivalent.ts +344 -0
  243. package/src/news/aggregator.ts +4 -2
  244. package/src/notifications/notification-log.ts +5 -3
  245. package/src/plugins/auto-update-node.ts +1 -0
  246. package/src/plugins/builtin/account-management/footer.ts +1 -1
  247. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  248. package/src/plugins/builtin/account-management/model.ts +1 -0
  249. package/src/plugins/builtin/account-management/pane.tsx +71 -19
  250. package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
  251. package/src/plugins/builtin/alerts/cli.ts +7 -18
  252. package/src/plugins/builtin/alerts/constants.ts +8 -0
  253. package/src/plugins/builtin/alerts/event-rows.ts +16 -0
  254. package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
  255. package/src/plugins/builtin/alerts/headless.ts +182 -0
  256. package/src/plugins/builtin/alerts/index.tsx +3 -0
  257. package/src/plugins/builtin/alerts/pane.tsx +1 -7
  258. package/src/plugins/builtin/alerts/storage.ts +17 -1
  259. package/src/plugins/builtin/analytics/index.tsx +6 -1
  260. package/src/plugins/builtin/analytics/metrics.ts +47 -9
  261. package/src/plugins/builtin/analytics/risk-headless.ts +14 -2
  262. package/src/plugins/builtin/analytics/risk-math.ts +83 -0
  263. package/src/plugins/builtin/analytics/risk-model.ts +97 -4
  264. package/src/plugins/builtin/analytics/risk-pane.tsx +11 -6
  265. package/src/plugins/builtin/analytics/sector-model.ts +14 -3
  266. package/src/plugins/builtin/awards/headless.ts +6 -5
  267. package/src/plugins/builtin/awards/index.tsx +1 -1
  268. package/src/plugins/builtin/backtest/client.ts +38 -8
  269. package/src/plugins/builtin/backtest/engine.ts +25 -13
  270. package/src/plugins/builtin/backtest/export.ts +27 -0
  271. package/src/plugins/builtin/backtest/format.ts +19 -3
  272. package/src/plugins/builtin/backtest/headless.ts +42 -28
  273. package/src/plugins/builtin/backtest/index.tsx +3 -0
  274. package/src/plugins/builtin/backtest/pane.tsx +39 -10
  275. package/src/plugins/builtin/backtest/report.ts +160 -0
  276. package/src/plugins/builtin/backtest/rules.ts +2 -0
  277. package/src/plugins/builtin/backtest/window.ts +112 -0
  278. package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
  279. package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
  280. package/src/plugins/builtin/catalysts/headless.ts +24 -13
  281. package/src/plugins/builtin/catalysts/index.tsx +4 -2
  282. package/src/plugins/builtin/catalysts/model.ts +18 -1
  283. package/src/plugins/builtin/catalysts/pane.tsx +2 -2
  284. package/src/plugins/builtin/cds/client.ts +28 -5
  285. package/src/plugins/builtin/cds/headless.ts +183 -31
  286. package/src/plugins/builtin/cds/index.tsx +1 -1
  287. package/src/plugins/builtin/cds/model.ts +229 -53
  288. package/src/plugins/builtin/cds/pane.tsx +82 -26
  289. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
  290. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
  291. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
  292. package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
  293. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
  294. package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
  295. package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
  296. package/src/plugins/builtin/chart-composer/headless.ts +99 -21
  297. package/src/plugins/builtin/chart-composer/index.tsx +70 -13
  298. package/src/plugins/builtin/chart-composer/pane.tsx +65 -15
  299. package/src/plugins/builtin/chart-composer/presets.ts +79 -11
  300. package/src/plugins/builtin/chart-composer/series-catalog.ts +50 -14
  301. package/src/plugins/builtin/chart-composer/series-expression.ts +9 -7
  302. package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
  303. package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
  304. package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
  305. package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
  306. package/src/plugins/builtin/chat/content/composer.tsx +22 -1
  307. package/src/plugins/builtin/chat/content/index.tsx +35 -5
  308. package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
  309. package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
  310. package/src/plugins/builtin/chat/content/snapshot.ts +29 -6
  311. package/src/plugins/builtin/chat/ghost-user.ts +11 -3
  312. package/src/plugins/builtin/chat/layout.ts +2 -0
  313. package/src/plugins/builtin/chat/message/desktop.tsx +13 -5
  314. package/src/plugins/builtin/chat/message/header.tsx +26 -4
  315. package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
  316. package/src/plugins/builtin/chat/message/render-state.ts +28 -1
  317. package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
  318. package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
  319. package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
  320. package/src/plugins/builtin/chat/share/flow.tsx +9 -73
  321. package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
  322. package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
  323. package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
  324. package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
  325. package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
  326. package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
  327. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
  328. package/src/plugins/builtin/cloud/plugin.tsx +2 -0
  329. package/src/plugins/builtin/cloud/team/module.tsx +5 -1
  330. package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
  331. package/src/plugins/builtin/cloud/team/views.ts +11 -4
  332. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
  333. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
  334. package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
  335. package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
  336. package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
  337. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
  338. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
  339. package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
  340. package/src/plugins/builtin/commodities-energy/index.tsx +8 -5
  341. package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
  342. package/src/plugins/builtin/company-attention/headless.ts +15 -7
  343. package/src/plugins/builtin/company-attention/index.tsx +1 -1
  344. package/src/plugins/builtin/company-attention/model.ts +49 -4
  345. package/src/plugins/builtin/company-attention/pane.tsx +11 -9
  346. package/src/plugins/builtin/company-kpis/headless.ts +4 -3
  347. package/src/plugins/builtin/company-kpis/index.tsx +2 -2
  348. package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
  349. package/src/plugins/builtin/congress-trades/headless.ts +23 -2
  350. package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
  351. package/src/plugins/builtin/cot/headless.ts +5 -2
  352. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
  353. package/src/plugins/builtin/credit-boards/client.ts +9 -2
  354. package/src/plugins/builtin/credit-boards/headless.ts +93 -27
  355. package/src/plugins/builtin/credit-boards/index.tsx +15 -4
  356. package/src/plugins/builtin/credit-boards/model.ts +105 -6
  357. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
  358. package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
  359. package/src/plugins/builtin/credit-documents/index.tsx +3 -0
  360. package/src/plugins/builtin/credit-documents/model.ts +3 -10
  361. package/src/plugins/builtin/crypto-board/client.ts +152 -2
  362. package/src/plugins/builtin/crypto-board/headless.ts +138 -19
  363. package/src/plugins/builtin/crypto-board/index.tsx +5 -3
  364. package/src/plugins/builtin/crypto-board/model.ts +210 -12
  365. package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
  366. package/src/plugins/builtin/crypto-board/series.ts +52 -1
  367. package/src/plugins/builtin/crypto-board/supply.ts +123 -0
  368. package/src/plugins/builtin/debt-maturities/client.ts +54 -1
  369. package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
  370. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  371. package/src/plugins/builtin/debt-maturities/model.ts +58 -13
  372. package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
  373. package/src/plugins/builtin/dividend-yield/client.ts +42 -36
  374. package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
  375. package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
  376. package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
  377. package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
  378. package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
  379. package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
  380. package/src/plugins/builtin/dividend-yield/types.ts +6 -1
  381. package/src/plugins/builtin/dividend-yield/view.ts +1 -1
  382. package/src/plugins/builtin/docs/blocks.tsx +54 -8
  383. package/src/plugins/builtin/docs/pane.tsx +8 -13
  384. package/src/plugins/builtin/earnings/headless.ts +3 -2
  385. package/src/plugins/builtin/earnings-calls/data.ts +51 -0
  386. package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
  387. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  388. package/src/plugins/builtin/earnings-calls/model.ts +97 -0
  389. package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
  390. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
  391. package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
  392. package/src/plugins/builtin/econ/calendar-model.ts +22 -0
  393. package/src/plugins/builtin/econ/calendar-source.ts +35 -0
  394. package/src/plugins/builtin/econ/index.tsx +40 -8
  395. package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
  396. package/src/plugins/builtin/econ-statistics/detail.tsx +8 -1
  397. package/src/plugins/builtin/econ-statistics/headless.ts +26 -5
  398. package/src/plugins/builtin/econ-statistics/pane.tsx +4 -2
  399. package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
  400. package/src/plugins/builtin/econ-statistics/view.ts +19 -0
  401. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  402. package/src/plugins/builtin/equity-screener/model.ts +46 -4
  403. package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
  404. package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
  405. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  406. package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
  407. package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
  408. package/src/plugins/builtin/executives/index.tsx +1 -0
  409. package/src/plugins/builtin/exposure/editor.tsx +3 -3
  410. package/src/plugins/builtin/fear-greed/index.tsx +9 -0
  411. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  412. package/src/plugins/builtin/futures/index.tsx +2 -2
  413. package/src/plugins/builtin/futures/model.ts +34 -21
  414. package/src/plugins/builtin/futures/table.tsx +1 -1
  415. package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
  416. package/src/plugins/builtin/futures-curve/headless.ts +4 -2
  417. package/src/plugins/builtin/futures-curve/model.ts +5 -7
  418. package/src/plugins/builtin/help/index.tsx +55 -8
  419. package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
  420. package/src/plugins/builtin/holders/headless.ts +12 -0
  421. package/src/plugins/builtin/insider/headless.ts +311 -41
  422. package/src/plugins/builtin/insider/index.tsx +280 -106
  423. package/src/plugins/builtin/insider/insiders.tsx +224 -0
  424. package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
  425. package/src/plugins/builtin/insider/signals-client.ts +135 -11
  426. package/src/plugins/builtin/insider/signals-model.ts +628 -56
  427. package/src/plugins/builtin/insider/signals.tsx +283 -83
  428. package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
  429. package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
  430. package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
  431. package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
  432. package/src/plugins/builtin/iv-history/headless.ts +2 -0
  433. package/src/plugins/builtin/jobs/headless.ts +1 -0
  434. package/src/plugins/builtin/jobs/index.tsx +1 -0
  435. package/src/plugins/builtin/jodi/headless.ts +2 -0
  436. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  437. package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
  438. package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
  439. package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
  440. package/src/plugins/builtin/market-valuation/pane.tsx +1 -1
  441. package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
  442. package/src/plugins/builtin/mna/distress/headless.ts +2 -1
  443. package/src/plugins/builtin/mna/headless.ts +14 -2
  444. package/src/plugins/builtin/mna/index.tsx +1 -0
  445. package/src/plugins/builtin/news/headless.ts +4 -0
  446. package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
  447. package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
  448. package/src/plugins/builtin/notes/cli.ts +8 -4
  449. package/src/plugins/builtin/notes/files.ts +66 -20
  450. package/src/plugins/builtin/notes/migration.ts +18 -6
  451. package/src/plugins/builtin/notes/owner.tsx +3 -2
  452. package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
  453. package/src/plugins/builtin/options-scenario/client.ts +7 -4
  454. package/src/plugins/builtin/options-scenario/headless.ts +5 -3
  455. package/src/plugins/builtin/pe-band/index.tsx +1 -1
  456. package/src/plugins/builtin/pe-band/model.ts +1 -15
  457. package/src/plugins/builtin/perps/headless.ts +30 -13
  458. package/src/plugins/builtin/perps/model.ts +45 -3
  459. package/src/plugins/builtin/perps/pane.tsx +7 -7
  460. package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
  461. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
  462. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +108 -46
  463. package/src/plugins/builtin/portfolio-list/cli/render.ts +368 -45
  464. package/src/plugins/builtin/portfolio-list/cli/shared.ts +8 -2
  465. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +24 -34
  466. package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
  467. package/src/plugins/builtin/portfolio-list/headless.ts +151 -29
  468. package/src/plugins/builtin/portfolio-list/income.ts +296 -0
  469. package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
  470. package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
  471. package/src/plugins/builtin/portfolio-list/pane/index.tsx +27 -10
  472. package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
  473. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +3 -2
  474. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +10 -3
  475. package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
  476. package/src/plugins/builtin/portfolio-list/summary/totals.ts +31 -3
  477. package/src/plugins/builtin/portfolio-list/table.tsx +25 -5
  478. package/src/plugins/builtin/power/prices-headless.ts +2 -1
  479. package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
  480. package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
  481. package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
  482. package/src/plugins/builtin/realized-vol/headless.ts +6 -4
  483. package/src/plugins/builtin/realized-vol/model.ts +5 -1
  484. package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
  485. package/src/plugins/builtin/realized-vol/settings.ts +1 -1
  486. package/src/plugins/builtin/research/analyst-headless.ts +4 -0
  487. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -0
  488. package/src/plugins/builtin/research/event-model.ts +22 -2
  489. package/src/plugins/builtin/research/headless-schema.ts +1 -0
  490. package/src/plugins/builtin/research/headless.ts +3 -0
  491. package/src/plugins/builtin/research/index.tsx +3 -0
  492. package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
  493. package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
  494. package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
  495. package/src/plugins/builtin/reverse-dcf/headless.ts +9 -6
  496. package/src/plugins/builtin/reverse-dcf/index.tsx +2 -2
  497. package/src/plugins/builtin/reverse-dcf/model.ts +51 -4
  498. package/src/plugins/builtin/reverse-dcf/pane.tsx +23 -10
  499. package/src/plugins/builtin/risk-factors/headless.ts +7 -0
  500. package/src/plugins/builtin/risk-factors/index.tsx +1 -0
  501. package/src/plugins/builtin/scanner/feed.ts +5 -3
  502. package/src/plugins/builtin/scanner/headless.ts +9 -57
  503. package/src/plugins/builtin/scanner/index.ts +1 -2
  504. package/src/plugins/builtin/sec/forms.ts +2 -6
  505. package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
  506. package/src/plugins/builtin/sec/fund-facts.ts +328 -0
  507. package/src/plugins/builtin/sec/headless.ts +140 -44
  508. package/src/plugins/builtin/sec/index.tsx +95 -30
  509. package/src/plugins/builtin/sec/model.ts +2 -44
  510. package/src/plugins/builtin/shared/headless-options.ts +10 -0
  511. package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
  512. package/src/plugins/builtin/shared/move-rank.ts +108 -0
  513. package/src/plugins/builtin/shared/report-freshness.ts +25 -9
  514. package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
  515. package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
  516. package/src/plugins/builtin/shared/use-quote-board.ts +1 -0
  517. package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
  518. package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
  519. package/src/plugins/builtin/short-interest/headless.ts +3 -0
  520. package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
  521. package/src/plugins/builtin/social-mentions/client.ts +8 -1
  522. package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
  523. package/src/plugins/builtin/supply-chain/client.ts +12 -3
  524. package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
  525. package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
  526. package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
  527. package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
  528. package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
  529. package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
  530. package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
  531. package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
  532. package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
  533. package/src/plugins/builtin/supply-chain/headless.ts +69 -27
  534. package/src/plugins/builtin/supply-chain/index.tsx +1 -1
  535. package/src/plugins/builtin/supply-chain/model.ts +76 -15
  536. package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
  537. package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
  538. package/src/plugins/builtin/themes/model.ts +2 -5
  539. package/src/plugins/builtin/thirteenf/api.ts +50 -2
  540. package/src/plugins/builtin/thirteenf/data.ts +250 -11
  541. package/src/plugins/builtin/thirteenf/headless.ts +311 -28
  542. package/src/plugins/builtin/thirteenf/index.tsx +4 -1
  543. package/src/plugins/builtin/thirteenf/model.ts +244 -19
  544. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
  545. package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
  546. package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
  547. package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
  548. package/src/plugins/builtin/thirteenf/types.ts +49 -0
  549. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -8
  550. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +17 -1
  551. package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
  552. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
  553. package/src/plugins/builtin/ticker-detail/headless.ts +23 -10
  554. package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
  555. package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
  556. package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
  557. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
  558. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +36 -3
  559. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
  560. package/src/plugins/builtin/time-sales/client.ts +7 -4
  561. package/src/plugins/builtin/time-sales/headless.ts +71 -22
  562. package/src/plugins/builtin/time-sales/model.ts +12 -0
  563. package/src/plugins/builtin/time-sales/pane.tsx +31 -7
  564. package/src/plugins/builtin/time-sales/window.ts +128 -0
  565. package/src/plugins/builtin/trace-bonds/client.ts +351 -33
  566. package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
  567. package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
  568. package/src/plugins/builtin/trace-bonds/model.ts +27 -25
  569. package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
  570. package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
  571. package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
  572. package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
  573. package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
  574. package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
  575. package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
  576. package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
  577. package/src/plugins/builtin/vol-surface/headless.ts +3 -2
  578. package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
  579. package/src/plugins/builtin/vol-surface/stored.ts +4 -7
  580. package/src/plugins/builtin/volatility/chart-model.ts +16 -15
  581. package/src/plugins/builtin/volatility/charts.tsx +5 -5
  582. package/src/plugins/builtin/volatility/client.ts +73 -2
  583. package/src/plugins/builtin/volatility/evidence.ts +13 -14
  584. package/src/plugins/builtin/volatility/headless.ts +13 -7
  585. package/src/plugins/builtin/volatility/index.tsx +1 -1
  586. package/src/plugins/builtin/volatility/model.ts +104 -38
  587. package/src/plugins/builtin/volatility/pane.tsx +42 -24
  588. package/src/plugins/builtin/volatility/series.ts +22 -13
  589. package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
  590. package/src/plugins/builtin/world-venue-map/headless.ts +8 -5
  591. package/src/plugins/builtin/world-venue-map/index.ts +16 -2
  592. package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
  593. package/src/plugins/builtin/yield-curve/curves.ts +29 -5
  594. package/src/plugins/builtin/yield-curve/headless.ts +41 -8
  595. package/src/plugins/builtin/yield-curve/history.ts +5 -5
  596. package/src/plugins/builtin/yield-curve/index.tsx +30 -13
  597. package/src/plugins/compat.ts +3 -1
  598. package/src/plugins/dependencies.ts +8 -2
  599. package/src/plugins/host-link.ts +12 -5
  600. package/src/plugins/installer.ts +16 -7
  601. package/src/plugins/loader.ts +9 -2
  602. package/src/plugins/marketplace/activation.ts +10 -4
  603. package/src/plugins/registry/host-actions.ts +3 -0
  604. package/src/plugins/registry/index.ts +3 -1
  605. package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +74 -12
  606. package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +140 -53
  607. package/src/portfolio/futures-positions.ts +213 -0
  608. package/src/portfolio/futures-terms.ts +75 -0
  609. package/src/portfolio/manual-lots.ts +78 -0
  610. package/src/portfolio/mutations.ts +54 -10
  611. package/src/portfolio/position-metrics.ts +44 -10
  612. package/src/portfolio/valuation-basis.ts +31 -4
  613. package/src/public/__snapshots__/public-api.test.ts.snap +4 -0
  614. package/src/public/time-series.ts +2 -1
  615. package/src/remote/confirm-change.tsx +2 -1
  616. package/src/remote/server.ts +1 -1
  617. package/src/remote/watchlist.ts +9 -1
  618. package/src/renderers/dom/data-table/row.tsx +1 -1
  619. package/src/renderers/dom/desktop/audio-player.tsx +312 -0
  620. package/src/renderers/dom/desktop/control-styles.ts +17 -82
  621. package/src/renderers/dom/desktop/controls.tsx +39 -63
  622. package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
  623. package/src/renderers/dom/desktop/icons.tsx +8 -0
  624. package/src/renderers/dom/desktop/list-view.tsx +6 -6
  625. package/src/renderers/dom/desktop/popover.tsx +0 -3
  626. package/src/renderers/dom/desktop/query-bar.tsx +6 -4
  627. package/src/renderers/dom/desktop/select-field.tsx +9 -8
  628. package/src/renderers/dom/desktop/stack-header.ts +3 -0
  629. package/src/renderers/dom/dom-ui-host.tsx +3 -2
  630. package/src/renderers/dom/host/chart-surface.tsx +3 -3
  631. package/src/renderers/dom/host/size-observer.ts +33 -4
  632. package/src/renderers/dom/host/surface-3d.tsx +3 -2
  633. package/src/renderers/dom/host/surface-fit.ts +4 -1
  634. package/src/renderers/dom/host/tabs.tsx +22 -132
  635. package/src/renderers/dom/styles.css +358 -160
  636. package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
  637. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
  638. package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
  639. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
  640. package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
  641. package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
  642. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
  643. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  644. package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
  645. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
  646. package/src/series/capability.ts +1 -0
  647. package/src/series/files.ts +9 -3
  648. package/src/series/registry.ts +40 -14
  649. package/src/series/resolve.ts +121 -18
  650. package/src/series/standalone.ts +3 -2
  651. package/src/series/types.ts +55 -1
  652. package/src/series/validate.ts +39 -0
  653. package/src/shares/api.ts +26 -7
  654. package/src/shares/bug-report-dialog.tsx +2 -2
  655. package/src/shares/bug-report-flow.tsx +4 -7
  656. package/src/shares/capture-flow.ts +5 -4
  657. package/src/shares/capture-preview.tsx +2 -2
  658. package/src/shares/chat.ts +7 -27
  659. package/src/shares/flow.tsx +86 -40
  660. package/src/shares/location.ts +1 -3
  661. package/src/shares/pane-image.ts +11 -9
  662. package/src/shares/pane.ts +5 -2
  663. package/src/shares/payload.ts +1 -1
  664. package/src/shares/personal-pane.ts +3 -3
  665. package/src/shares/portable-layout.ts +9 -2
  666. package/src/shares/ready.ts +42 -0
  667. package/src/shares/test-harness.ts +62 -0
  668. package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
  669. package/src/sources/gloomberb-cloud/index.ts +64 -12
  670. package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
  671. package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
  672. package/src/sources/history-omitted.ts +34 -0
  673. package/src/sources/history-result.ts +3 -0
  674. package/src/sources/history-retention.ts +1 -1
  675. package/src/sources/provider-errors.ts +43 -1
  676. package/src/sources/provider-router/batches.ts +3 -2
  677. package/src/sources/provider-router/cache.ts +2 -1
  678. package/src/sources/provider-router/cached-routes.ts +9 -3
  679. package/src/sources/provider-router/history.ts +9 -8
  680. package/src/sources/provider-router/index.ts +18 -3
  681. package/src/sources/provider-router/primary.ts +5 -4
  682. package/src/sources/provider-router/quote-route.ts +3 -1
  683. package/src/sources/provider-router/routing.ts +2 -1
  684. package/src/sources/provider-router/search.ts +47 -13
  685. package/src/sources/provider-router/streaming.ts +7 -4
  686. package/src/sources/sec-edgar.ts +1 -3
  687. package/src/state/app/context/index.tsx +9 -13
  688. package/src/state/app/tab-cursor.ts +149 -12
  689. package/src/state/hooks/quote-streaming.ts +3 -2
  690. package/src/state/hooks/session-snapshot.ts +3 -2
  691. package/src/state/persist-scheduler.ts +12 -4
  692. package/src/sync/controller.ts +22 -1
  693. package/src/sync/core-contributors.ts +58 -15
  694. package/src/team/collections-sync.ts +14 -4
  695. package/src/team/collections.ts +40 -11
  696. package/src/team/store.ts +5 -4
  697. package/src/telemetry/attention-counts.ts +8 -2
  698. package/src/telemetry/crash-reports-dom.ts +3 -0
  699. package/src/telemetry/crash-reports-node.ts +7 -4
  700. package/src/telemetry/crash-reports.ts +11 -11
  701. package/src/telemetry/usage-counts.ts +16 -12
  702. package/src/theme/colors.ts +2 -0
  703. package/src/theme/font-scale.ts +2 -0
  704. package/src/theme/ui-tokens.ts +71 -0
  705. package/src/tickers/batched-lookups.ts +186 -0
  706. package/src/tickers/company-name-listing.ts +97 -0
  707. package/src/tickers/company-name.ts +13 -0
  708. package/src/tickers/instrument-coverage.ts +112 -0
  709. package/src/tickers/listing-fate.ts +49 -9
  710. package/src/tickers/listing-venues.ts +24 -5
  711. package/src/tickers/open-target.ts +13 -5
  712. package/src/tickers/search/index.ts +112 -35
  713. package/src/tickers/search/ranking.ts +49 -1
  714. package/src/tickers/terminal-codes.ts +79 -0
  715. package/src/tickers/ticker-changes.ts +74 -3
  716. package/src/tickers/us-listing.ts +2 -1
  717. package/src/time-series/chart-data.ts +79 -8
  718. package/src/time-series/fundamentals.ts +55 -7
  719. package/src/time-series/ice-credit.ts +17 -2
  720. package/src/time-series/live-bars.ts +21 -8
  721. package/src/time-series/live-quotes.ts +2 -3
  722. package/src/time-series/price-comparison.ts +6 -1
  723. package/src/time-series/resolve.ts +65 -10
  724. package/src/time-series/spec.ts +2 -1
  725. package/src/time-series/studies.ts +3 -3
  726. package/src/time-series/types.ts +22 -0
  727. package/src/time-series/use-chart-resolution.ts +2 -1
  728. package/src/types/config.ts +7 -0
  729. package/src/types/data-provider.ts +20 -0
  730. package/src/types/headless.ts +142 -1
  731. package/src/types/instrument.ts +6 -0
  732. package/src/types/plugin.ts +32 -9
  733. package/src/types/price-history.ts +5 -0
  734. package/src/types/ticker-changes.ts +19 -0
  735. package/src/types/ticker.ts +10 -2
  736. package/src/ui/context-menu.tsx +2 -0
  737. package/src/ui/host.tsx +40 -4
  738. package/src/ui/measured-cells.ts +13 -7
  739. package/src/ui/qr.ts +7 -5
  740. package/src/updater/index.ts +5 -5
  741. package/src/utils/calendar-date.ts +86 -27
  742. package/src/utils/currency-units.ts +17 -0
  743. package/src/utils/debug-log.ts +1 -1
  744. package/src/utils/dividend-cash.ts +48 -0
  745. package/src/utils/dom-screenshot-rasters.ts +3 -1
  746. package/src/utils/dom-screenshot.ts +14 -10
  747. package/src/utils/exchange-rate-snapshot.ts +9 -4
  748. package/src/utils/external-url.ts +1 -0
  749. package/src/utils/fiscal-period.ts +47 -0
  750. package/src/utils/format.ts +5 -2
  751. package/src/utils/forward-dividend.ts +160 -11
  752. package/src/utils/futures-generic.ts +34 -8
  753. package/src/utils/http-proxy-response.ts +2 -1
  754. package/src/utils/local-utc-offset.ts +2 -0
  755. package/src/utils/log-failure.ts +31 -0
  756. package/src/utils/option-expiry.ts +12 -12
  757. package/src/utils/price-history-integrity.ts +56 -0
  758. package/src/utils/price-history.ts +13 -1
  759. package/src/utils/sec-filings.ts +245 -0
  760. package/src/utils/selection-clipboard.ts +5 -2
  761. package/src/utils/throttled-fetch.ts +1 -0
  762. package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
  763. package/src/utils/url.ts +1 -0
  764. package/src/utils/utc-time.ts +11 -0
  765. package/src/plugins/builtin/chat/share/targets.ts +0 -27
  766. package/src/renderers/dom/host/top-surface.ts +0 -119
  767. package/src/shares/dialog.tsx +0 -221
  768. package/src/shares/live.ts +0 -19
@@ -1,8 +1,8 @@
1
- import type { Portfolio, PortfolioCash } from "../../../types/ticker";
2
- import type { BrokerAccount } from "../../../types/trading";
3
- import { currencyMinorDigits, getCurrencySymbol, resolveAssetDisplayKind } from "../../../market-data/market/format";
4
- import { formatNumber } from "../../../utils/format";
5
- import { parseTypedNumber } from "../../../utils/decimal-comma";
1
+ import type { Portfolio, PortfolioCash } from "../types/ticker";
2
+ import type { BrokerAccount } from "../types/trading";
3
+ import { currencyMinorDigits, getCurrencySymbol, resolveAssetDisplayKind } from "../market-data/market/format";
4
+ import { formatNumber } from "../utils/format";
5
+ import { parseTypedNumber } from "../utils/decimal-comma";
6
6
 
7
7
  /**
8
8
  * Weights, targets and the trades that would rebalance a portfolio. `PF`, its
@@ -10,9 +10,10 @@ import { parseTypedNumber } from "../../../utils/decimal-comma";
10
10
  * here, so a weight never differs between them.
11
11
  *
12
12
  * A weight is a share of the total value, cash included: the priced holdings
13
- * at their net market value (a short counts against it) plus the cash line.
14
- * A holding without a price is left out of the total and the weights and is
15
- * listed as unpriced, never valued at zero.
13
+ * at their net market value plus the cash line. A book that holds a short
14
+ * weighs against its gross exposure instead (WeightBasis). A holding without
15
+ * a price is left out of the total and the weights and is listed as
16
+ * unpriced, never valued at zero.
16
17
  */
17
18
 
18
19
  /** The cash line's symbol in targets and reports. */
@@ -35,7 +36,7 @@ export interface AllocationHolding {
35
36
  }
36
37
 
37
38
  export interface AllocationFigures {
38
- /** Percent of the total, cash included. */
39
+ /** Percent of the weight base: the total, cash included, or a hedged book's gross exposure. */
39
40
  weight: number | null;
40
41
  /** Percent. */
41
42
  targetWeight: number | null;
@@ -61,6 +62,10 @@ export interface PortfolioAllocation {
61
62
  cash: PortfolioCashLine | null;
62
63
  /** Priced holdings plus cash; null when it cannot be valued. */
63
64
  total: number | null;
65
+ /** What the weights are a share of. */
66
+ weightBasis: WeightBasis;
67
+ /** The amount they divide: the total, or the gross exposure; null when there is no positive one. */
68
+ weightBase: number | null;
64
69
  /** Held symbols without a price, left out of the total and the weights. */
65
70
  unpriced: string[];
66
71
  /** The targets of the listed symbols and cash added up; null when none is set. */
@@ -105,6 +110,52 @@ export function allocationFigures(
105
110
  return { weight, targetWeight, drift, tradeValue, tradeUnits };
106
111
  }
107
112
 
113
+ /**
114
+ * What weights divide by. `total`: the total value, cash included, as a book
115
+ * without a short is weighed. `gross`: a book that holds a short weighs each
116
+ * position's signed value against its gross exposure, longs plus shorts at
117
+ * their absolute value, so the absolute weights add up to 100% however close
118
+ * to zero the hedge nets, or below it. Cash is no exposure and has no weight
119
+ * there.
120
+ */
121
+ export type WeightBasis = "total" | "gross";
122
+
123
+ /** Whether any held position is short: its value, or its units when it has no price, below zero. */
124
+ function holdsShort(holdings: readonly AllocationHolding[]): boolean {
125
+ return holdings.some((holding) => holding.held && (finite(holding.marketValue) ? holding.marketValue < 0 : holding.units < 0));
126
+ }
127
+
128
+ /** What the weights of these holdings are a share of, and how much it is. */
129
+ export function allocationWeightBase(
130
+ holdings: readonly AllocationHolding[],
131
+ cashValue: number | null | undefined,
132
+ ): { basis: WeightBasis; value: number | null } {
133
+ if (!holdsShort(holdings)) return { basis: "total", value: weightBase(allocationTotal(holdings, cashValue)) };
134
+ let gross = 0;
135
+ for (const holding of holdings) {
136
+ if (holding.held && finite(holding.marketValue)) gross += Math.abs(holding.marketValue);
137
+ }
138
+ return { basis: "gross", value: weightBase(gross) };
139
+ }
140
+
141
+ /** The line that says what a hedged book's weights are a share of; null on the total, which needs none. */
142
+ export function weightBasisNote(
143
+ base: Pick<PortfolioAllocation, "weightBasis" | "weightBase">,
144
+ money: (value: number) => string,
145
+ ): string | null {
146
+ if (base.weightBasis !== "gross") return null;
147
+ const amount = base.weightBase != null ? ` (${money(base.weightBase)})` : "";
148
+ return `Weights are shares of gross exposure${amount}, longs plus shorts at their absolute value, as the book holds a short; cash has no weight.`;
149
+ }
150
+
151
+ /**
152
+ * One lot's share of the weight base, in percent. A ticker held in several lots
153
+ * weighs each by its own value; the lots add up to the ticker's weight.
154
+ */
155
+ export function lotWeight(marketValue: number | null | undefined, total: number | null | undefined): number | null {
156
+ return allocationFigures({ held: true, marketValue: marketValue ?? null, units: 0, unitPrice: null }, total, null).weight;
157
+ }
158
+
108
159
  /** The total weights divide by: every priced holding plus the cash. */
109
160
  export function allocationTotal(holdings: readonly AllocationHolding[], cashValue: number | null | undefined): number | null {
110
161
  // Cash that cannot be converted leaves the total unknown rather than smaller.
@@ -127,12 +178,15 @@ export function buildPortfolioAllocation({
127
178
  targets?: Readonly<Record<string, number>>;
128
179
  }): PortfolioAllocation {
129
180
  const total = allocationTotal(holdings, cashValue);
130
- const rows = holdings.map((holding) => ({ ...holding, ...allocationFigures(holding, total, holdingTarget(targets, holding.symbol)) }));
181
+ const base = allocationWeightBase(holdings, cashValue);
182
+ const rows = holdings.map((holding) => ({ ...holding, ...allocationFigures(holding, base.value, holdingTarget(targets, holding.symbol)) }));
131
183
  const cashTarget = targets?.[CASH_SYMBOL];
132
184
  const cash = cashValue != null || finite(cashTarget)
133
185
  ? {
134
186
  value: cashValue ?? 0,
135
- ...allocationFigures({ held: true, marketValue: cashValue ?? 0, units: 0, unitPrice: null }, total, cashTarget),
187
+ // Cash is no exposure: against a gross base it keeps its target but has no weight or trade.
188
+ ...allocationFigures({ held: true, marketValue: cashValue ?? 0, units: 0, unitPrice: null },
189
+ base.basis === "gross" ? null : base.value, cashTarget),
136
190
  }
137
191
  : null;
138
192
  let targetSum: number | null = null;
@@ -144,6 +198,8 @@ export function buildPortfolioAllocation({
144
198
  rows,
145
199
  cash,
146
200
  total,
201
+ weightBasis: base.basis,
202
+ weightBase: base.value,
147
203
  unpriced: holdings.filter((holding) => holding.held && !finite(holding.marketValue)).map((holding) => holding.symbol),
148
204
  targetSum,
149
205
  };
@@ -190,9 +246,15 @@ export function parseTargetWeight(raw: string | undefined): number {
190
246
  }
191
247
 
192
248
  /** A one-line note when the targets do not add up to the whole portfolio, else null. */
193
- export function describeTargetSum(targetSum: number | null): string | null {
249
+ export function describeTargetSum(targetSum: number | null, basis: WeightBasis = "total"): string | null {
194
250
  if (targetSum == null || Math.abs(targetSum - 100) < 0.05) return null;
195
251
  const remainder = 100 - targetSum;
252
+ // Against gross exposure, what no target covers is not cash waiting: it is a short's share, or a holding without a target.
253
+ if (basis === "gross") {
254
+ return remainder > 0
255
+ ? `Targets add up to ${formatAllocationWeight(targetSum)} of gross exposure; ${formatAllocationWeight(remainder)} has no target.`
256
+ : `Targets add up to ${formatAllocationWeight(targetSum)}, ${formatAllocationWeight(-remainder)} over the gross exposure.`;
257
+ }
196
258
  return remainder > 0
197
259
  ? `Targets add up to ${formatAllocationWeight(targetSum)}; ${formatAllocationWeight(remainder)} is unallocated.`
198
260
  : `Targets add up to ${formatAllocationWeight(targetSum)}, ${formatAllocationWeight(-remainder)} over the whole portfolio.`;
@@ -1,15 +1,15 @@
1
1
  // Public API: gloomberb/components re-exports getColumnValue, getSortValue and
2
2
  // ColumnContext from here, so external plugins depend on their names and shapes.
3
- import { comparablePriceEarnings, formatPriceEarnings } from "../../../utils/price-earnings";
4
- import { convertMarketCapitalization, listedMarketCapitalization } from "../../../utils/market-capitalization";
5
- import type { ColumnConfig } from "../../../types/config";
6
- import type { AnalystResearchData, CorporateActionsData, MarketState, TickerFinancials } from "../../../types/financials";
7
- import type { EarningsEvent } from "../../../types/data-provider";
8
- import type { TickerRecord } from "../../../types/ticker";
9
- import { colors, priceColor } from "../../../theme/colors";
10
- import { formatQuoteAgeWithSource, resolveQuoteAgeTimestamp } from "../../../market-data/quotes/time";
11
- import { formatFeedTime, formatShortDate, parseDisplayDate, type ShortDateOptions } from "../../../utils/datetime-format";
12
- import { convertCurrency, formatCompact, formatCompactAmount, formatNumber, formatPercentRaw } from "../../../utils/format";
3
+ import { comparablePriceEarnings, formatPriceEarnings } from "../utils/price-earnings";
4
+ import { convertMarketCapitalization, listedMarketCapitalization } from "../utils/market-capitalization";
5
+ import type { ColumnConfig } from "../types/config";
6
+ import type { AnalystResearchData, CorporateActionsData, MarketState, TickerFinancials } from "../types/financials";
7
+ import type { EarningsEvent } from "../types/data-provider";
8
+ import type { TickerRecord } from "../types/ticker";
9
+ import { colors, priceColor } from "../theme/colors";
10
+ import { formatQuoteAgeWithSource, resolveQuoteAgeTimestamp } from "../market-data/quotes/time";
11
+ import { formatFeedTime, formatShortDate, parseDisplayDate, type ShortDateOptions } from "../utils/datetime-format";
12
+ import { convertCurrency, formatCompact, formatCompactAmount, formatNumber, formatPercentRaw } from "../utils/format";
13
13
  import {
14
14
  formatMarketCost,
15
15
  quoteFormatOptions,
@@ -20,7 +20,7 @@ import {
20
20
  withCurrencyMinorDigits,
21
21
  withStablePriceDigits,
22
22
  type MarketFormatOptions,
23
- } from "../../../market-data/market/format";
23
+ } from "../market-data/market/format";
24
24
  import {
25
25
  getActiveQuoteDisplay,
26
26
  getCompletedRegularSessionDisplay,
@@ -30,21 +30,25 @@ import {
30
30
  marketStateDot,
31
31
  quoteDotMarketState,
32
32
  type ActiveQuoteDisplay,
33
- } from "../../../market-data/market/status";
34
- import { formatOptionTicker } from "../../../utils/options";
35
- import { classifyInstrumentType } from "../../../tickers/instrument-kind";
36
- import { perpetualDisplaySymbol, perpetualListing } from "../../../tickers/perpetual-listing";
37
- import { currentListingName } from "../../../tickers/listing-name";
38
- import { PRICE_SPARKLINE_COLUMN_ID } from "../../../components/price-sparkline/view";
39
- import { followLiveSparklinePrice, resolveSparklineHistory, sparklineValues } from "../../../components/price-sparkline/model";
33
+ } from "../market-data/market/status";
34
+ import { formatOptionTicker } from "../utils/options";
35
+ import { distributionHistory, forwardYieldMayHaveLapsed, lapsedDividend } from "../utils/forward-dividend";
36
+ import { classifyInstrumentType } from "../tickers/instrument-kind";
37
+ import { isIndexLevel, reportedQuoteVolume } from "../market-data/market/index-level";
38
+ import { perpetualDisplaySymbol, perpetualListing } from "../tickers/perpetual-listing";
39
+ import { currentListingName } from "../tickers/listing-name";
40
+ import { PRICE_SPARKLINE_COLUMN_ID } from "../components/price-sparkline/view";
41
+ import { followLiveSparklinePrice, resolveSparklineHistory, sparklineValues } from "../components/price-sparkline/model";
40
42
  import {
43
+ listingDividendYield,
41
44
  liveDividendYield,
42
45
  liveFiftyTwoWeekRange,
43
46
  liveForwardPE,
44
47
  liveMarketCapitalization,
45
48
  liveTrailingPE,
49
+ measuresTrailingYield,
46
50
  targetReferencePrice,
47
- } from "../../../market-data/quotes/live-valuation";
51
+ } from "../market-data/quotes/live-valuation";
48
52
  import {
49
53
  getPortfolioPositionMetrics,
50
54
  getPortfolioQuoteDisplay,
@@ -52,14 +56,17 @@ import {
52
56
  resolvePortfolioPositionPnl,
53
57
  portfolioPnlPercent,
54
58
  signedPositionDirection,
59
+ type PortfolioPositionMetrics,
55
60
  type PortfolioPositionPnl,
56
- } from "../../../portfolio/position-metrics";
61
+ } from "./position-metrics";
57
62
  import {
58
63
  getPortfolioValuationDisplay,
59
64
  getPortfolioValuationTime,
65
+ valuesAtSettlement,
60
66
  type PortfolioValuationBasis,
61
- } from "../../../portfolio/valuation-basis";
62
- import { isFiniteNumber } from "../../../utils/guards";
67
+ } from "./valuation-basis";
68
+ import { futuresQuantityText, futuresSettlementDisplay, type PortfolioFuturesTerms } from "./futures-positions";
69
+ import { isFiniteNumber } from "../utils/guards";
63
70
  import {
64
71
  allocationFigures,
65
72
  formatAllocationDrift,
@@ -67,6 +74,7 @@ import {
67
74
  formatTradeUnits,
68
75
  holdingTarget,
69
76
  type AllocationFigures,
77
+ type WeightBasis,
70
78
  } from "./allocation";
71
79
 
72
80
  export interface ColumnContext {
@@ -79,11 +87,13 @@ export interface ColumnContext {
79
87
  /** What market values, P&L, weights and the day's move are priced at; the latest print when absent. */
80
88
  valuationBasis?: PortfolioValuationBasis;
81
89
  /**
82
- * The total a portfolio's weights divide by: its priced holdings at net
83
- * market value plus its cash (see allocation.ts). It may trail the rows by
84
- * about a second.
90
+ * What a portfolio's weights divide by (allocationWeightBase): its priced
91
+ * holdings at net market value plus its cash, or, for a book that holds a
92
+ * short, its gross exposure. It may trail the rows by about a second.
85
93
  */
86
- portfolioTotalMarketValue?: number;
94
+ portfolioWeightBase?: number;
95
+ /** Which of the two `portfolioWeightBase` is. */
96
+ portfolioWeightBasis?: WeightBasis;
87
97
  /** The portfolio's target weights in percent, by symbol. */
88
98
  portfolioTargets?: Readonly<Record<string, number>>;
89
99
  supplementalVersion?: number;
@@ -94,6 +104,13 @@ export interface ColumnContext {
94
104
  perpetuals?: ReadonlyMap<string, ListedPerpetual | null>;
95
105
  /** Moves whenever `perpetuals` does. */
96
106
  perpetualsVersion?: number;
107
+ /**
108
+ * Each future's contract size and settlement by symbol (loadPortfolioFuturesTerms):
109
+ * at the close a future is valued, and its Last shown, at its settlement.
110
+ */
111
+ futuresTerms?: ReadonlyMap<string, PortfolioFuturesTerms>;
112
+ /** Moves whenever `futuresTerms` does. */
113
+ futuresTermsVersion?: number;
97
114
  }
98
115
 
99
116
  /** A row's stock perpetual as PERP% and FUND 8H read it; rates are fractions. */
@@ -163,6 +180,17 @@ function positionSideLabel(ticker: TickerRecord, activeTab: string | undefined):
163
180
  return "MIX";
164
181
  }
165
182
 
183
+ /** The currency a row is listed in: its position's, else its quote's; an index's level is in points and has none. */
184
+ function listedCurrency(
185
+ positionCurrency: string | undefined,
186
+ quoteCurrency: string,
187
+ ticker: TickerRecord,
188
+ quote: TickerFinancials["quote"],
189
+ ): string {
190
+ if (!positionCurrency && isIndexLevel(quote?.instrumentType || ticker.metadata.assetCategory)) return "";
191
+ return (positionCurrency || quoteCurrency || ticker.metadata.currency || "").toUpperCase();
192
+ }
193
+
166
194
  function compactText(value: string | null | undefined): string {
167
195
  const trimmed = value?.trim();
168
196
  return trimmed ? trimmed : "—";
@@ -207,6 +235,30 @@ function nextEarningsDate(symbol: string, ctx: ColumnContext): { pending: boolea
207
235
  };
208
236
  }
209
237
 
238
+ /**
239
+ * DIV%: the yield at the live price; a trailing one as DVD measures it from
240
+ * the cash history once that has loaded (listingDividendYield), and none
241
+ * once a forward yield's dividend has stopped (lapsedDividend), pending while
242
+ * the history that says so loads.
243
+ */
244
+ function currentDividendYield(
245
+ symbol: string,
246
+ quote: TickerFinancials["quote"],
247
+ fundamentals: TickerFinancials["fundamentals"],
248
+ ctx: ColumnContext,
249
+ ): { pending: boolean; value: number | null } {
250
+ const now = new Date(ctx.now);
251
+ // The rows the corporate actions are loaded for (usePortfolioSupplementalData); a trailing yield is never withdrawn, so it does not wait.
252
+ if (measuresTrailingYield(fundamentals)) {
253
+ return { pending: false, value: listingDividendYield(quote, fundamentals, mapData(ctx.corporateActions, symbol).data, now) ?? null };
254
+ }
255
+ const value = liveDividendYield(quote, fundamentals) ?? null;
256
+ if (value == null || !forwardYieldMayHaveLapsed(fundamentals, now)) return { pending: false, value };
257
+ const actions = mapData(ctx.corporateActions, symbol);
258
+ if (actions.pending) return { pending: true, value: null };
259
+ return { pending: false, value: lapsedDividend(fundamentals!.exDividendDate, distributionHistory(actions.data, now), now) ? null : value };
260
+ }
261
+
210
262
  function exDividendDate(symbol: string, ctx: ColumnContext): { pending: boolean; date: Date | null } {
211
263
  const actions = mapData(ctx.corporateActions, symbol);
212
264
  if (actions.pending) return { pending: true, date: null };
@@ -272,7 +324,7 @@ function rowAllocation(
272
324
  return {
273
325
  ...allocationFigures(
274
326
  { held, marketValue, units: baseMetrics.totalShares, unitPrice },
275
- ctx.portfolioTotalMarketValue,
327
+ ctx.portfolioWeightBase,
276
328
  holdingTarget(ctx.portfolioTargets, ticker.metadata.ticker),
277
329
  ),
278
330
  unpriced: held && marketValue == null,
@@ -312,6 +364,30 @@ export function resolvePortfolioPriceValue(
312
364
  return { text: "—" };
313
365
  }
314
366
 
367
+ /**
368
+ * What Last and Chg show for a future valued at the close: the settlement it
369
+ * is valued at and the move from the one before, so its value is still Last
370
+ * times its quantity. Null on the latest print, or without a settlement.
371
+ */
372
+ function settledHeadline(
373
+ metrics: PortfolioPositionMetrics,
374
+ ctx: Pick<ColumnContext, "valuationBasis">,
375
+ futures: PortfolioFuturesTerms | undefined,
376
+ ): ActiveQuoteDisplay | null {
377
+ return futures?.settlement && valuesAtSettlement(metrics, ctx.valuationBasis ?? "latest-print")
378
+ ? futuresSettlementDisplay(futures.settlement) : null;
379
+ }
380
+
381
+ /** One contract as the terms word it ("100 oz"), else its multiplier ("100"); none while the size is unknown. */
382
+ function futuresContractSizeLabel(
383
+ futures: PortfolioFuturesTerms | undefined,
384
+ multiplier: number,
385
+ metrics: Pick<PortfolioPositionMetrics, "unknownContractSize">,
386
+ ): { size: string } | null {
387
+ if (futures?.size) return futures.size;
388
+ return !metrics.unknownContractSize && multiplier > 1 ? { size: formatMarketQuantity(multiplier) } : null;
389
+ }
390
+
315
391
  export function getColumnValue(
316
392
  col: ColumnConfig,
317
393
  ticker: TickerRecord,
@@ -324,11 +400,12 @@ export function getColumnValue(
324
400
  const quoteCurrency = quote?.currency || ticker.metadata.currency || "USD";
325
401
 
326
402
  const positionMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, undefined, quote);
403
+ const futures = positionMetrics.isFuture ? ctx.futuresTerms?.get(ticker.metadata.ticker) : undefined;
327
404
  // The latest print, which the quote columns read, and the price the position is valued at.
328
405
  const liveQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
329
- const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis);
406
+ const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis, futures?.settlement);
330
407
  const displayQuote = tradedQuoteDisplay(positionMetrics, liveQuote, quote);
331
- const headlineQuote = headlineQuoteDisplay(displayQuote, quote);
408
+ const headlineQuote = settledHeadline(positionMetrics, ctx, futures) ?? headlineQuoteDisplay(displayQuote, quote);
332
409
  const { positionCurrency, totalShares, totalCost, totalCostUnits, totalPriceUnits, multiplierHint, brokerMarkPrice } = positionMetrics;
333
410
  const baseMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, {
334
411
  currency: ctx.baseCurrency,
@@ -376,7 +453,7 @@ export function getColumnValue(
376
453
  ),
377
454
  };
378
455
  case "currency":
379
- return { text: compactText((positionCurrency || quoteCurrency || ticker.metadata.currency || "").toUpperCase()) };
456
+ return { text: compactText(listedCurrency(positionCurrency, quoteCurrency, ticker, quote)) };
380
457
  case "sector":
381
458
  return { text: compactText(ticker.metadata.sector || financials?.profile?.sector) };
382
459
  case "industry":
@@ -417,11 +494,14 @@ export function getColumnValue(
417
494
  ? { text: formatPercentRaw(changePercent), color: marketChangeColor(changePercent, quote.marketState) }
418
495
  : { text: "—" };
419
496
  }
420
- case "volume":
421
- return { text: isFiniteNumber(quote?.volume) ? formatCompact(quote.volume, { fixedDecimals: true }) : "—" };
497
+ case "volume": {
498
+ const volume = reportedQuoteVolume(quote);
499
+ return { text: volume != null ? formatCompact(volume, { fixedDecimals: true }) : "—" };
500
+ }
422
501
  case "dollar_volume": {
423
- if (!displayQuote || !isFiniteNumber(quote?.volume)) return { text: "—" };
424
- return { text: formatCompact(toBaseQuote(displayQuote.price * quote.volume), { fixedDecimals: true }) };
502
+ const volume = reportedQuoteVolume(quote);
503
+ if (!displayQuote || volume == null) return { text: "—" };
504
+ return { text: formatCompact(toBaseQuote(displayQuote.price * volume), { fixedDecimals: true }) };
425
505
  }
426
506
  case "range_52w": {
427
507
  const position = fiftyTwoWeekPosition(displayQuote, quote);
@@ -437,8 +517,9 @@ export function getColumnValue(
437
517
  case "forward_pe":
438
518
  return { text: formatPriceEarnings(liveForwardPE(quote, fundamentals)) };
439
519
  case "dividend_yield": {
440
- const dividendYield = liveDividendYield(quote, fundamentals);
441
- return { text: dividendYield != null ? `${(dividendYield * 100).toFixed(2)}%` : "—" };
520
+ const dividendYield = currentDividendYield(ticker.metadata.ticker, quote, fundamentals, ctx);
521
+ if (dividendYield.pending) return { text: "…" };
522
+ return { text: dividendYield.value != null ? `${(dividendYield.value * 100).toFixed(2)}%` : "—" };
442
523
  }
443
524
  case "ext_hours": {
444
525
  const changePercent = getExtendedSessionDisplay(quote)?.changePercent;
@@ -448,17 +529,22 @@ export function getColumnValue(
448
529
  case "side":
449
530
  return { text: positionSideLabel(ticker, ctx.activeTab) ?? "—" };
450
531
  case "shares":
451
- return { text: positionMetrics.positionCount > 0 ? formatMarketQuantity(totalShares, { ...formatOptions, maxWidth: col.width }) : "—" };
532
+ if (positionMetrics.positionCount === 0) return { text: "—" };
533
+ // A future counts contracts and says what one is: -1,000 × 100 oz. The table widens the column to fit.
534
+ return positionMetrics.isFuture
535
+ ? { text: futuresQuantityText(formatMarketQuantity(totalShares, formatOptions), futuresContractSizeLabel(futures, multiplierHint, positionMetrics)) }
536
+ : { text: formatMarketQuantity(totalShares, { ...formatOptions, maxWidth: col.width }) };
452
537
  case "avg_cost":
453
538
  if (totalCostUnits === 0 || !Number.isFinite(totalCost)) return { text: "—" };
454
539
  // A money cost keeps its currency's minor unit, as `portfolio show` prints it: 45.50, not 45.5.
455
540
  return { text: formatMarketCost(totalCost / Math.abs(totalCostUnits), { ...withCurrencyMinorDigits(formatOptions, positionCurrency), maxWidth: col.width }) };
456
541
  case "cost_basis":
457
- if (baseMetrics.positionCount === 0 || !Number.isFinite(baseMetrics.totalCost)) return { text: "—" };
458
- return { text: formatCompact(baseMetrics.totalCost) };
542
+ // Signed, as the value is: a short's cost is what it was sold for, negative.
543
+ if (baseMetrics.positionCount === 0 || !Number.isFinite(baseMetrics.signedCost)) return { text: "—" };
544
+ return { text: formatCompact(baseMetrics.signedCost) };
459
545
  case "mkt_value": {
460
546
  if (baseMetrics.positionCount === 0) return { text: "—" };
461
- const marketValue = resolvePortfolioMarketValue(baseMetrics, activeQuote ? toBaseQuote(activeQuote.price) : null)?.gross;
547
+ const marketValue = resolvePortfolioMarketValue(baseMetrics, activeQuote ? toBaseQuote(activeQuote.price) : null)?.net;
462
548
  return { text: marketValue == null ? UNPRICED : formatCompactAmount(marketValue) };
463
549
  }
464
550
  case "weight": {
@@ -562,7 +648,7 @@ export function getColumnValue(
562
648
  case "latency":
563
649
  return { text: formatQuoteAgeWithSource(quote, ctx.now, { seconds: true }) };
564
650
  case "as_of": {
565
- const time = getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics);
651
+ const time = getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics, futures?.settlement);
566
652
  if (!time) return { text: "—" };
567
653
  // In UTC, as the header says; a close the venue's calendar gives no hour for is dated by its day.
568
654
  return { text: time.dateOnly ? formatShortDate(time.time, MONTH_DAY) : formatFeedTime(time.time, ctx.now, "—", { utc: true }) };
@@ -586,10 +672,11 @@ export function getSortValue(
586
672
  const quoteCurrency = quote?.currency || ticker.metadata.currency || "USD";
587
673
 
588
674
  const positionMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, undefined, quote);
675
+ const futures = positionMetrics.isFuture ? ctx.futuresTerms?.get(ticker.metadata.ticker) : undefined;
589
676
  const liveQuote = getPortfolioQuoteDisplay(positionMetrics, quote);
590
- const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis);
677
+ const activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, ctx.valuationBasis, futures?.settlement);
591
678
  const displayQuote = tradedQuoteDisplay(positionMetrics, liveQuote, quote);
592
- const headlineQuote = headlineQuoteDisplay(displayQuote, quote);
679
+ const headlineQuote = settledHeadline(positionMetrics, ctx, futures) ?? headlineQuoteDisplay(displayQuote, quote);
593
680
  const { positionCurrency, totalShares, totalCost, totalCostUnits, totalPriceUnits, brokerMarkPrice } = positionMetrics;
594
681
  const baseMetrics = getPortfolioPositionMetrics(ticker, ctx.activeTab, quoteCurrency, {
595
682
  currency: ctx.baseCurrency,
@@ -616,7 +703,7 @@ export function getSortValue(
616
703
  ?? ticker.metadata.exchange
617
704
  ?? null;
618
705
  case "currency":
619
- return (positionCurrency || quoteCurrency || ticker.metadata.currency || "").toUpperCase() || null;
706
+ return listedCurrency(positionCurrency, quoteCurrency, ticker, quote) || null;
620
707
  case "sector":
621
708
  return ticker.metadata.sector || financials?.profile?.sector || null;
622
709
  case "industry":
@@ -647,11 +734,11 @@ export function getSortValue(
647
734
  case "change_pct":
648
735
  return headlineChangePercent(headlineQuote, quote) ?? null;
649
736
  case "volume":
650
- return quote?.volume ?? null;
651
- case "dollar_volume":
652
- return displayQuote && isFiniteNumber(quote?.volume)
653
- ? toBaseQuote(displayQuote.price * quote.volume)
654
- : null;
737
+ return reportedQuoteVolume(quote);
738
+ case "dollar_volume": {
739
+ const volume = reportedQuoteVolume(quote);
740
+ return displayQuote && volume != null ? toBaseQuote(displayQuote.price * volume) : null;
741
+ }
655
742
  case "range_52w":
656
743
  return fiftyTwoWeekPosition(displayQuote, quote);
657
744
  case "market_cap": {
@@ -663,7 +750,7 @@ export function getSortValue(
663
750
  case "forward_pe":
664
751
  return comparablePriceEarnings(liveForwardPE(quote, fundamentals));
665
752
  case "dividend_yield":
666
- return liveDividendYield(quote, fundamentals) ?? null;
753
+ return currentDividendYield(ticker.metadata.ticker, quote, fundamentals, ctx).value;
667
754
  case "ext_hours":
668
755
  return getExtendedSessionDisplay(quote)?.changePercent ?? null;
669
756
  case "side":
@@ -673,9 +760,9 @@ export function getSortValue(
673
760
  case "avg_cost":
674
761
  return positionMetrics.priceBasis !== null && totalCostUnits !== 0 && Number.isFinite(totalCost) ? totalCost / Math.abs(totalCostUnits) : null;
675
762
  case "cost_basis":
676
- return baseMetrics.positionCount > 0 && Number.isFinite(baseMetrics.totalCost) ? baseMetrics.totalCost : null;
763
+ return baseMetrics.positionCount > 0 && Number.isFinite(baseMetrics.signedCost) ? baseMetrics.signedCost : null;
677
764
  case "mkt_value":
678
- return resolvePortfolioMarketValue(baseMetrics, activeQuote ? toBaseQuote(activeQuote.price) : null)?.gross ?? null;
765
+ return resolvePortfolioMarketValue(baseMetrics, activeQuote ? toBaseQuote(activeQuote.price) : null)?.net ?? null;
679
766
  case "weight":
680
767
  return rowAllocation(ticker, activeQuote, baseMetrics, toBaseQuote, ctx).weight;
681
768
  case "target_weight":
@@ -731,7 +818,7 @@ export function getSortValue(
731
818
  case "latency":
732
819
  return quote ? ctx.now - (resolveQuoteAgeTimestamp(quote, ctx.now) ?? ctx.now) : null;
733
820
  case "as_of":
734
- return getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics)?.time ?? null;
821
+ return getPortfolioValuationTime(quote, ctx.valuationBasis, positionMetrics, futures?.settlement)?.time ?? null;
735
822
  case PRICE_SPARKLINE_COLUMN_ID: {
736
823
  // The trend the sparkline draws: its window, closed by the live price.
737
824
  const history = followLiveSparklinePrice(financials?.priceHistory ?? [], quote, {