gloomberb 0.18.3 → 0.18.4

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 (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -14,6 +14,7 @@ import type { IssuerListingParams } from "../../../api-client/paths";
14
14
  import { useAsyncResource } from "../../../react/async-resource";
15
15
  import { useAutoRefresh } from "../../../react/auto-refresh";
16
16
  import { colors, priceColor } from "../../../theme/colors";
17
+ import { MISSING_VALUE } from "../../../utils/format";
17
18
  import { isPlainKey } from "../../../utils/keyboard";
18
19
  import { nextHeaderSort } from "../../../utils/sort-values";
19
20
  import { usePluginAppActions, usePluginPaneState } from "../../runtime";
@@ -74,6 +75,7 @@ export function BeneficialOwnersView({
74
75
  holderRows,
75
76
  fundMatches,
76
77
  sharesOutstanding,
78
+ sharesOutstandingAsOf,
77
79
  onCycleView,
78
80
  onRefreshHolders,
79
81
  listing,
@@ -87,6 +89,8 @@ export function BeneficialOwnersView({
87
89
  fundMatches: ReadonlyMap<string, Holder13FMatch>;
88
90
  /** Today's shares outstanding, which a report's shares are set against when its own base is out of date. */
89
91
  sharesOutstanding?: number | null;
92
+ /** The day that count was taken, when it is dated. */
93
+ sharesOutstandingAsOf?: string | null;
90
94
  onCycleView: () => void;
91
95
  onRefreshHolders: () => void;
92
96
  }) {
@@ -161,7 +165,7 @@ export function BeneficialOwnersView({
161
165
  const renderTodayLine = useCallback((item: BeneficialItem) => (
162
166
  item.kind === "today" && item.row.today
163
167
  // Indented under its row's name; no-break spaces, which the desktop table does not collapse.
164
- ? { text: `\u00a0\u00a0${formatStakeToday(item.row.today)}`, color: colors.textDim, attributes: TextAttributes.NONE }
168
+ ? { text: `\u00a0\u00a0${formatStakeToday(item.row.today, sharesOutstandingAsOf)}`, color: colors.textDim, attributes: TextAttributes.NONE }
165
169
  : null
166
170
  ), []);
167
171
 
@@ -204,12 +208,12 @@ export function BeneficialOwnersView({
204
208
  case "shares":
205
209
  return { text: formatOwnerShares(filing.shares), value: filing.shares, color: tone };
206
210
  case "eventDate":
207
- return { text: filing.eventDate ?? "-", value: filing.eventDate, color: colors.textDim };
211
+ return { text: filing.eventDate ?? MISSING_VALUE, value: filing.eventDate, color: colors.textDim };
208
212
  case "filingDate":
209
213
  return { text: filing.filingDate, value: filing.filingDate, color: colors.textDim };
210
214
  case "thirteenF": {
211
215
  const action = row.thirteenF;
212
- if (!action) return { text: "-", value: null, color: colors.textDim };
216
+ if (!action) return { text: MISSING_VALUE, value: null, color: colors.textDim };
213
217
  return { text: action.label, color: action.value === 0 ? colors.textDim : priceColor(action.value) };
214
218
  }
215
219
  }
@@ -28,11 +28,21 @@ export function classSharesToday(financials: Pick<TickerFinancials, "quote" | "f
28
28
  return count != null && Number.isFinite(count) && count > 0 ? count : null;
29
29
  }
30
30
 
31
+ /** The day `classSharesToday` was counted (YYYY-MM-DD), when it is a dated 10-K or 10-Q cover count; null when undated. */
32
+ export function classSharesAsOf(financials: Pick<TickerFinancials, "quote" | "fundamentals"> | null | undefined): string | null {
33
+ const fundamentals = financials?.fundamentals;
34
+ if (classSharesToday(financials) == null || !fundamentals?.sharesOutstandingAsOf) return null;
35
+ const receipt = fundamentals.shareBasis === "depositary_receipt"
36
+ || fundamentals.isDepositaryReceipt === true
37
+ || financials?.quote?.isDepositaryReceipt === true;
38
+ return receipt ? null : fundamentals.sharesOutstandingAsOf;
39
+ }
40
+
31
41
  export async function loadHolderSnapshot(
32
42
  provider: DataProvider,
33
43
  symbol: string,
34
44
  exchange = "",
35
- ): Promise<{ data: HolderData; marketCap?: number; sharesOutstanding?: number | null }> {
45
+ ): Promise<{ data: HolderData; marketCap?: number; sharesOutstanding?: number | null; sharesOutstandingAsOf?: string | null; price?: number }> {
36
46
  const [data, financials] = await Promise.all([
37
47
  loadHolderData(provider, symbol, exchange),
38
48
  provider.getTickerFinancials(symbol, exchange).catch(logFailure("holders.client", "Read holder reference financials failed", null)),
@@ -42,5 +52,7 @@ export async function loadHolderSnapshot(
42
52
  data,
43
53
  marketCap: holderStakeMarketCap(quote?.marketCap, quote?.currency, holderValueCurrency(data)),
44
54
  sharesOutstanding: classSharesToday(financials),
55
+ sharesOutstandingAsOf: classSharesAsOf(financials),
56
+ ...(quote?.price != null ? { price: quote.price } : {}),
45
57
  };
46
58
  }
@@ -1,9 +1,9 @@
1
1
  import type { HolderData, HolderRecord } from "../../../types/financials";
2
- import { formatCompact, formatPercent, formatPercentRaw } from "../../../utils/format";
2
+ import { formatCompact, MISSING_VALUE } from "../../../utils/format";
3
3
  import type { HolderRow } from "./types";
4
4
 
5
5
  export function formatMoneyCompact(value: number | undefined, currency = "USD"): string {
6
- if (value == null) return "-";
6
+ if (value == null) return MISSING_VALUE;
7
7
  if (currency === "USD") {
8
8
  const sign = value < 0 ? "-" : "";
9
9
  return `${sign}$${formatCompact(Math.abs(value))}`;
@@ -11,11 +11,6 @@ export function formatMoneyCompact(value: number | undefined, currency = "USD"):
11
11
  return `${formatCompact(value)} ${currency}`;
12
12
  }
13
13
 
14
- export function formatMaybePercent(value: number | undefined): string {
15
- if (value == null) return "-";
16
- return Math.abs(value) <= 1 ? formatPercent(value) : formatPercentRaw(value);
17
- }
18
-
19
14
  /**
20
15
  * The currency holder values are in. Gloom Cloud names it when it differs
21
16
  * from the listing's (dollars from 13F filings on a London line); an older
@@ -51,23 +46,39 @@ export function resolveHolderOwnershipPercent(row: Pick<HolderRecord, "percentHe
51
46
  }
52
47
 
53
48
  /**
54
- * A stake or a change in percent (0.59 for 0.59%), as reports carry it. A
55
- * source gives a fraction (0.0059) or, above 1, percent points; the pane reads
56
- * them the same way. Six significant digits drop a source's float noise.
49
+ * A holder's stake or quarter's change in percent, as the reports carry it.
50
+ * Every holder record gives both as a fraction: 0.0059 is a 0.59% stake,
51
+ * 1.086 a position that grew 108.6%, -0.6 one that fell 60%. Six significant
52
+ * digits drop a source's float noise.
57
53
  */
58
- export function holderPercent(value: number | null | undefined): number | null {
59
- if (value == null || !Number.isFinite(value)) return null;
60
- const percent = Math.abs(value) <= 1 ? value * 100 : value;
61
- return Number(percent.toPrecision(6));
54
+ export function holderPercent(fraction: number | null | undefined): number | null {
55
+ if (fraction == null || !Number.isFinite(fraction)) return null;
56
+ return Number((fraction * 100).toPrecision(6));
62
57
  }
63
58
 
64
59
  /** A stake in percent too small for two decimals reads "<0.01%", not a zero. */
65
60
  export function formatPercentHeld(percent: number | null | undefined): string {
66
- if (percent == null) return "-";
61
+ if (percent == null) return MISSING_VALUE;
67
62
  if (percent > 0 && percent < 0.005) return "<0.01%";
68
63
  return `${percent.toFixed(2)}%`;
69
64
  }
70
65
 
66
+ /**
67
+ * A change in percent, signed, to two decimals; from 1000% on to none, so a
68
+ * position that grew tenfold still fits its column.
69
+ */
70
+ export function formatChangePercent(percent: number | null | undefined): string {
71
+ if (percent == null || !Number.isFinite(percent)) return MISSING_VALUE;
72
+ const fixed = Math.abs(percent).toFixed(Math.abs(percent) >= 1000 ? 0 : 2);
73
+ if (!/[1-9]/.test(fixed)) return `${fixed}%`;
74
+ return `${percent > 0 ? "+" : "-"}${fixed}%`;
75
+ }
76
+
77
+ /** A holder record's quarter's change, a fraction, as the pane shows it. */
78
+ export function formatHolderChangePercent(fraction: number | null | undefined): string {
79
+ return formatChangePercent(holderPercent(fraction));
80
+ }
81
+
71
82
  /** A stake too small for two decimals reads "<0.01%", not a zero. */
72
83
  export function formatHolderOwnershipPercent(value: number | undefined): string {
73
84
  return formatPercentHeld(holderPercent(value));
@@ -79,11 +90,11 @@ export function formatHolderOwnershipLine(row: HolderRow, marketCap: number | un
79
90
  }
80
91
 
81
92
  export function formatSignedCompact(value: number | undefined): string {
82
- if (value == null) return "-";
93
+ if (value == null) return MISSING_VALUE;
83
94
  const sign = value > 0 ? "+" : "";
84
95
  return `${sign}${formatCompact(value)}`;
85
96
  }
86
97
 
87
98
  export function displayDate(value: string | undefined): string {
88
- return value?.slice(0, 10) ?? "-";
99
+ return value?.slice(0, 10) ?? MISSING_VALUE;
89
100
  }
@@ -10,7 +10,7 @@ import type { HolderData } from "../../../types/financials";
10
10
  import { SEC_FILINGS } from "../shared/report-freshness";
11
11
  import type { BeneficialOwnersPayload } from "../../../api-client/beneficial-owners";
12
12
  import { fetchBeneficialOwners, type BeneficialOwnersRequest } from "./beneficial-client";
13
- import { resolveHeadlessIssuerListing } from "../shared/headless-market-data";
13
+ import { resolveHeadlessInstrument, resolveHeadlessIssuerListing } from "../shared/headless-market-data";
14
14
  import type { BeneficialColumnId } from "./beneficial-model";
15
15
  import {
16
16
  beneficialCoverageNotices,
@@ -33,6 +33,15 @@ import {
33
33
  holderReportUnits,
34
34
  } from "./report-rows";
35
35
  import { REPORT_ROWS } from "../shared/headless-options";
36
+ import {
37
+ HOLDER_ROWS_MAX,
38
+ indexedHoldersPartialNote,
39
+ indexedHolderUnits,
40
+ indexHolderTicker,
41
+ loadIndexedHolders,
42
+ withIndexedHolders,
43
+ type IndexedHolderList,
44
+ } from "./index-holders";
36
45
 
37
46
  /** The same sort keys order the 13D/13G rows; `value` and `held` are the percent of class. */
38
47
  const BENEFICIAL_SORT_COLUMNS: Record<string, BeneficialColumnId> = {
@@ -50,6 +59,9 @@ interface HolderSnapshot {
50
59
  marketCap?: number;
51
60
  /** Today's shares outstanding, which a 13D/13G percent of class is set against. */
52
61
  sharesOutstanding?: number | null;
62
+ sharesOutstandingAsOf?: string | null;
63
+ /** The latest price, which values the index's holders when the source's rows give none. */
64
+ price?: number;
53
65
  }
54
66
 
55
67
  export interface HoldersHeadlessDependencies {
@@ -63,6 +75,12 @@ export interface HoldersHeadlessDependencies {
63
75
  request: BeneficialOwnersRequest,
64
76
  ctx: HeadlessPaneContext,
65
77
  ): Promise<BeneficialOwnersPayload>;
78
+ /** A US listing's largest `limit` 13F holders from the SEC holder index, as `fn 13F` pages them. */
79
+ loadIndexedHolders(
80
+ ticker: string,
81
+ limit: number,
82
+ ctx: HeadlessPaneContext,
83
+ ): Promise<IndexedHolderList>;
66
84
  }
67
85
 
68
86
  const defaultDependencies: HoldersHeadlessDependencies = {
@@ -75,6 +93,7 @@ const defaultDependencies: HoldersHeadlessDependencies = {
75
93
  client: ctx.apiClient,
76
94
  signal: ctx.signal,
77
95
  }),
96
+ loadIndexedHolders: (ticker, limit, ctx) => loadIndexedHolders(ticker, limit, ctx.signal, ctx.apiClient),
78
97
  };
79
98
 
80
99
  export function createHoldersHeadless(
@@ -108,11 +127,11 @@ export function createHoldersHeadless(
108
127
  key: "limit",
109
128
  shot: REPORT_ROWS,
110
129
  aliases: ["count", "rows"],
111
- description: "Maximum holder rows.",
130
+ description: "Maximum holder rows, largest first. A US listing's 13F holders are every filer fn 13F lists; a listing abroad has only the source's largest few.",
112
131
  type: "integer",
113
132
  defaultValue: 25,
114
133
  minimum: 1,
115
- maximum: 200,
134
+ maximum: HOLDER_ROWS_MAX,
116
135
  },
117
136
  {
118
137
  key: "view",
@@ -171,7 +190,7 @@ export function createHoldersHeadless(
171
190
  sharesOutstanding,
172
191
  });
173
192
  const limited = rows.slice(0, Number(args.options.limit));
174
- const legend = beneficialReportLegend(limited, sharesOutstanding);
193
+ const legend = beneficialReportLegend(limited, sharesOutstanding, snapshot?.sharesOutstandingAsOf);
175
194
  return {
176
195
  columns: beneficialReportColumns(limited),
177
196
  rows: limited,
@@ -187,6 +206,7 @@ export function createHoldersHeadless(
187
206
  asOf: payload.asOf,
188
207
  coverage: payload.coverage,
189
208
  sharesOutstanding,
209
+ ...(snapshot?.sharesOutstandingAsOf ? { sharesOutstandingAsOf: snapshot.sharesOutstandingAsOf } : {}),
190
210
  notices: [
191
211
  [payload.companyName || symbol, ...beneficialListFacts(payload, form, rows.length, history)].join(" · "),
192
212
  ...(legend ? [legend] : []),
@@ -197,7 +217,25 @@ export function createHoldersHeadless(
197
217
  },
198
218
  };
199
219
  }
200
- const { data, marketCap } = await dependencies.loadSnapshot(symbol, args, ctx);
220
+ const limit = Number(args.options.limit);
221
+ // Asked beside the source's list; a listing abroad (named in the key or saved with the ticker),
222
+ // or an index that cannot be read, keeps that list.
223
+ const exchange = (await resolveHeadlessInstrument(ctx, symbol)
224
+ .catch(logFailure("holders.headless", "Resolve the listing's venue for the 13F holder index failed", null)))?.exchange ?? "";
225
+ const indexTicker = indexHolderTicker(symbol, exchange);
226
+ const [snapshot, index] = await Promise.all([
227
+ dependencies.loadSnapshot(symbol, args, ctx),
228
+ indexTicker
229
+ ? dependencies.loadIndexedHolders(indexTicker, limit, ctx).catch(logFailure("holders.headless", "Load 13F holder index failed", null))
230
+ : null,
231
+ ]);
232
+ const { marketCap } = snapshot;
233
+ const indexed = !!index?.rows.length && indexHolderTicker(symbol, exchange, snapshot.data) != null;
234
+ const partialNote = indexed ? indexedHoldersPartialNote(index, limit) : null;
235
+ // Pages hold 25; another order ranks the largest `limit`, not whatever the last page held past them.
236
+ const data = indexed
237
+ ? withIndexedHolders(snapshot.data, indexTicker!, { ...index!, rows: index!.rows.slice(0, limit) }, indexedHolderUnits(snapshot.data, snapshot.price))
238
+ : snapshot.data;
201
239
  const currency = data.currency ?? "USD";
202
240
  // A London line's values can be dollars from the 13F filings; they are labelled and formatted as such.
203
241
  const valueCurrency = holderValueCurrency(data, currency)!;
@@ -206,15 +244,16 @@ export function createHoldersHeadless(
206
244
  direction: args.options.order === "asc" ? "asc" as const : "desc" as const,
207
245
  };
208
246
  const sorted = holderReportRows(data, { marketCap, sort });
209
- const rows = sorted.slice(0, Number(args.options.limit));
247
+ const rows = sorted.slice(0, limit);
210
248
  const total = data.summary?.institutionsCount ?? null;
211
249
  const { notices, valueBasis, positionsBasis, changeReported } = holderReportNotices({
212
- data, requested: symbol, shown: rows, reported: sorted.length, total, sort,
250
+ data, requested: symbol, shown: rows, reported: sorted.length, total, sort, indexed,
213
251
  });
214
252
  return {
215
253
  // A change column that is empty on every row says nothing; the notices explain it once.
216
254
  columns: holderReportColumns(rows, valueCurrency),
217
255
  rows,
256
+ ...(partialNote ? { complete: false, warnings: [partialNote] } : {}),
218
257
  metadata: {
219
258
  symbol: data.symbol || symbol,
220
259
  name: data.name ?? null,
@@ -0,0 +1,264 @@
1
+ import { apiClient } from "../../../api-client";
2
+ import type { HolderData, HolderRecord } from "../../../types/financials";
3
+ import type { TickerHoldings } from "../thirteenf/signals";
4
+ import { logFailure } from "../../../utils/log-failure";
5
+ import { nonUsHolderCaveat } from "./report-header";
6
+
7
+ /**
8
+ * A US listing's 13F holders from the SEC 13F holder index, the list `fn 13F`
9
+ * pages through: every filer that reported the security for the latest
10
+ * quarter, largest first, 25 to a page. HDS shows them in the units of the
11
+ * source's own short list (each position at the latest price, the stake as a
12
+ * share of the class that list divides by), and keeps that short list for a
13
+ * listing abroad and whenever the index cannot be read.
14
+ */
15
+
16
+ /** The most holder rows `fn HDS` and `holders` print. */
17
+ export const HOLDER_ROWS_MAX = 200;
18
+
19
+ /** One filer's position in the security, summed over the ticker's CUSIPs. */
20
+ export interface IndexedHolder {
21
+ cik: string;
22
+ name: string;
23
+ shares: number;
24
+ /** Shares at the prior quarter end: 0 for a new position, undefined when unknown. */
25
+ previousShares?: number;
26
+ }
27
+
28
+ /** The index's holders loaded so far. */
29
+ export interface IndexedHolderList {
30
+ rows: IndexedHolder[];
31
+ /** The report period the positions are as of. */
32
+ period: string;
33
+ /** Every filer that holds the security at the period end. */
34
+ holderCount: number;
35
+ hasMore: boolean;
36
+ nextOffset: number;
37
+ /** A later page failed: the rows are the ones loaded before it, short of the limit asked. */
38
+ partial?: boolean;
39
+ }
40
+
41
+ const usTicker = /^[A-Z0-9]{1,10}(\.[A-Z]{1,2})?$/;
42
+
43
+ /**
44
+ * The ticker to ask the index for, or null when the listing is not a US
45
+ * line: a venue abroad (typed `SAN:EPA` or given apart), another currency,
46
+ * or a home line whose list the service priced from the filings.
47
+ */
48
+ export function indexHolderTicker(
49
+ symbol: string | null | undefined,
50
+ exchange = "",
51
+ data?: Pick<HolderData, "exchange" | "currency" | "valueBasis"> | null,
52
+ ): string | null {
53
+ const [bare = "", typed = ""] = (symbol ?? "").trim().toUpperCase().split(":");
54
+ const ticker = bare.replace(/[/-]/g, ".");
55
+ if (!usTicker.test(ticker)) return null;
56
+ if (nonUsHolderCaveat(typed || exchange, null) != null) return null;
57
+ if (data && (data.valueBasis === "period_end_price" || nonUsHolderCaveat(data.exchange, data.currency ?? "USD") != null)) return null;
58
+ return ticker;
59
+ }
60
+
61
+ /**
62
+ * One page of the index's holders. Rows that exited during the quarter, and
63
+ * option or principal positions, are not holders of the shares; the pages
64
+ * list the period's holders before its exits, so the list ends where the
65
+ * holder count does.
66
+ */
67
+ export function indexedHolderPage(holdings: TickerHoldings): IndexedHolderList {
68
+ const byCik = new Map<string, IndexedHolder & { previousKnown: boolean }>();
69
+ for (const row of holdings.rows) {
70
+ const type = row.type.trim().toUpperCase();
71
+ if (row.action === "exit" || (type && type !== "SH")) continue;
72
+ if (row.shares == null || !(row.shares > 0)) continue;
73
+ const previous = typeof row.previousShares === "number" ? row.previousShares : null;
74
+ const current = byCik.get(row.cik);
75
+ if (!current) {
76
+ byCik.set(row.cik, {
77
+ cik: row.cik,
78
+ name: row.fund,
79
+ shares: row.shares,
80
+ previousShares: previous ?? undefined,
81
+ previousKnown: previous != null,
82
+ });
83
+ continue;
84
+ }
85
+ // Two CUSIPs under one ticker (a re-issued one) are one position.
86
+ current.shares += row.shares;
87
+ current.previousKnown &&= previous != null;
88
+ current.previousShares = current.previousKnown ? (current.previousShares ?? 0) + previous! : undefined;
89
+ }
90
+ return {
91
+ rows: [...byCik.values()].map(({ previousKnown: _known, ...row }) => row),
92
+ period: holdings.period,
93
+ holderCount: holdings.holderCount,
94
+ hasMore: holdings.hasMore && holdings.nextOffset < holdings.holderCount,
95
+ nextOffset: holdings.nextOffset,
96
+ };
97
+ }
98
+
99
+ /** Rows the service gives a page, as `fn 13F` asks for them. */
100
+ const INDEX_PAGE_ROWS = 25;
101
+ /**
102
+ * Pages one list reads at most: twice what the most rows take, for pages
103
+ * whose options and exits leave fewer holders, and never without end.
104
+ */
105
+ const INDEX_PAGES_MAX = Math.ceil(HOLDER_ROWS_MAX / INDEX_PAGE_ROWS) * 2;
106
+
107
+ /** The client the pages come through; headless reports pass their own. */
108
+ export type IndexedHolderClient = Pick<typeof apiClient, "getCloudSec13F">;
109
+
110
+ /** One page of 25, as `fn 13F` asks for it, so the two share the service's copy. */
111
+ export async function loadIndexedHolderPage(
112
+ ticker: string,
113
+ offset: number,
114
+ signal?: AbortSignal,
115
+ client: IndexedHolderClient = apiClient,
116
+ ): Promise<IndexedHolderList> {
117
+ signal?.throwIfAborted();
118
+ const holdings = await client.getCloudSec13F("ticker-holdings", { tickers: ticker, offset, limit: INDEX_PAGE_ROWS }, { signal }) as TickerHoldings;
119
+ signal?.throwIfAborted();
120
+ if (!Array.isArray(holdings?.rows) || typeof holdings.period !== "string") throw new Error(`13F holders of ${ticker} are unreadable`);
121
+ const page = indexedHolderPage(holdings);
122
+ // A page that does not move the offset on ends the list, or it would be asked for again and again.
123
+ return page.nextOffset > offset ? page : { ...page, hasMore: false };
124
+ }
125
+
126
+ /** Later pages after the first; a page of another period starts the list over. */
127
+ function appendIndexedHolders(current: IndexedHolderList, page: IndexedHolderList): IndexedHolderList {
128
+ if (current.period !== page.period) return page;
129
+ const seen = new Set(current.rows.map((row) => row.cik));
130
+ return { ...page, rows: [...current.rows, ...page.rows.filter((row) => !seen.has(row.cik))] };
131
+ }
132
+
133
+ /**
134
+ * The largest `limit` holders, paging as far as that takes, never more than
135
+ * `INDEX_PAGES_MAX` pages. A later page that fails keeps the holders already
136
+ * loaded, marked partial; only a first page that fails leaves the source's list.
137
+ */
138
+ export async function loadIndexedHolders(
139
+ ticker: string,
140
+ limit: number,
141
+ signal?: AbortSignal,
142
+ client: IndexedHolderClient = apiClient,
143
+ ): Promise<IndexedHolderList> {
144
+ let list = await loadIndexedHolderPage(ticker, 0, signal, client);
145
+ for (let pages = 1; list.hasMore && list.rows.length < limit && pages < INDEX_PAGES_MAX; pages += 1) {
146
+ const offset = list.nextOffset;
147
+ let page: IndexedHolderList;
148
+ try {
149
+ page = await loadIndexedHolderPage(ticker, offset, signal, client);
150
+ } catch (error) {
151
+ if (signal?.aborted) throw error;
152
+ logFailure("holders.index", "Read a later page of the 13F holder index failed", null)(error);
153
+ return { ...list, partial: true };
154
+ }
155
+ list = appendIndexedHolders(list, page);
156
+ }
157
+ return list;
158
+ }
159
+
160
+ /** What a list cut short by a failed page says, when it holds fewer rows than were asked for. */
161
+ export function indexedHoldersPartialNote(list: IndexedHolderList | null | undefined, limit: number): string | null {
162
+ if (!list?.partial || list.rows.length >= limit) return null;
163
+ return `13F holders past the largest ${list.rows.length} could not be read this time.`;
164
+ }
165
+
166
+ /** How the source's own rows value and divide a position, which the index's rows take on. */
167
+ export interface IndexedHolderUnits {
168
+ /** The price a position's shares are valued at. */
169
+ price?: number;
170
+ /**
171
+ * The share count a stake is a share of. The source divides by the class
172
+ * the line trades (PBR's receipts stand for the common shares alone), not
173
+ * by every share the company has.
174
+ */
175
+ classShares?: number;
176
+ }
177
+
178
+ function median(values: number[]): number | undefined {
179
+ if (values.length === 0) return undefined;
180
+ const sorted = [...values].sort((left, right) => left - right);
181
+ const middle = Math.floor(sorted.length / 2);
182
+ return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1]! + sorted[middle]!) / 2;
183
+ }
184
+
185
+ /**
186
+ * The units of the source's list: its rows' price (shares times the latest
187
+ * price), else the quote's, and the count its stakes divide by. The stakes
188
+ * are rounded to four places, so the count is taken over all of them, where
189
+ * the largest weigh most.
190
+ */
191
+ export function indexedHolderUnits(data: HolderData | null | undefined, quotePrice?: number | null): IndexedHolderUnits {
192
+ const rows = (data?.holders ?? []).filter((row) => row.ownerType === "institution" && row.shares != null && row.shares > 0);
193
+ const price = median(rows.flatMap((row) => (row.value != null && row.value > 0 ? [row.value / row.shares!] : [])))
194
+ ?? (quotePrice != null && Number.isFinite(quotePrice) && quotePrice > 0 ? quotePrice : undefined);
195
+ const staked = rows.filter((row) => row.percentHeld != null && row.percentHeld > 0);
196
+ const held = staked.reduce((sum, row) => sum + row.percentHeld!, 0);
197
+ const classShares = held > 0 ? staked.reduce((sum, row) => sum + row.shares!, 0) / held : undefined;
198
+ return {
199
+ ...(price != null ? { price } : {}),
200
+ ...(classShares != null && Number.isFinite(classShares) ? { classShares } : {}),
201
+ };
202
+ }
203
+
204
+ /** The source's rows of the period by their shares, where only one row has that many. */
205
+ function sourceRowsByShares(source: readonly HolderRecord[], period: string): Map<number, HolderRecord> {
206
+ const counts = new Map<number, number>();
207
+ for (const row of source) if (row.reportDate === period && row.shares != null) counts.set(row.shares, (counts.get(row.shares) ?? 0) + 1);
208
+ return new Map(source.flatMap((row) => row.reportDate === period && row.shares != null && counts.get(row.shares) === 1 ? [[row.shares, row]] : []));
209
+ }
210
+
211
+ /**
212
+ * The index's filers as holder rows. A filer whose position is exactly one of
213
+ * the source's rows keeps that row's value and stake, so the largest holders
214
+ * read as they did; the others are valued and divided in the same units.
215
+ */
216
+ function indexedHolderRecords(
217
+ rows: readonly IndexedHolder[],
218
+ period: string,
219
+ units: IndexedHolderUnits,
220
+ source: readonly HolderRecord[] = [],
221
+ ): HolderRecord[] {
222
+ const known = sourceRowsByShares(source, period);
223
+ return rows.map((row) => {
224
+ const change = row.previousShares == null ? undefined : row.shares - row.previousShares;
225
+ const same = known.get(row.shares);
226
+ const value = same?.value ?? (units.price != null ? Math.round(row.shares * units.price) : undefined);
227
+ const percentHeld = same?.percentHeld ?? (units.classShares != null ? row.shares / units.classShares : undefined);
228
+ return {
229
+ ownerType: "institution",
230
+ // The source's spelling of the same holder, not the filer's capitals.
231
+ name: same?.name ?? row.name,
232
+ cik: row.cik,
233
+ reportDate: period,
234
+ shares: row.shares,
235
+ ...(value != null ? { value } : {}),
236
+ ...(percentHeld != null ? { percentHeld } : {}),
237
+ ...(change != null ? { changeShares: change } : {}),
238
+ // A fraction of the prior position, as every holder record carries it; a new one has none.
239
+ ...(change != null && row.previousShares! > 0
240
+ ? { changePercent: Math.round((change / row.previousShares!) * 1e6) / 1e6 }
241
+ : {}),
242
+ };
243
+ });
244
+ }
245
+
246
+ /**
247
+ * The holder list with the index's filers in place of the source's few: the
248
+ * listing's facts and units as the source gave them, the index's period and
249
+ * count.
250
+ */
251
+ export function withIndexedHolders(
252
+ data: HolderData | null | undefined,
253
+ symbol: string,
254
+ list: IndexedHolderList,
255
+ units: IndexedHolderUnits,
256
+ ): HolderData {
257
+ return {
258
+ ...(data ?? { symbol, currency: "USD" }),
259
+ asOf: list.period,
260
+ holders: indexedHolderRecords(list.rows, list.period, units, data?.holders),
261
+ summary: { ...data?.summary, institutionsCount: list.holderCount },
262
+ ...(units.price != null ? { valueBasis: "latest_price" as const } : {}),
263
+ };
264
+ }