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
@@ -16,6 +16,7 @@ import {
16
16
  import { colors, priceColor } from "../../../../theme/colors";
17
17
  import { fiscalYearEndMonth } from "../../../../utils/fiscal-period";
18
18
  import { padTo } from "../../../../utils/format";
19
+ import { filledPeriodsNote, stalePeriodNote } from "../../../../utils/financial-statements";
19
20
  import {
20
21
  FINANCIAL_COL_W,
21
22
  FINANCIAL_LABEL_W,
@@ -29,6 +30,8 @@ import {
29
30
  formatFinancialCell,
30
31
  financialStatementCurrency,
31
32
  financialStatementLimitations,
33
+ financialStatementPeriods,
34
+ financialSubTabFields,
32
35
  formatFinancialValue,
33
36
  latestFinancialPeriodEnd,
34
37
  resolveFinancialPeriod,
@@ -51,9 +54,12 @@ import {
51
54
  ratioPeriodEnd,
52
55
  ratioPeriods,
53
56
  resolveFinancialSectionKey,
57
+ visibleRatios,
54
58
  type RatioAmount,
55
59
  } from "./ratios";
56
60
  import { PeriodEndHistoryLoader, RatioTable, ratioMetricColumn, type PeriodEndHistoryState, type RatioTableColumn } from "./ratio-table";
61
+ import { latestBalanceSheetDate, useOfferingNote } from "./offerings";
62
+ import { useBoundTicker } from "../../shared/ticker-request";
57
63
  import { createValuationCurrencyContext } from "../../../../time-series/valuation-currency";
58
64
 
59
65
  const RATIOS_SEGMENT = "ratios";
@@ -127,9 +133,11 @@ export function ResolvedFinancialsTab({
127
133
  const ratioTab = section.kind === "ratio" ? section.tab : null;
128
134
  // A ratio tab builds its own rows; the statement rows below idle on Income.
129
135
  const subTab = section.kind === "statement" ? section.tab : FINANCIAL_SUB_TABS[0]!;
136
+ // A ratio read over one quarter is not on the annual view, so its state does not count there.
137
+ const quarterlyView = resolveFinancialPeriod(period, hasAnnualStatements, hasQuarterlyStatements) === "quarterly";
130
138
  const currentGroupIds = useMemo(
131
- () => ratioTab ? ratioTab.ratios.map((ratio) => ratio.id) : collectGroupIds(subTab.rows),
132
- [ratioTab, subTab],
139
+ () => ratioTab ? visibleRatios(ratioTab, quarterlyView).map((ratio) => ratio.id) : collectGroupIds(subTab.rows),
140
+ [quarterlyView, ratioTab, subTab],
133
141
  );
134
142
  const hasCollapsedCurrentGroup = currentGroupIds.some((id) => collapsedGroups.has(id));
135
143
  const hasExpandedCurrentGroup = currentGroupIds.some((id) => !collapsedGroups.has(id));
@@ -426,20 +434,38 @@ export function ResolvedFinancialsTab({
426
434
  return (close === undefined ? null : currencies?.priceInStatementUnits(statement, close)) ?? "no-price";
427
435
  };
428
436
  const expanded = new Set(ratioTab.ratios.map((ratio) => ratio.id).filter((id) => !collapsedGroups.has(id)));
429
- return buildRatioTableModel(ratioTab, ratioPeriods(displayStatements, openings, resolvedPeriod, price, { annual: annualStatements, quarterly: quarterlyStatements }), expanded);
437
+ return buildRatioTableModel(ratioTab, ratioPeriods(displayStatements, openings, resolvedPeriod, price, { annual: annualStatements, quarterly: quarterlyStatements }), expanded, financials?.profile);
430
438
  }, [
431
439
  annualStatements, collapsedGroups, currencies, displayStatements, history.data, history.error, history.loading,
432
- isValuation, quarterlyStatements, ratioTab, resolvedPeriod,
440
+ isValuation, quarterlyStatements, ratioTab, resolvedPeriod, financials?.profile,
433
441
  ]);
434
442
  const ratioColumns = useMemo<RatioTableColumn[]>(() => [
435
443
  ratioMetricColumn(),
436
444
  ...columns.flatMap((column, index) => column.kind === "statement" ? [{ ...column, index: index - 1 }] : []),
437
445
  ], [columns]);
438
446
 
447
+ // The Balance Sheet and Liquidity show cash, which an offering filed since the latest balance sheet is not in yet.
448
+ const { symbol: boundSymbol, exchange: boundExchange } = useBoundTicker();
449
+ const offeringNote = useOfferingNote(boundSymbol, boundExchange, latestBalanceSheetDate(financials),
450
+ !!financials && (section.key === "balance" || section.key === "liquidity"));
451
+
452
+ // A latest period over 15 months old says how old it is, beside the data's other limits.
453
+ const stalePeriod = useMemo(
454
+ () => stalePeriodNote(financialStatementPeriods(displayStatements, subTab)),
455
+ [displayStatements, subTab],
456
+ );
457
+ // Years filled from the listing's exchange, with the lines this table shows.
458
+ const filledPeriods = useMemo(
459
+ () => filledPeriodsNote(displayStatements, ratioTab ? undefined : financialSubTabFields(subTab)),
460
+ [displayStatements, ratioTab, subTab],
461
+ );
439
462
  usePaneNoticeFooter({
440
463
  registrationId: "financials-notices",
441
464
  notices: [
465
+ ...(stalePeriod ? [stalePeriod] : []),
466
+ ...(filledPeriods ? [filledPeriods] : []),
442
467
  ...financialStatementLimitations(financials),
468
+ ...(offeringNote ? [offeringNote] : []),
443
469
  ...(isValuation && history.error && !history.data ? ["Period-end prices are unavailable, so valuation ratios are too."] : []),
444
470
  ...(isValuation ? [currencies?.warning(displayStatements) ?? ""] : []),
445
471
  ],
@@ -3,6 +3,16 @@ import { FINANCIAL_PERIOD_OPTION, HISTORY_RANGE_VALUES } from "../shared/headles
3
3
  import { historyIntervalsByRange } from "../../../cli/history-rows";
4
4
  import { HISTORY_DEFAULT_RANGE } from "./data-panes/history-bars";
5
5
  import { RETURN_INTERVAL_VALUES, RETURN_RANGES } from "./data-panes/returns-model";
6
+ import { PRICE_WINDOW_FROM_HELP, PRICE_WINDOW_TO_HELP } from "../../../utils/price-window";
7
+ import type { HeadlessPaneOptionDef } from "../../../types/headless";
8
+
9
+ /** `--from 2007 --to 2009`: the report's bars for those dates. The pane keeps its range, so a capture refuses them. */
10
+ const WINDOW_OPTIONS: HeadlessPaneOptionDef[] = [
11
+ { key: "from", type: "string", placeholder: "year|date", description: PRICE_WINDOW_FROM_HELP, example: "--from 2007 --to 2009",
12
+ shot: { reportOnly: "reads the report's bars for those dates" }, replaces: ["range"] },
13
+ { key: "to", type: "string", placeholder: "year|date", description: PRICE_WINDOW_TO_HELP,
14
+ shot: { reportOnly: "reads the report's bars for those dates" } },
15
+ ];
6
16
 
7
17
  type PaneSchema = Pick<HeadlessPaneDefinition, "argument" | "options" | "discovery">;
8
18
 
@@ -60,10 +70,11 @@ export const paneSchemas = {
60
70
  defaultValue: HISTORY_DEFAULT_RANGE,
61
71
  pluginState: { pluginId: "ticker-research" },
62
72
  },
73
+ ...WINDOW_OPTIONS,
63
74
  ],
64
75
  discovery: {
65
76
  id: "historical-prices",
66
- aliases: ["historical prices", "price history", "ohlcv", "daily prices"],
77
+ aliases: ["historical prices", "price history", "ohlcv", "daily prices", "max drawdown"],
67
78
  screenshotReadiness: "partial",
68
79
  },
69
80
  },
@@ -88,10 +99,11 @@ export const paneSchemas = {
88
99
  defaultValue: "1h",
89
100
  pluginState: { pluginId: "ticker-research" },
90
101
  },
102
+ ...WINDOW_OPTIONS,
91
103
  ],
92
104
  discovery: {
93
105
  id: "returns",
94
- aliases: ["returns", "interval returns", "cumulative return", "performance"],
106
+ aliases: ["returns", "interval returns", "cumulative return", "performance", "max drawdown"],
95
107
  // A capture is read from the rendered table, as before the report existed.
96
108
  screenshotReadiness: "live-dom",
97
109
  },
@@ -1,20 +1,23 @@
1
- import { FINANCIAL_VINTAGE_NOTICE, statementHistoryNotes } from "../../../utils/financial-statements";
1
+ import { FINANCIAL_VINTAGE_NOTICE, filledPeriodsNote, stalePeriodNote, statementHistoryNotes } from "../../../utils/financial-statements";
2
2
  import { hasValidQuoteObservationTime } from "../../../market-data/quotes/freshness";
3
3
  import { EXTENDED_SESSION_LABELS, getQuoteSessionFields, quoteHeadlineTime, type ExtendedSession } from "../../../market-data/market/status";
4
- import type { HeadlessPaneColumn, HeadlessPaneDefinition } from "../../../types/headless";
4
+ import type { HeadlessPaneColumn, HeadlessPaneDefinition, HeadlessPaneFreshness, HeadlessPaneOptionValues } from "../../../types/headless";
5
5
  import type { TimeRange } from "../../../time-series/range";
6
6
  import { formatNumber, formatPercentRaw } from "../../../utils/format";
7
- import { formatMarketPrice, formatMarketPriceWithCurrency, formatPriceObservation, withCurrencyMinorDigits, type MarketFormatOptions } from "../../../market-data/market/format";
7
+ import { formatMarketPrice, formatMarketPriceWithCurrency, formatPriceObservation, quoteFormatOptions, withCurrencyMinorDigits, type MarketFormatOptions } from "../../../market-data/market/format";
8
8
  import {
9
9
  MISSING_VOLUME_TEXT, missingVolumeCount, missingVolumeNotice, pricePointValues, priceHistoryIntegrityNotice,
10
10
  } from "../../../utils/price-history-integrity";
11
11
  import {
12
12
  buildFinancialTableModel, financialStatementCurrency, financialStatementDateNotice, financialStatementLimitations,
13
- formatFinancialHeader, isPerShareFinancialRow, receiptShareCountLabel,
13
+ financialStatementPeriods, financialSubTabFields, formatFinancialHeader, isPerShareFinancialRow, receiptShareCountLabel,
14
14
  } from "./financials/model";
15
15
  import { adrRatioText } from "../../../utils/depositary-receipt";
16
16
  import { paneSchemas } from "./headless-schema";
17
17
  import { loadPeriodEndHistory } from "./financials/period-end-history";
18
+ import { latestBalanceSheetDate, loadOfferingNote } from "./financials/offerings";
19
+ import { reportsShortTermTotal, runwayMethod } from "../../../utils/cash-runway";
20
+ import { logFailure } from "../../../utils/log-failure";
18
21
  import {
19
22
  RATIO_GAP_TEXT,
20
23
  findRatioTab,
@@ -32,16 +35,46 @@ import {
32
35
  loadHeadlessFinancials, loadHeadlessPriceHistory, loadHeadlessSymbols, resolveHeadlessInstrument,
33
36
  } from "../shared/headless-market-data";
34
37
  import { barHistoryFreshness, quoteFreshnessFields, REPORTED_DATA } from "../shared/report-freshness";
35
- import { cleanFloat32Price, historyPriceDecimals } from "../../../cli/history-rows";
38
+ import {
39
+ BAR_INTERVAL_LABELS, barPriceDecimals, cleanFloat32Price, formatBarPrice, historyAllStart, historyAllStartNote, historyMissingPeriodsNote, historyPriceDecimals,
40
+ } from "../../../cli/history-rows";
41
+ import { formatUtcTime } from "../../../utils/utc-time";
42
+ import { maxDrawdown, maxDrawdownText } from "../../../utils/max-drawdown";
43
+ import { isPastPriceWindow, loadPriceWindowHistory, priceWindowText, readPriceWindow, type PriceWindow } from "../../../utils/price-window";
36
44
  import { historyCoverageNotice } from "../../../sources/history-coverage";
37
45
  import { getChartResolutionLabel, isIntradayResolution, RANGE_HISTORY_RESOLUTION, type ManualChartResolution } from "../../../time-series/resolution";
38
46
  import { DAY_SO_FAR_TEXT, withSessionBar } from "../../../time-series/session-bar";
39
- import { buildReturnRows, closedMarketNote, type ReturnRange } from "./data-panes/returns-model";
47
+ import { buildReturnRows, closedMarketNote, isTodayReturnRow, returnBaseCloseDay, type ReturnRange } from "./data-panes/returns-model";
48
+ import { periodBaseText } from "../../../market-data/market/period-return";
40
49
  import { loadReturnSeries } from "./data-panes/returns-history";
41
50
  import {
42
- closedHistoryBarDay, formingHistoryBar, HISTORY_DEFAULT_RANGE, historyBarDate, historyBarSize, historyDateHeader, isDailyOrLongerBar, type HistoryBarSize,
51
+ closedHistoryBarDay, formingHistoryBar, HISTORY_DEFAULT_RANGE, historyBarDate, historyBarSize, historyBarSizeWord, historyDateHeader, isDailyOrLongerBar,
52
+ type HistoryBarSize,
43
53
  } from "./data-panes/history-bars";
44
54
 
55
+ const optionText = (value: unknown) => typeof value === "string" && value.trim() ? value : undefined;
56
+
57
+ /** The `--from`/`--to` window HP and RETURN read in place of their range; null when neither was given. */
58
+ function readReportWindow(options: HeadlessPaneOptionValues): PriceWindow | null {
59
+ return readPriceWindow(optionText(options.from), optionText(options.to));
60
+ }
61
+
62
+ /** `2007 to 2009` for a report's title, when it reads a window. */
63
+ function reportWindowText(options: HeadlessPaneOptionValues): string | null {
64
+ try {
65
+ const window = readReportWindow(options);
66
+ return window ? priceWindowText(window) : null;
67
+ } catch {
68
+ // Intentional ignore: the load reports a window it cannot read; the title keeps the range.
69
+ return null;
70
+ }
71
+ }
72
+
73
+ /** Bars of a window that closed before today: the history asked for, which no later bar makes stale. */
74
+ function pastWindowFreshness(window: PriceWindow, size: HistoryBarSize, observedKey: string): HeadlessPaneFreshness {
75
+ return { status: "not-a-feed", basis: `${historyBarSizeWord(size)} bars, ${priceWindowText(window)}`, observedKey, oldest: null };
76
+ }
77
+
45
78
  export const financialStatementsHeadless: HeadlessPaneDefinition<"rows"> = {
46
79
  ...paneSchemas["financial-analysis-pane"],
47
80
  shape: "rows",
@@ -76,12 +109,13 @@ export const financialStatementsHeadless: HeadlessPaneDefinition<"rows"> = {
76
109
  : allReceipts
77
110
  ? `Share counts are in ADRs and EPS is per ADR${ratio ? `; ${ratio}` : ""}.`
78
111
  : `Share counts are in ADRs and EPS is per ADR for ${receiptPeriods.join(", ")}${ratio ? ` (${ratio})` : ""}; other periods as reported.`;
79
- const dates = table?.statements.map(({ date, currency, dateSource, providerDate, dateEvidence, availableAt, fieldAvailability, fieldSources, unavailableFields, epsBasis, unavailableEarnings, aggregation, shareBasis }) => ({
112
+ const dates = table?.statements.map(({ date, currency, dateSource, providerDate, dateEvidence, availableAt, fieldAvailability, fieldSources, unavailableFields, epsBasis, unavailableEarnings, aggregation, shareBasis, filledFrom }) => ({
80
113
  date, currency: currency ?? statementCurrency ?? null,
81
114
  shareBasis: shareBasis ?? null,
82
115
  availableAt: availableAt ?? null,
83
116
  fieldAvailability: fieldAvailability ? { ...fieldAvailability } : null,
84
117
  ...(fieldSources ? { fieldSources } : {}),
118
+ ...(filledFrom ? { filledFrom } : {}),
85
119
  ...(unavailableFields ? { unavailableFields } : {}),
86
120
  ...(epsBasis ? { epsBasis } : {}),
87
121
  ...(unavailableEarnings ? { unavailableEarnings } : {}),
@@ -110,11 +144,17 @@ export const financialStatementsHeadless: HeadlessPaneDefinition<"rows"> = {
110
144
  },
111
145
  })),
112
146
  ];
147
+ // The balance sheet's cash, when an offering since is not in it yet.
148
+ const offering = table?.subTab.key === "balance" ? await reportOfferingNote(ctx, symbol, financials) : null;
149
+ // A latest period over 15 months old says how old it is.
150
+ const stale = table ? stalePeriodNote(financialStatementPeriods(table.statements, table.subTab)) : null;
151
+ // Years filled from the listing's exchange, with the lines this table shows.
152
+ const filled = table ? filledPeriodsNote(table.statements, financialSubTabFields(table.subTab)) : null;
113
153
  return {
114
154
  rows, columns, unavailableSymbols: rows.length ? [] : [symbol],
115
155
  ...(!hasRequestedStatements ? { errors: [`${symbol}: No ${requestedPeriod} financial statement coverage.`] } : {}),
116
- // The report closes with how far back its periods go, and how to read further.
117
- notes: statementHistoryNotes(requestedPeriod, dates.map(({ date }) => date), symbol),
156
+ // The report closes with how old its latest period is, how far back its periods go, and how to read further.
157
+ notes: [...stale ? [stale] : [], ...filled ? [filled] : [], ...offering ? [offering] : [], ...statementHistoryNotes(requestedPeriod, dates.map(({ date }) => date), symbol)],
118
158
  metadata: {
119
159
  symbol, name: financials.quote?.name ?? symbol, currency: statementCurrency ?? null, unit: table?.unit ?? null, quoteCurrency: financials.quote?.currency ?? null,
120
160
  statement: table?.subTab.key ?? options.statement, statementLabel: table?.subTab.name ?? null,
@@ -131,6 +171,19 @@ export const financialStatementsHeadless: HeadlessPaneDefinition<"rows"> = {
131
171
 
132
172
  const reportAmount = (amount: RatioAmount) => (typeof amount === "number" ? amount : null);
133
173
 
174
+ /** The note that an offering filed after the latest balance sheet is not in its cash yet; a failed read leaves it out. */
175
+ async function reportOfferingNote(
176
+ ctx: Parameters<typeof financialStatementsHeadless.load>[1],
177
+ symbol: string,
178
+ financials: Awaited<ReturnType<typeof loadHeadlessFinancials>>,
179
+ ): Promise<string | null> {
180
+ const periodEnd = latestBalanceSheetDate(financials);
181
+ if (!periodEnd) return null;
182
+ return resolveHeadlessInstrument(ctx, symbol)
183
+ .then((listing) => loadOfferingNote(ctx.apiClient, listing, periodEnd, ctx.signal))
184
+ .catch(logFailure("ticker-detail.headless", "Reading the offering filings failed", null));
185
+ }
186
+
134
187
  /** A ratio tab as a report: each ratio, then its inputs, per period. */
135
188
  async function loadRatioReport(
136
189
  ctx: Parameters<typeof financialStatementsHeadless.load>[1],
@@ -181,11 +234,22 @@ async function loadRatioReport(
181
234
  format: (_value: unknown, row: Record<string, unknown>) => (row.cells as Array<{ formatted: string }>)[index]!.formatted,
182
235
  })),
183
236
  ];
237
+ // Liquidity's runway says how it counts months, and that the cash predates an offering since.
238
+ const liquidity = tab.key === "liquidity" && table;
239
+ const runwayShown = liquidity && table.ratios.some((def) => def.format === "months"
240
+ && table.cells.get(def.id)!.some((cell) => typeof cell.value === "number"));
241
+ const offering = liquidity ? await reportOfferingNote(ctx, symbol, financials) : null;
184
242
  return {
185
243
  rows, columns, unavailableSymbols: rows.length ? [] : [symbol],
186
244
  ...(!hasRequestedStatements ? { errors: [`${symbol}: No ${period} financial statement coverage.`] } : {}),
187
245
  ...(tab.key === "valuation" && hasRequestedStatements && !history?.length ? { complete: false } : {}),
188
- notes: statementHistoryNotes(period, dates.map(({ date }) => date), symbol),
246
+ notes: [
247
+ ...[stalePeriodNote(dates.map(({ periodEnd }) => ({ date: periodEnd, lead: true })))].filter((note): note is string => !!note),
248
+ ...[filledPeriodsNote(table?.periods.map(({ statement }) => statement) ?? [])].filter((note): note is string => !!note),
249
+ ...offering ? [offering] : [],
250
+ ...runwayShown ? [runwayMethod(reportsShortTermTotal([...financials.quarterlyStatements, ...financials.annualStatements]))] : [],
251
+ ...statementHistoryNotes(period, dates.map(({ date }) => date), symbol),
252
+ ],
189
253
  metadata: {
190
254
  symbol, name: financials.quote?.name ?? symbol, currency: statementCurrency ?? null,
191
255
  quoteCurrency: financials.quote?.currency ?? null,
@@ -270,14 +334,17 @@ export const quoteComparisonHeadless: HeadlessPaneDefinition<"rows"> = {
270
334
  };
271
335
 
272
336
  /**
273
- * The price columns of HP, which `fn HP` prints and exports with the date column of the bars' size. A bar without
337
+ * The price columns of HP, which `fn HP` prints and exports with the date column of the bars' size. Every price has
338
+ * the table's one decimal count (`decimals`, barPriceDecimals), as `history` and the pane print it; the columns a
339
+ * report declares before it has bars keep every digit the source sent. A bar without
274
340
  * volume in a history that reports it (`volumeMissing`) prints it as missing, never as 0.
275
341
  */
276
- const historyPriceColumns = (volumeMissing: boolean): HeadlessPaneColumn[] => ["open", "high", "low", "close", "volume"].map((key) => ({
342
+ const historyPriceColumns = (volumeMissing: boolean, decimals?: number): HeadlessPaneColumn[] => ["open", "high", "low", "close", "volume"].map((key) => ({
277
343
  key, header: key, align: "right" as const,
278
344
  format: (value: unknown) => value == null || !Number.isFinite(Number(value)) ? key === "volume" && volumeMissing ? MISSING_VOLUME_TEXT : "-"
279
345
  : key === "volume" ? formatNumber(Number(value), 0)
280
- : formatPriceObservation(Number(value), { minimumFractionDigits: 2 }),
346
+ : decimals == null ? formatPriceObservation(Number(value), { minimumFractionDigits: 2 })
347
+ : formatBarPrice(Number(value), decimals),
281
348
  }));
282
349
 
283
350
  /**
@@ -286,7 +353,7 @@ const historyPriceColumns = (volumeMissing: boolean): HeadlessPaneColumn[] => ["
286
353
  * whose period runs on (`2026-10 MTD`); the export keeps each bar's own date
287
354
  * and adds a `Partial` column when one is.
288
355
  */
289
- function historyColumns(size: HistoryBarSize, partial: boolean, text: boolean, volumeMissing = false): HeadlessPaneColumn[] {
356
+ function historyColumns(size: HistoryBarSize, partial: boolean, text: boolean, volumeMissing = false, decimals?: number): HeadlessPaneColumn[] {
290
357
  const daily = isDailyOrLongerBar(size);
291
358
  const date: HeadlessPaneColumn = {
292
359
  key: "date",
@@ -298,33 +365,42 @@ function historyColumns(size: HistoryBarSize, partial: boolean, text: boolean, v
298
365
  const marked: HeadlessPaneColumn[] = partial && !text
299
366
  ? [{ key: "partial", header: "Partial", format: (value) => value === true ? "true" : "" }]
300
367
  : [];
301
- return [date, ...historyPriceColumns(volumeMissing), ...marked];
368
+ return [date, ...historyPriceColumns(volumeMissing, decimals), ...marked];
302
369
  }
303
370
 
304
371
  export const historicalPricesHeadless: HeadlessPaneDefinition<"rows"> = {
305
372
  ...paneSchemas["historical-prices-pane"],
306
373
  shape: "rows",
307
374
  description: "OHLCV bars (date, open, high, low, close, volume) for one ticker over a range: daily to start, weekly for 5Y and monthly for ALL. The newest bar is marked partial while its day, week or month runs on; a day's bar then comes from the live quote.",
308
- describe: ({ symbols, options }) => `Historical Prices | ${symbols[0]} | ${options.range ?? HISTORY_DEFAULT_RANGE}`,
375
+ describe: ({ symbols, options }) => `Historical Prices | ${symbols[0]} | ${reportWindowText(options) ?? options.range ?? HISTORY_DEFAULT_RANGE}`,
309
376
  columns: historyColumns("1d", false, false),
310
377
  async load({ symbols, options }, ctx) {
311
378
  const symbol = symbols[0]!;
312
379
  const range = (options.range ?? HISTORY_DEFAULT_RANGE) as TimeRange;
380
+ // --from 2007 --to 2009 reads those dates' bars in place of the range.
381
+ const window = readReportWindow(options);
382
+ const pastWindow = !!window && isPastPriceWindow(window);
313
383
  // A range of daily or longer bars reaches into the session now trading, whose bar is the quote's (withSessionBar).
314
384
  const { symbol: listing, exchange } = await resolveHeadlessInstrument(ctx, symbol);
315
385
  const [loaded, quote] = await Promise.all([
316
- loadHeadlessPriceHistory(ctx, symbol, range),
317
- isIntradayResolution(RANGE_HISTORY_RESOLUTION[range]) ? null : ctx.marketData.getQuote(listing, exchange ?? "").catch(() => null),
386
+ window ? loadPriceWindowHistory(ctx.marketData, listing, exchange ?? "", window).then((result) => result.points)
387
+ : loadHeadlessPriceHistory(ctx, symbol, range),
388
+ pastWindow || (!window && isIntradayResolution(RANGE_HISTORY_RESOLUTION[range])) ? null
389
+ : ctx.marketData.getQuote(listing, exchange ?? "").catch(() => null),
318
390
  ]);
319
391
  // The venue whose sessions say whether a day, week or month is still running: the key's, or for a bare symbol its quote's.
320
392
  const venue = exchange || quote?.listingExchangeName || quote?.exchangeName || undefined;
321
393
  const now = Date.now();
322
394
  const points = withSessionBar(loaded, quote, { now, venue });
395
+ // Providers serve float32 prices (4013.39990234 for 4013.4): the rows hold the decimal each is, as `history` does.
396
+ const clean = (value: number | null) => value == null ? null : cleanFloat32Price(value);
323
397
  const rows = points.map((point) => {
324
398
  const date = new Date(point.date);
399
+ const values = pricePointValues(point);
325
400
  return {
326
401
  date: Number.isFinite(date.getTime()) ? date.toISOString() : String(point.date),
327
- ...pricePointValues(point),
402
+ open: clean(values.open), high: clean(values.high), low: clean(values.low), close: clean(values.close), volume: values.volume,
403
+ ...(values.integrity ? { integrity: values.integrity } : {}),
328
404
  ...(point.partial ? { partial: true } : {}),
329
405
  // A coin's day Gloom Cloud rebuilt from hourly bars has no volume of its own, as `history` marks it.
330
406
  ...(point.filled ? { filled: true } : {}),
@@ -336,28 +412,45 @@ export const historicalPricesHeadless: HeadlessPaneDefinition<"rows"> = {
336
412
  const forming = formingHistoryBar(size, rows.at(-1)?.date, venue, now);
337
413
  // A complete one is dated by the day its last session closed, the day its close is from.
338
414
  const closedDay = closedHistoryBarDay(size, rows.at(-1)?.date, venue, now);
415
+ // A daily bar of a session still trading is as of its listing's latest quote, never its midnight.
416
+ const quotedAt = size === "1d" && !closedDay && rows.length && quote && Number.isFinite(quote.lastUpdated)
417
+ && quote.lastUpdated >= Date.parse(`${rows.at(-1)!.date.slice(0, 10)}T00:00:00Z`) ? new Date(quote.lastUpdated).toISOString() : null;
339
418
  const shown = forming ? [...rows.slice(0, -1), { ...rows.at(-1)!, partial: true }] : rows;
419
+ // One decimal count for the table, by the instrument's display rules when the quote names its kind.
420
+ const decimals = barPriceDecimals(rows, quoteFormatOptions(quote).assetCategory);
340
421
  const marked = shown.some((row) => row.partial === true);
341
422
  const volumeMissing = missingVolumeCount(shown);
342
423
  const volumeNote = missingVolumeNotice(volumeMissing, shown.length);
424
+ // Every month or week without a bar is named, and ALL says where the source's bars start (BTC-USD's in 2014-09).
425
+ const interval = size === "intraday" ? null : size;
426
+ const gapNote = historyMissingPeriodsNote(rows.map((row) => Date.parse(row.date)), interval);
427
+ const allStart = window ? null : historyAllStart(range, interval, rows[0]?.date, now);
428
+ const notes = [allStart ? historyAllStartNote(allStart) : null, gapNote, volumeNote].filter((note): note is string => note != null);
343
429
  // The day's bar built from the quote is not a close; a coin's day in progress, as its source flags it, keeps its line.
344
430
  const dayToDate = points !== loaded && size === "1d" && shown.at(-1)?.partial === true;
345
431
  // A bar history: dated by its last bar, stale once bars of its size stop arriving.
346
- const freshness = {
432
+ const freshness = pastWindow ? pastWindowFreshness(window, size, "date") : {
347
433
  ...barHistoryFreshness(isDailyOrLongerBar(size) ? size : null),
348
434
  observedKey: "date", oldest: null,
349
- ...(forming ? { periodToDate: forming } : closedDay ? { asOf: closedDay } : {}),
435
+ ...(forming ? { periodToDate: forming } : closedDay ? { asOf: closedDay } : quotedAt ? { asOf: quotedAt } : {}),
350
436
  ...(dayToDate ? { basis: "daily bars", note: `the newest bar is ${DAY_SO_FAR_TEXT}`, ...(quote ? { asOf: new Date(quote.lastUpdated).toISOString() } : {}) } : {}),
351
437
  };
438
+ // The largest fall from a close to a later one in the bars shown, said under the title.
439
+ const drawdown = maxDrawdown(shown);
440
+ const drawdownLine = drawdown ? maxDrawdownText(drawdown, { basis: `${historyBarSizeWord(size)} closes`, price: (value) => formatBarPrice(value, decimals),
441
+ date: (value) => isDailyOrLongerBar(size) ? value.slice(0, 10) : formatUtcTime(value) }) : null;
442
+ const reportNotices = [drawdownLine, notice].filter((line): line is string => line != null);
352
443
  return {
353
444
  rows: shown,
354
- columns: historyColumns(size, marked, false),
355
- textColumns: historyColumns(size, marked, true, volumeMissing > 0),
445
+ columns: historyColumns(size, marked, false, false, decimals),
446
+ textColumns: historyColumns(size, marked, true, volumeMissing > 0, decimals),
356
447
  freshness,
357
- ...(volumeNote ? { notes: [volumeNote] } : {}),
448
+ ...(notes.length > 0 ? { notes } : {}),
358
449
  ...(notice ? { complete: false } : {}),
359
450
  unavailableSymbols: rows.some((row) => row.close !== null) ? [] : [symbol],
360
- metadata: { symbol, range, ...(size === "intraday" ? {} : { interval: size }), ...(notice ? { notices: [notice] } : {}) },
451
+ metadata: { symbol, range: window ? null : range, ...(window ? { requestedWindow: window } : {}), ...(size === "intraday" ? {} : { interval: size }),
452
+ ...(allStart ? { sourceStart: allStart } : {}), maxDrawdown: drawdown,
453
+ ...(reportNotices.length ? { notices: reportNotices } : {}) },
361
454
  };
362
455
  },
363
456
  };
@@ -372,17 +465,24 @@ export const returnsHeadless: HeadlessPaneDefinition<"rows"> = {
372
465
  ...paneSchemas["returns-pane"],
373
466
  shape: "rows",
374
467
  description: "Interval and cumulative price returns of one ticker's bars over a range: each bar's close, its move from the bar before, and its move from the bar before the window.",
375
- describe: ({ symbols, options }) => `Returns | ${symbols[0]} | ${options.range ?? "5D"} | ${options.interval ?? "1h"}`,
468
+ describe: ({ symbols, options }) => `Returns | ${symbols[0]} | ${reportWindowText(options) ?? options.range ?? "5D"} | ${options.interval ?? "1h"}`,
376
469
  async load({ symbols, options }, ctx) {
377
470
  const key = symbols[0]!;
378
471
  const { symbol, exchange } = await resolveHeadlessInstrument(ctx, key);
379
472
  const range = (options.range ?? "5D") as ReturnRange;
380
473
  const requested = (options.interval ?? "1h") as ManualChartResolution;
474
+ // --from 2007 --to 2009 measures those dates' returns in place of the range.
475
+ const window = readReportWindow(options);
476
+ const pastWindow = !!window && isPastPriceWindow(window);
381
477
  const support = await Promise.resolve(ctx.marketData.getChartResolutionSupport?.(symbol, exchange ?? "") ?? []).catch(() => []);
478
+ const now = Date.now();
382
479
  const series = await loadReturnSeries(ctx.marketData, {
383
- symbol, exchange: exchange ?? "", range, resolution: requested, support, now: Date.now(), forceRefresh: ctx.refresh,
480
+ symbol, exchange: exchange ?? "", range, resolution: requested, support, now, forceRefresh: ctx.refresh, window,
384
481
  });
385
482
  const returns = buildReturnRows(series.points, series.visibleFrom, series.visibleTo).reverse();
483
+ const venue = series.venue || undefined;
484
+ // The close every total is measured from, which the report names: `Totals from Mon 21 Sep close.`
485
+ const baseDay = returns.length ? returnBaseCloseDay(series.points, series.visibleFrom, series.resolution, venue, now) : null;
386
486
  const decimals = historyPriceDecimals(returns.flatMap((row) => row.price === null ? [] : [{
387
487
  open: null, high: null, low: null, close: cleanFloat32Price(row.price),
388
488
  }]));
@@ -400,10 +500,16 @@ export const returnsHeadless: HeadlessPaneDefinition<"rows"> = {
400
500
  ...(row.inconsistent ? { inconsistent: true } : {}),
401
501
  }));
402
502
  // A weekly or monthly bar whose period runs on is the period so far: marked partial, and dated by how far it runs.
403
- const forming = formingHistoryBar(series.resolution, unmarked.at(-1)?.time, series.venue || undefined, Date.now());
404
- const closedDay = closedHistoryBarDay(series.resolution, unmarked.at(-1)?.time, series.venue || undefined, Date.now());
405
- const rows = forming ? [...unmarked.slice(0, -1), { ...unmarked.at(-1)!, partial: true }] : unmarked;
503
+ const forming = formingHistoryBar(series.resolution, unmarked.at(-1)?.time, venue, now);
504
+ const closedDay = closedHistoryBarDay(series.resolution, unmarked.at(-1)?.time, venue, now);
505
+ // Today's daily bar is the session still trading, not a close: marked partial (DTD), as `history` marks it.
506
+ const dayToDate = isTodayReturnRow(returns.at(-1), series.resolution, venue, now);
507
+ const rows = forming || dayToDate ? [...unmarked.slice(0, -1), { ...unmarked.at(-1)!, partial: true }] : unmarked;
406
508
  const price = (value: unknown) => typeof value === "number" && Number.isFinite(value) ? value.toFixed(decimals) : "-";
509
+ // The largest fall from a close to a later one in the window, said under the title.
510
+ const drawdown = maxDrawdown(unmarked.map((row) => ({ date: row.time, close: row.close })));
511
+ const maxDrawdownLine = drawdown ? maxDrawdownText(drawdown, { basis: `${BAR_INTERVAL_LABELS[series.resolution]} closes`, price,
512
+ date: (value) => intraday ? formatUtcTime(value) : value.slice(0, 10) }) : null;
407
513
  const figures: HeadlessPaneColumn[] = [
408
514
  { key: "close", header: "Price", align: "right", format: price },
409
515
  { key: "intervalChange", header: "Int $", align: "right", format: price },
@@ -422,13 +528,15 @@ export const returnsHeadless: HeadlessPaneDefinition<"rows"> = {
422
528
  const columns: HeadlessPaneColumn[] = [
423
529
  timeColumn(false),
424
530
  ...figures,
425
- ...forming ? [{ key: "partial", header: "Partial", format: (value: unknown) => value === true ? "true" : "" }] : [],
531
+ ...forming || dayToDate ? [{ key: "partial", header: "Partial", format: (value: unknown) => value === true ? "true" : "" }] : [],
426
532
  ];
427
533
  const textColumns: HeadlessPaneColumn[] = [timeColumn(true), ...figures];
428
534
  // An interval the range is too long for is served in the nearest longer bar; say so rather than switch silently.
429
535
  const notices = [
536
+ maxDrawdownLine,
537
+ baseDay ? `Totals ${periodBaseText(baseDay, now)}.` : null,
430
538
  series.resolution !== requested
431
- ? `${getChartResolutionLabel(requested)} bars do not reach back ${range}; these are ${getChartResolutionLabel(series.resolution)} bars.`
539
+ ? `${getChartResolutionLabel(requested)} bars do not ${window ? `cover ${priceWindowText(window)}` : `reach back ${range}`}; these are ${getChartResolutionLabel(series.resolution)} bars.`
432
540
  : null,
433
541
  historyCoverageNotice(series.coverageStart, series.visibleFrom),
434
542
  priceHistoryIntegrityNotice(rows.filter((row) => row.inconsistent).length) ?? null,
@@ -439,7 +547,7 @@ export const returnsHeadless: HeadlessPaneDefinition<"rows"> = {
439
547
  textColumns,
440
548
  unavailableSymbols: rows.length ? [] : [key],
441
549
  ...(rows.length ? {} : { errors: [`${key}: No bars in this window.`] }),
442
- freshness: {
550
+ freshness: pastWindow ? pastWindowFreshness(window, series.resolution, "time") : {
443
551
  ...barHistoryFreshness(intraday ? null : series.resolution),
444
552
  observedKey: "time",
445
553
  oldest: null,
@@ -447,15 +555,20 @@ export const returnsHeadless: HeadlessPaneDefinition<"rows"> = {
447
555
  ...(series.venue ? { cadenceExchange: series.venue } : {}),
448
556
  // The window ends at the last session while the market is shut, which the status line says.
449
557
  ...(series.lastSession ? { note: closedMarketNote(series.lastSession, series.visibleTo) } : {}),
558
+ ...(dayToDate ? { basis: "daily bars", note: `the newest bar is ${DAY_SO_FAR_TEXT}` } : {}),
450
559
  },
451
560
  metadata: {
452
561
  symbol: key,
453
- range,
562
+ range: window ? null : range,
563
+ // The dates asked for, as history and HP carry them; `window` below is the span of the bars served.
564
+ ...(window ? { requestedWindow: window } : {}),
454
565
  interval: series.resolution,
455
566
  requestedInterval: requested,
456
567
  window: { after: new Date(series.visibleFrom).toISOString(), through: new Date(series.visibleTo).toISOString() },
568
+ ...(baseDay ? { baseDay } : {}),
457
569
  ...(series.lastSession ? { marketClosed: true, lastSession: series.lastSession } : {}),
458
570
  basis: "Price returns of bar closes; dividends are not included",
571
+ maxDrawdown: drawdown,
459
572
  ...(notices.length ? { notices } : {}),
460
573
  },
461
574
  };
@@ -9,6 +9,7 @@ import { HistoricalPricesPane } from "./data-panes/historical-prices";
9
9
  import { ReturnsPane } from "./data-panes/returns-pane";
10
10
  import { TickerResearchPane } from "./pane";
11
11
  import { futuresContractCache } from "./overview/futures-contract";
12
+ import { offeringFilingsCache } from "./financials/offerings";
12
13
  import { TICKER_RESEARCH_BUILTIN_TABS } from "./research-tabs";
13
14
  import { QuoteMonitorPane } from "./quote-monitor";
14
15
  import { financialStatementsHeadless, historicalPricesHeadless, quoteComparisonHeadless, returnsHeadless } from "./headless";
@@ -19,6 +20,10 @@ import {
19
20
  getTickerResearchPaneSettings,
20
21
  } from "./settings";
21
22
  import { formatTickerListInput } from "../../../tickers/list";
23
+ import { withCommandTab } from "../shared/command-tab";
24
+ import { buildTickerSurfaceInstanceId } from "../shared/ticker-surface";
25
+ import { adrPairHeadless, ADR_PAIR_KEYWORDS } from "./adr-pair/headless";
26
+ import { ADR_PAIR_TAB_ID, ADR_PAIR_TEMPLATE_ID } from "./adr-pair/model";
22
27
  import {
23
28
  LIVE_STREAMING_QUICK_SETTING,
24
29
  withLiveStreamingSetting,
@@ -27,11 +32,15 @@ import {
27
32
  export const tickerDetailModule: PluginModule = {
28
33
  setup(ctx) {
29
34
  futuresContractCache.attach(ctx.persistence);
35
+ offeringFilingsCache.attach(ctx.persistence);
30
36
  for (const tab of TICKER_RESEARCH_BUILTIN_TABS) {
31
37
  ctx.registerTickerResearchTab(tab);
32
38
  }
33
39
  },
34
- dispose() { futuresContractCache.reset(); },
40
+ dispose() {
41
+ futuresContractCache.reset();
42
+ offeringFilingsCache.reset();
43
+ },
35
44
 
36
45
  panes: [
37
46
  {
@@ -41,6 +50,8 @@ export const tickerDetailModule: PluginModule = {
41
50
  component: TickerResearchPane,
42
51
  defaultPosition: "right",
43
52
  tickerFollower: true,
53
+ // DES and ADR open this pane; ADR's window is named by its params (the tab it asked for), so settings never say whose a window is.
54
+ identitySettings: [],
44
55
  personalData: (context) => {
45
56
  const settings = getTickerResearchPaneSettings(context.settings);
46
57
  const tab = settings.hideTabs ? settings.lockedTabId : context.paneState.activeTabId;
@@ -114,7 +125,7 @@ export const tickerDetailModule: PluginModule = {
114
125
  paneId: TICKER_RESEARCH_PANE_ID,
115
126
  label: "Ticker Research",
116
127
  description: "Open another research pane for the selected ticker or current collection",
117
- keywords: ["new", "ticker", "research", "detail", "pane", "inspector"],
128
+ keywords: ["new", "ticker", "research", "detail", "pane", "inspector", "runway", "cash runway", "burn", "cash burn", "months of cash"],
118
129
  shortcut: { prefix: "T", aliases: ["DES"], argPlaceholder: "ticker", argKind: "ticker" },
119
130
  canCreate: (context) => context.activeTicker !== null || context.activeCollectionId !== null,
120
131
  createInstance: (context) => (
@@ -134,6 +145,27 @@ export const tickerDetailModule: PluginModule = {
134
145
  : null,
135
146
  },
136
147
  },
148
+ {
149
+ // DES on its ADR vs Home tab: no pane of its own.
150
+ ...withCommandTab({
151
+ id: ADR_PAIR_TEMPLATE_ID,
152
+ paneId: TICKER_RESEARCH_PANE_ID,
153
+ label: "ADR vs Home",
154
+ description: "A depositary receipt beside its home listing: the ratio, both prices, the dollar rate they imply (the CCL rate for an Argentine pair), spot, and the receipt's premium or discount.",
155
+ keywords: [...ADR_PAIR_KEYWORDS],
156
+ shortcut: { prefix: "ADR", argPlaceholder: "ticker", argKind: "ticker" },
157
+ canCreate: (context, options) => normalizeTickerInput(context.activeTicker, options?.arg) !== null,
158
+ // One window a listing: ADR again focuses it and brings its tab back.
159
+ createInstance: (context, options) => {
160
+ const symbol = options?.symbol?.trim().toUpperCase() || normalizeTickerInput(context.activeTicker, options?.arg);
161
+ return symbol ? {
162
+ instanceId: buildTickerSurfaceInstanceId(TICKER_RESEARCH_PANE_ID, symbol, "ADR"),
163
+ title: symbol, binding: { kind: "fixed", symbol }, placement: "floating",
164
+ } : null;
165
+ },
166
+ }, ADR_PAIR_TAB_ID),
167
+ headless: adrPairHeadless,
168
+ },
137
169
  {
138
170
  id: "quote-monitor-pane",
139
171
  headless: quoteComparisonHeadless,
@@ -180,7 +212,7 @@ export const tickerDetailModule: PluginModule = {
180
212
  paneId: "returns",
181
213
  label: "Returns",
182
214
  description: "Inspect interval and cumulative price returns over a selectable range and granularity.",
183
- keywords: ["returns", "return", "performance", "change", "interval", "granularity"],
215
+ keywords: ["returns", "return", "performance", "change", "interval", "granularity", "drawdown", "max drawdown", "peak to trough"],
184
216
  shortcut: "RETURN",
185
217
  publicShare: true,
186
218
  titlePrefix: "RETURN",
@@ -193,7 +225,7 @@ export const tickerDetailModule: PluginModule = {
193
225
  paneId: "historical-prices",
194
226
  label: "Historical Prices",
195
227
  description: "Open a historical OHLCV table for a ticker.",
196
- keywords: ["historical", "prices", "hp", "ohlc", "volume"],
228
+ keywords: ["historical", "prices", "hp", "ohlc", "volume", "drawdown", "max drawdown", "peak to trough"],
197
229
  shortcut: "HP",
198
230
  publicShare: true,
199
231
  }),
@@ -205,7 +237,7 @@ export const tickerDetailModule: PluginModule = {
205
237
  paneId: "financial-analysis",
206
238
  label: "Financial Analysis",
207
239
  description: "Open financial statements for a ticker.",
208
- keywords: ["fa", "financial", "analysis", "statements"],
240
+ keywords: ["fa", "financial", "analysis", "statements", "runway", "cash runway", "burn", "cash burn", "months of cash"],
209
241
  shortcut: "FA",
210
242
  publicShare: true,
211
243
  titlePrefix: "FA",