gloomberb 0.18.0 → 0.18.2

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 (365) hide show
  1. package/package.json +1 -1
  2. package/src/api-client/commodity-balances.ts +6 -0
  3. package/src/api-client/company-kpis.ts +9 -0
  4. package/src/api-client/crypto-markets.ts +9 -0
  5. package/src/api-client/data.ts +6 -5
  6. package/src/api-client/equity-screener.ts +2 -0
  7. package/src/api-client/market-movers.ts +7 -0
  8. package/src/api-client/types.ts +14 -0
  9. package/src/app/pane-runtime/plugin-bindings.ts +3 -1
  10. package/src/app/pane-runtime/ticker-open-runtime.ts +17 -5
  11. package/src/app/runtime/plugin-bindings.ts +6 -2
  12. package/src/brokers/logos.ts +66 -0
  13. package/src/brokers/profile-form.ts +3 -0
  14. package/src/brokers/remote-broker-adapter.ts +13 -3
  15. package/src/capabilities/index.ts +1 -1
  16. package/src/capabilities/service-capabilities.ts +7 -1
  17. package/src/cli/base-converter.ts +60 -18
  18. package/src/cli/commands/fred-series.ts +15 -5
  19. package/src/cli/commands/market.ts +290 -159
  20. package/src/cli/commands/news-search.ts +35 -8
  21. package/src/cli/commands/overview.ts +31 -6
  22. package/src/cli/commands/system.ts +35 -1
  23. package/src/cli/commands/ticker.ts +105 -52
  24. package/src/cli/currency-hints.ts +27 -0
  25. package/src/cli/fx-pair.ts +41 -4
  26. package/src/cli/glossary.ts +57 -4
  27. package/src/cli/helpers.ts +36 -3
  28. package/src/cli/index.ts +4 -1
  29. package/src/cli/known-gaps.ts +37 -1
  30. package/src/cli/listing-arg.ts +37 -2
  31. package/src/cli/pane-functions/catalog.ts +3 -1
  32. package/src/cli/pane-functions/discovery.ts +15 -1
  33. package/src/cli/pane-functions/dom.ts +9 -4
  34. package/src/cli/pane-functions/freshness.ts +4 -4
  35. package/src/cli/pane-functions/function-help.ts +31 -7
  36. package/src/cli/pane-functions/headless.ts +6 -5
  37. package/src/cli/pane-functions/index.ts +3 -2
  38. package/src/cli/pane-functions/lock-note.ts +7 -4
  39. package/src/cli/pane-functions/resolver.ts +2 -1
  40. package/src/cli/quote-answer.ts +179 -0
  41. package/src/cli/series-search.ts +2 -1
  42. package/src/cli/symbol-list.ts +51 -16
  43. package/src/cli/types.ts +4 -0
  44. package/src/components/chart/composite/composite-chart.tsx +22 -7
  45. package/src/components/chart/composite/format.ts +13 -1
  46. package/src/components/chart/composite/level-labels.ts +30 -0
  47. package/src/components/chart/composite/levels.ts +17 -6
  48. package/src/components/chart/composite/panel-surface.tsx +64 -16
  49. package/src/components/chart/composite/price-axis-labels.tsx +2 -1
  50. package/src/components/chart/composite/types.ts +4 -0
  51. package/src/components/command-bar/routes/ticker-search/actions.ts +6 -0
  52. package/src/components/command-bar/workflow/collection-actions.ts +4 -0
  53. package/src/components/index.ts +2 -0
  54. package/src/components/layout/pane/content.tsx +16 -14
  55. package/src/components/layout/pane/footer/index.tsx +22 -3
  56. package/src/components/layout/pane/footer/model.ts +99 -4
  57. package/src/components/layout/pane/header-tabs.tsx +15 -1
  58. package/src/components/onboarding/onboarding-frame.tsx +9 -11
  59. package/src/components/onboarding/use-onboarding-broker-form.ts +5 -2
  60. package/src/components/onboarding/wizard-model.ts +10 -3
  61. package/src/components/onboarding/wizard-positions.ts +8 -0
  62. package/src/components/ui/button.tsx +11 -4
  63. package/src/components/ui/choice-dialog.tsx +8 -5
  64. package/src/components/ui/display.tsx +11 -6
  65. package/src/components/ui/fields.tsx +100 -20
  66. package/src/components/ui/icon.tsx +6 -1
  67. package/src/components/ui/list-row-lines.tsx +87 -0
  68. package/src/components/ui/list-view.tsx +14 -0
  69. package/src/components/ui/logo-mark.tsx +64 -0
  70. package/src/components/ui/number-step.ts +54 -0
  71. package/src/components/ui/select-button.tsx +5 -4
  72. package/src/components/ui/select-field.tsx +3 -3
  73. package/src/components/ui/status.tsx +17 -3
  74. package/src/components/ui/tabs.tsx +9 -1
  75. package/src/components/ui/toggle.tsx +17 -3
  76. package/src/core/state/app/instrument.ts +8 -3
  77. package/src/data/config/store/normalize.ts +4 -1
  78. package/src/data/plugin-cache.ts +32 -6
  79. package/src/docs/snapshot.json +57 -22
  80. package/src/i18n/es.ts +9 -3
  81. package/src/i18n/ja.ts +9 -3
  82. package/src/i18n/ko.ts +9 -3
  83. package/src/i18n/zh-cn.ts +10 -4
  84. package/src/i18n/zh-tw.ts +10 -4
  85. package/src/market-data/commodity-names.ts +80 -0
  86. package/src/market-data/coordinator/auxiliary.ts +3 -1
  87. package/src/market-data/coordinator/chart.ts +3 -1
  88. package/src/market-data/futures-board.ts +38 -1
  89. package/src/market-data/futures-contract.ts +91 -0
  90. package/src/market-data/fx-closes.ts +78 -1
  91. package/src/market-data/market/change-basis.ts +219 -0
  92. package/src/market-data/market/format.ts +28 -12
  93. package/src/market-data/market/freshness.ts +38 -0
  94. package/src/market-data/market/status.ts +55 -9
  95. package/src/market-data/market/year-to-date.ts +46 -0
  96. package/src/market-data/quotes/contributions.ts +12 -0
  97. package/src/market-data/quotes/delisting.ts +34 -0
  98. package/src/market-data/quotes/live-valuation.ts +23 -0
  99. package/src/market-data/quotes/resolution.ts +8 -2
  100. package/src/market-data/tax-equivalent.ts +10 -2
  101. package/src/notifications/app-notifier.ts +2 -2
  102. package/src/notifications/notification-log.ts +8 -6
  103. package/src/plugins/builtin/alerts/cli.ts +26 -18
  104. package/src/plugins/builtin/alerts/headless.ts +1 -1
  105. package/src/plugins/builtin/alerts/index.tsx +13 -4
  106. package/src/plugins/builtin/analytics/index.tsx +1 -1
  107. package/src/plugins/builtin/analytics/risk-client.ts +44 -11
  108. package/src/plugins/builtin/analytics/risk-fx.ts +61 -0
  109. package/src/plugins/builtin/analytics/risk-headless.ts +10 -1
  110. package/src/plugins/builtin/analytics/risk-model.ts +79 -16
  111. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
  112. package/src/plugins/builtin/analytics/risk-test-data.ts +3 -0
  113. package/src/plugins/builtin/attention/trending.tsx +8 -6
  114. package/src/plugins/builtin/backtest/client.ts +5 -2
  115. package/src/plugins/builtin/backtest/window.ts +16 -3
  116. package/src/plugins/builtin/broker-manager/add-flow.tsx +40 -8
  117. package/src/plugins/builtin/broker-manager/detail.tsx +26 -1
  118. package/src/plugins/builtin/broker-manager/index.tsx +20 -9
  119. package/src/plugins/builtin/broker-manager/model.ts +5 -0
  120. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -1
  121. package/src/plugins/builtin/broker-manager/table.ts +5 -1
  122. package/src/plugins/builtin/broker-trading/account-picker.tsx +91 -0
  123. package/src/plugins/builtin/broker-trading/chart-levels.ts +54 -0
  124. package/src/plugins/builtin/broker-trading/command.ts +103 -0
  125. package/src/plugins/builtin/broker-trading/controller.ts +688 -0
  126. package/src/plugins/builtin/broker-trading/dock.tsx +182 -0
  127. package/src/plugins/builtin/broker-trading/headless.ts +76 -0
  128. package/src/plugins/builtin/broker-trading/index.tsx +77 -0
  129. package/src/plugins/builtin/broker-trading/order-feed.ts +383 -0
  130. package/src/plugins/builtin/broker-trading/orders-data.ts +133 -0
  131. package/src/plugins/builtin/broker-trading/orders.tsx +437 -0
  132. package/src/plugins/builtin/broker-trading/overview-orders.tsx +121 -0
  133. package/src/plugins/builtin/broker-trading/pane-model.ts +207 -0
  134. package/src/plugins/builtin/broker-trading/pane.tsx +505 -0
  135. package/src/plugins/builtin/broker-trading/strategy.ts +153 -0
  136. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +117 -0
  137. package/src/plugins/builtin/broker-trading/ticket.tsx +573 -0
  138. package/src/plugins/builtin/buildout/data-runtime.ts +1 -1
  139. package/src/plugins/builtin/buildout/format.ts +1 -0
  140. package/src/plugins/builtin/buildout/model/index.ts +16 -7
  141. package/src/plugins/builtin/buildout/pane/index.tsx +3 -2
  142. package/src/plugins/builtin/buildout/pane/status.tsx +3 -3
  143. package/src/plugins/builtin/chart-composer/cli-options.ts +19 -0
  144. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  145. package/src/plugins/builtin/chart-composer/headless-schema.ts +3 -3
  146. package/src/plugins/builtin/chart-composer/headless.ts +2 -1
  147. package/src/plugins/builtin/chart-composer/option-range.ts +39 -0
  148. package/src/plugins/builtin/chart-composer/pane.tsx +31 -11
  149. package/src/plugins/builtin/chart-composer/presets.ts +2 -2
  150. package/src/plugins/builtin/chart-composer/series-catalog.ts +4 -2
  151. package/src/plugins/builtin/chart-composer/shortcuts.ts +3 -3
  152. package/src/plugins/builtin/chart-composer/viewport-labels.ts +5 -2
  153. package/src/plugins/builtin/chat/index.tsx +1 -1
  154. package/src/plugins/builtin/chat/status-widget.tsx +1 -1
  155. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +6 -1
  156. package/src/plugins/builtin/chat/unread-inbox.ts +1 -1
  157. package/src/plugins/builtin/cloud/team/pane-sections.tsx +10 -3
  158. package/src/plugins/builtin/cloud/team/pane.tsx +30 -9
  159. package/src/plugins/builtin/commodity-balances/client.ts +6 -4
  160. package/src/plugins/builtin/commodity-balances/headless.ts +41 -7
  161. package/src/plugins/builtin/commodity-balances/index.tsx +19 -4
  162. package/src/plugins/builtin/commodity-balances/model.ts +22 -0
  163. package/src/plugins/builtin/commodity-balances/pane.tsx +36 -5
  164. package/src/plugins/builtin/company-kpis/client.ts +3 -2
  165. package/src/plugins/builtin/company-kpis/headless.ts +5 -7
  166. package/src/plugins/builtin/company-kpis/model.ts +85 -2
  167. package/src/plugins/builtin/company-kpis/pane.tsx +26 -12
  168. package/src/plugins/builtin/composite-plugins.ts +3 -2
  169. package/src/plugins/builtin/cot/headless.ts +1 -1
  170. package/src/plugins/builtin/cot/index.tsx +1 -1
  171. package/src/plugins/builtin/cot/model.ts +35 -12
  172. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
  173. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +2 -1
  174. package/src/plugins/builtin/credit-conditions/index.tsx +2 -1
  175. package/src/plugins/builtin/crypto-board/client.ts +33 -2
  176. package/src/plugins/builtin/crypto-board/headless.ts +5 -2
  177. package/src/plugins/builtin/crypto-board/model.ts +28 -8
  178. package/src/plugins/builtin/custom-view/loader.ts +3 -2
  179. package/src/plugins/builtin/custom-view/pane.tsx +5 -4
  180. package/src/plugins/builtin/custom-view/view-spec.ts +1 -0
  181. package/src/plugins/builtin/dividend-yield/headless.ts +30 -8
  182. package/src/plugins/builtin/dividend-yield/provider-client.ts +3 -1
  183. package/src/plugins/builtin/earnings-calls/headless.ts +4 -4
  184. package/src/plugins/builtin/earnings-calls/lock-note.ts +12 -3
  185. package/src/plugins/builtin/econ/calendar-model.ts +38 -2
  186. package/src/plugins/builtin/econ/fred-catalog.ts +6 -2
  187. package/src/plugins/builtin/econ/fred-series-map.ts +12 -1
  188. package/src/plugins/builtin/econ/index.tsx +31 -4
  189. package/src/plugins/builtin/econ/print-watch.ts +279 -0
  190. package/src/plugins/builtin/equity-screener/headless.ts +20 -5
  191. package/src/plugins/builtin/equity-screener/model.ts +40 -2
  192. package/src/plugins/builtin/equity-screener/pane.tsx +24 -21
  193. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -2
  194. package/src/plugins/builtin/estimate-revisions/lock-note.ts +29 -7
  195. package/src/plugins/builtin/executives/data.ts +24 -8
  196. package/src/plugins/builtin/executives/index.tsx +2 -18
  197. package/src/plugins/builtin/executives/pane.tsx +34 -10
  198. package/src/plugins/builtin/exposure/client.ts +4 -1
  199. package/src/plugins/builtin/exposure/editor.tsx +3 -3
  200. package/src/plugins/builtin/exposure/evidence.ts +4 -1
  201. package/src/plugins/builtin/exposure/holdings.ts +3 -1
  202. package/src/plugins/builtin/exposure/pane.tsx +37 -16
  203. package/src/plugins/builtin/filing-events/index.tsx +9 -3
  204. package/src/plugins/builtin/futures/table.tsx +6 -3
  205. package/src/plugins/builtin/futures-curve/pane.tsx +2 -2
  206. package/src/plugins/builtin/insider/base-values.ts +72 -0
  207. package/src/plugins/builtin/insider/headless.ts +29 -4
  208. package/src/plugins/builtin/jobs/headless.ts +2 -2
  209. package/src/plugins/builtin/jobs/lock-note.ts +14 -3
  210. package/src/plugins/builtin/market-halts/model.ts +31 -6
  211. package/src/plugins/builtin/market-halts/pane.tsx +3 -0
  212. package/src/plugins/builtin/market-movers/client.ts +2 -2
  213. package/src/plugins/builtin/market-movers/index.tsx +0 -3
  214. package/src/plugins/builtin/market-movers/session-body.tsx +27 -11
  215. package/src/plugins/builtin/market-movers/session.ts +25 -10
  216. package/src/plugins/builtin/market-valuation/pane.tsx +2 -1
  217. package/src/plugins/builtin/members/pane.tsx +8 -3
  218. package/src/plugins/builtin/news/wire/feed-config.ts +33 -13
  219. package/src/plugins/builtin/news/wire/index.tsx +7 -2
  220. package/src/plugins/builtin/news/wire/letters/client.ts +1 -0
  221. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +6 -3
  222. package/src/plugins/builtin/news/wire/news/detail-view.tsx +2 -1
  223. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +11 -3
  224. package/src/plugins/builtin/news/wire/news/table.tsx +2 -1
  225. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -2
  226. package/src/plugins/builtin/news/wire/rss/feed-xml.ts +6 -1
  227. package/src/plugins/builtin/news/wire/rss/managed-feed.ts +1 -0
  228. package/src/plugins/builtin/news/wire/rss/source.ts +13 -4
  229. package/src/plugins/builtin/notes/cli.ts +33 -8
  230. package/src/plugins/builtin/notes/export.ts +49 -3
  231. package/src/plugins/builtin/notes/files.ts +14 -3
  232. package/src/plugins/builtin/notes/index.tsx +3 -3
  233. package/src/plugins/builtin/notes/quick-notes-pane.tsx +45 -10
  234. package/src/plugins/builtin/notes/store.ts +13 -3
  235. package/src/plugins/builtin/options/footer.ts +25 -20
  236. package/src/plugins/builtin/options/live-quotes.ts +33 -18
  237. package/src/plugins/builtin/options/view.tsx +77 -22
  238. package/src/plugins/builtin/options-calculator/pane.tsx +4 -2
  239. package/src/plugins/builtin/options-scenario/pane.tsx +41 -6
  240. package/src/plugins/builtin/portfolio-list/account-metrics.ts +3 -0
  241. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +8 -7
  242. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +166 -15
  243. package/src/plugins/builtin/portfolio-list/cli/render.ts +69 -15
  244. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +2 -2
  245. package/src/plugins/builtin/portfolio-list/headless.ts +3 -1
  246. package/src/plugins/builtin/portfolio-list/pane/data.ts +23 -1
  247. package/src/plugins/builtin/portfolio-list/pane/index.tsx +44 -17
  248. package/src/plugins/builtin/portfolio-list/settings.ts +20 -2
  249. package/src/plugins/builtin/portfolio-list/summary/index.tsx +22 -1
  250. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +42 -7
  251. package/src/plugins/builtin/portfolio-list/summary/totals.ts +24 -3
  252. package/src/plugins/builtin/primary-dealers/client.ts +137 -62
  253. package/src/plugins/builtin/primary-dealers/headless.ts +30 -5
  254. package/src/plugins/builtin/primary-dealers/index.tsx +3 -2
  255. package/src/plugins/builtin/primary-dealers/model.ts +179 -129
  256. package/src/plugins/builtin/primary-dealers/pane.tsx +135 -15
  257. package/src/plugins/builtin/research/analyst-model.ts +5 -1
  258. package/src/plugins/builtin/risk-factors/index.tsx +12 -3
  259. package/src/plugins/builtin/scanner/feed.ts +6 -1
  260. package/src/plugins/builtin/scanner/headless.ts +1 -1
  261. package/src/plugins/builtin/scanner/lock-note.ts +3 -2
  262. package/src/plugins/builtin/series-inventory.ts +1 -0
  263. package/src/plugins/builtin/shared/broker-reconnect.ts +105 -0
  264. package/src/plugins/builtin/shared/cloud-denied.ts +7 -6
  265. package/src/plugins/builtin/shared/cloud-upgrade.ts +10 -11
  266. package/src/plugins/builtin/shared/free-routes.ts +24 -0
  267. package/src/plugins/builtin/shared/headless-options.ts +11 -0
  268. package/src/plugins/builtin/shared/pro-feature-wall.tsx +9 -4
  269. package/src/plugins/builtin/shared/pro-lock-note.ts +89 -7
  270. package/src/plugins/builtin/shared/research-trading.tsx +62 -0
  271. package/src/plugins/builtin/social-mentions/headless.ts +1 -1
  272. package/src/plugins/builtin/social-mentions/lock-note.ts +1 -1
  273. package/src/plugins/builtin/themes/headless.ts +8 -2
  274. package/src/plugins/builtin/themes/model.ts +43 -10
  275. package/src/plugins/builtin/themes/pane.tsx +8 -6
  276. package/src/plugins/builtin/thirteenf/api.ts +4 -1
  277. package/src/plugins/builtin/thirteenf/data.ts +5 -1
  278. package/src/plugins/builtin/thirteenf/headless.ts +3 -1
  279. package/src/plugins/builtin/thirteenf/pane.tsx +8 -3
  280. package/src/plugins/builtin/ticker-detail/overview/model.ts +44 -10
  281. package/src/plugins/builtin/ticker-detail/overview/option-contract.ts +64 -0
  282. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +82 -21
  283. package/src/plugins/builtin/ticker-detail/pane.tsx +21 -14
  284. package/src/plugins/builtin/ticker-detail/quote-footer.ts +5 -1
  285. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +37 -8
  286. package/src/plugins/builtin/time-sales/pane.tsx +2 -2
  287. package/src/plugins/builtin/trace-bonds/client.ts +14 -3
  288. package/src/plugins/builtin/trace-bonds/headless.ts +1 -1
  289. package/src/plugins/builtin/vol-surface/pane.tsx +2 -2
  290. package/src/plugins/builtin-editorial.ts +1 -1
  291. package/src/plugins/compat.ts +3 -0
  292. package/src/plugins/external-runtime.ts +5 -0
  293. package/src/plugins/loader.ts +6 -0
  294. package/src/plugins/plugin-icon.ts +61 -0
  295. package/src/plugins/registry/host-actions.ts +2 -1
  296. package/src/plugins/registry/index.ts +9 -1
  297. package/src/plugins/runtime/context.tsx +5 -0
  298. package/src/plugins/runtime/index.tsx +3 -0
  299. package/src/portfolio/column-values.ts +13 -4
  300. package/src/portfolio/cost-fx.ts +61 -0
  301. package/src/portfolio/mutations.ts +16 -2
  302. package/src/portfolio/position-metrics.ts +45 -4
  303. package/src/portfolio/position-quantity.ts +43 -0
  304. package/src/public/__snapshots__/public-api.test.ts.snap +5 -0
  305. package/src/public/broker.ts +8 -0
  306. package/src/public/market-data.ts +5 -0
  307. package/src/renderers/dom/desktop/control-styles.ts +7 -1
  308. package/src/renderers/dom/desktop/controls.tsx +39 -7
  309. package/src/renderers/dom/desktop/icons.tsx +14 -0
  310. package/src/renderers/dom/desktop/list-view.tsx +51 -19
  311. package/src/renderers/dom/desktop/menu.tsx +10 -1
  312. package/src/renderers/dom/desktop/select-field.tsx +8 -6
  313. package/src/renderers/dom/host/style.ts +6 -1
  314. package/src/renderers/dom/host/tabs.tsx +6 -0
  315. package/src/renderers/dom/styles.css +12 -5
  316. package/src/renderers/electrobun/bun/core-capabilities.ts +12 -0
  317. package/src/renderers/electrobun/bun/external-plugins.ts +3 -0
  318. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  319. package/src/renderers/electrobun/view/broker-remote-client.ts +16 -0
  320. package/src/renderers/electrobun/view/external-plugins.ts +1 -0
  321. package/src/series/validate.ts +2 -2
  322. package/src/sources/gloomberb-cloud/fred-series.ts +27 -2
  323. package/src/sources/gloomberb-cloud/index.ts +50 -17
  324. package/src/sources/gloomberb-cloud/normalizers.ts +4 -0
  325. package/src/sources/history-result.ts +3 -0
  326. package/src/sources/provider-errors.ts +3 -1
  327. package/src/sources/provider-router/history.ts +49 -6
  328. package/src/sources/provider-router/index.ts +2 -1
  329. package/src/state/app/activity.ts +13 -0
  330. package/src/sync/controller.ts +4 -0
  331. package/src/sync/core-contributors.ts +63 -11
  332. package/src/sync/local-only.ts +121 -0
  333. package/src/sync/react.ts +6 -0
  334. package/src/sync/types.ts +3 -0
  335. package/src/team/collections.ts +2 -0
  336. package/src/tickers/listing-fate.ts +27 -8
  337. package/src/tickers/metadata.ts +10 -0
  338. package/src/tickers/search/index.ts +24 -3
  339. package/src/time-series/price-comparison.ts +35 -0
  340. package/src/time-series/resolve.ts +52 -11
  341. package/src/time-series/spec.ts +1 -1
  342. package/src/time-series/types.ts +5 -0
  343. package/src/types/broker.ts +56 -1
  344. package/src/types/config.ts +6 -0
  345. package/src/types/data-provider.ts +5 -1
  346. package/src/types/financials.ts +23 -0
  347. package/src/types/headless.ts +12 -2
  348. package/src/types/instrument.ts +4 -0
  349. package/src/types/plugin.ts +24 -6
  350. package/src/types/price-history.ts +6 -1
  351. package/src/types/ticker.ts +9 -0
  352. package/src/types/trading.ts +67 -0
  353. package/src/ui/host.tsx +4 -0
  354. package/src/utils/base-currency.ts +108 -0
  355. package/src/utils/currency-names.ts +128 -0
  356. package/src/utils/currency-pair.ts +2 -1
  357. package/src/utils/currency-units.ts +41 -1
  358. package/src/utils/dom-screenshot.ts +22 -9
  359. package/src/utils/exchange-notation.generated.ts +360 -0
  360. package/src/utils/exchanges.ts +15 -322
  361. package/src/utils/format.ts +31 -1
  362. package/src/utils/instrument-identity.ts +38 -1
  363. package/src/utils/options.ts +46 -1
  364. package/src/utils/price-history.ts +4 -0
  365. package/src/utils/reported-money.ts +8 -4
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "format": 1,
3
3
  "site": "https://gloom.sh",
4
- "updatedAt": "2026-10-16",
4
+ "updatedAt": "2026-10-17",
5
5
  "categories": [
6
6
  {
7
7
  "id": "research",
@@ -159,7 +159,7 @@
159
159
  "code": "DDIS",
160
160
  "name": "Debt maturities",
161
161
  "description": "Principal due by year",
162
- "detail": "Principal due in the next 12 months, in each of years two to five, and after, from the latest annual filing, with the near-term share ranked against 10 years. History tracks principal and interest expense.",
162
+ "detail": "Principal due in the next 12 months, in each of years two to five, and after, from the latest annual filing, with the near-term share ranked against 10 years. A newer 10-Q adds its current and non-current debt. History tracks principal and interest expense.",
163
163
  "category": "research",
164
164
  "arg": "ORCL",
165
165
  "shot": "https://gloom.sh/screenshots/fn/DDIS.png",
@@ -480,7 +480,7 @@
480
480
  "code": "EXEC",
481
481
  "name": "Executives",
482
482
  "description": "Officers and pay from the proxy",
483
- "detail": "Named executive officers and their compensation, read from the proxy statement and checked against the filing.",
483
+ "detail": "Named executive officers and their compensation, read from the proxy statement and checked against the filing. Free shows each executive's total pay; Pro adds the breakdown and earlier years.",
484
484
  "category": "research",
485
485
  "arg": "NVDA",
486
486
  "access": "pro",
@@ -695,7 +695,7 @@
695
695
  "code": "MOST",
696
696
  "name": "Market movers",
697
697
  "description": "Gainers, losers, pre-market, gaps",
698
- "detail": "Today's top gainers, losers, most active and trending tickers with price, change, volume against average and market cap. Pro adds pre-market and after-hours movers and the gaps at the open.",
698
+ "detail": "Today's top gainers, losers, most active and trending tickers with price, change, volume against average and market cap, and the pre-market and after-hours movers. Pro adds the gaps at the open.",
699
699
  "category": "markets",
700
700
  "shot": "https://gloom.sh/screenshots/fn/MOST.png",
701
701
  "lesson": "/academy/macro-markets-and-news/markets/movers-highs-halts"
@@ -759,7 +759,7 @@
759
759
  "code": "CRYP",
760
760
  "name": "Crypto board",
761
761
  "description": "Top coins by market cap",
762
- "detail": "The top 100 coins by market cap, stablecoins on their own tab, with returns from a day to a year, a 30-day sparkline, volume, and market cap. Prices stream live on every plan where the market allows.",
762
+ "detail": "The top 100 coins by market cap, with returns from a day to a year, a 30-day sparkline, volume, and market cap. Stablecoins have their own tab: total supply over time stacked by coin, and each coin's supply, 7- and 30-day supply growth and share of the total. Prices stream live on every plan where the market allows.",
763
763
  "category": "markets",
764
764
  "shot": "https://gloom.sh/screenshots/fn/CRYP.png",
765
765
  "lesson": "/academy/crypto-and-prediction-markets/crypto-from-zero"
@@ -777,8 +777,8 @@
777
777
  {
778
778
  "code": "FUT",
779
779
  "name": "Futures board",
780
- "description": "Most active futures",
781
- "detail": "Each root's most active contract across equity index, rates, energy, metals, agriculture, and FX with last price, unit and session change, grouped by sector, naming the nearer month while it still trades.",
780
+ "description": "Front-month futures",
781
+ "detail": "Each root's front contract until its stated roll date across equity index, rates, energy, metals, agriculture, and FX with last price, unit and session change, grouped by sector, naming the day's most active month by volume when it is another one.",
782
782
  "category": "markets",
783
783
  "shot": "https://gloom.sh/screenshots/fn/FUT.png",
784
784
  "lesson": "/academy/futures-commodities-energy/futures-from-zero"
@@ -1186,7 +1186,7 @@
1186
1186
  "code": "CDS",
1187
1187
  "name": "Single-name CDS",
1188
1188
  "description": "Corporate 5Y CDS and trades",
1189
- "detail": "Single-name corporate CDS. CDS alone lists the issuers traded in the last 5 days with trade count, last trade and 5Y spread, to rank them by; with a ticker or issuer, its 5Y spread (level, date, 1M change, range) and its trades.",
1189
+ "detail": "Single-name corporate CDS. CDS alone lists the issuers traded in the last 5 days with trade count, last trade, 5Y spread and its 1W and 1M moves through the roll while the level is current (points upfront past 2,000 bp), ranked with --sort spread, 1w or 1m; with a ticker or issuer, its 5Y spread (level, date, 1W and 1M change, range), its trades and its daily 5Y levels (--csv --section daily exports them).",
1190
1190
  "category": "macro",
1191
1191
  "arg": "F",
1192
1192
  "shot": "https://gloom.sh/screenshots/fn/CDS.png",
@@ -1229,8 +1229,8 @@
1229
1229
  {
1230
1230
  "code": "TRACE",
1231
1231
  "name": "Corporate bond tape",
1232
- "description": "Latest corporate and agency sales",
1233
- "detail": "Latest corporate and agency bond sales: issuer, coupon, price, yield, and grade. TRACE alone lists the tape; TRACE with an issuer filters to that name. It opens the Bonds section of Fixed Income.",
1232
+ "description": "Corporate and agency sales by issuer or CUSIP",
1233
+ "detail": "Latest corporate and agency bond sales: issuer, CUSIP, coupon, maturity, price, yield, and grade. TRACE alone lists the tape; TRACE with an issuer name, a bond symbol root, a stock ticker, or a CUSIP finds that issuer's outstanding bonds. It opens the Bonds section of Fixed Income.",
1234
1234
  "category": "macro",
1235
1235
  "arg": "issuer"
1236
1236
  },
@@ -1299,8 +1299,8 @@
1299
1299
  {
1300
1300
  "code": "INS",
1301
1301
  "name": "Insider transactions",
1302
- "description": "Form 4 activity and insider buying",
1303
- "detail": "Insider buys, sells, awards, and gifts from Form 4 filings with insider name, size, and price. Alone it ranks the companies whose insiders are buying in the market, with why: clusters, repeat buys, size against their usual. US equities only.",
1302
+ "description": "Form 4 activity, insider buying and selling",
1303
+ "detail": "Insider buys, sells, awards, and gifts from Form 4 filings with insider name, size, and price. Alone it ranks the companies whose insiders are buying, or selling, in the market, with why: clusters, repeat trades, size against their usual, the stake added or sold. Filters by role, size, cluster, new or exited positions and market cap. US equities only.",
1304
1304
  "category": "ownership",
1305
1305
  "arg": "NVDA",
1306
1306
  "shot": "https://gloom.sh/screenshots/fn/INS.png",
@@ -1401,9 +1401,9 @@
1401
1401
  },
1402
1402
  {
1403
1403
  "code": "ALRT",
1404
- "name": "Price alerts",
1405
- "description": "Price triggers",
1406
- "detail": "Your price alerts with current price, distance to target, and trigger state.",
1404
+ "name": "Alerts",
1405
+ "description": "Price, earnings, filing, news and flow alerts",
1406
+ "detail": "Price alerts with current price, distance to target, and trigger state, plus alerts on earnings, CPI and FOMC dates, filings and 13F, news keywords, analyst changes, 52-week highs and lows, unusual volume, short interest, insider and congress trades, catalysts, IV spikes, options flow, and perps.",
1407
1407
  "category": "workspace",
1408
1408
  "shot": "https://gloom.sh/screenshots/fn/ALRT.png",
1409
1409
  "lesson": "/academy/terminal-and-workspace/your-workspace/alerts"
@@ -2407,9 +2407,14 @@
2407
2407
  "drift",
2408
2408
  "rebalance",
2409
2409
  "weights",
2410
- "glossary"
2410
+ "glossary",
2411
+ "dividend income",
2412
+ "yield",
2413
+ "DRIP",
2414
+ "reinvest",
2415
+ "DVD"
2411
2416
  ],
2412
- "updatedAt": "2026-10-12",
2417
+ "updatedAt": "2026-10-17",
2413
2418
  "blocks": [
2414
2419
  {
2415
2420
  "type": "heading",
@@ -2493,6 +2498,31 @@
2493
2498
  }
2494
2499
  ]
2495
2500
  },
2501
+ {
2502
+ "type": "heading",
2503
+ "level": 2,
2504
+ "text": "Dividend income"
2505
+ },
2506
+ {
2507
+ "type": "paragraph",
2508
+ "text": "`gloomberb portfolio show Core` also lists what each share or fund pays a year: its trailing twelve months of dividends per share times the shares you hold, in the portfolio's currency, and that as a yield on the holding's value. The TOTAL row gives the portfolio's income and its yield on the whole portfolio, cash included. A holding whose dividends could not be read shows `—`, and so does the total, never $0."
2509
+ },
2510
+ {
2511
+ "type": "paragraph",
2512
+ "text": "To see what reinvesting them adds, ask for a DRIP projection:"
2513
+ },
2514
+ {
2515
+ "type": "code",
2516
+ "code": "gloomberb portfolio show Core --drip --years 3 --withholding 15"
2517
+ },
2518
+ {
2519
+ "type": "paragraph",
2520
+ "text": "Each year the shares you hold pay today's dividend, the withholding comes off, and the rest buys shares at today's price. The table gives each holding's shares now and after the last year, and the income each year, net of withholding. `--years` takes 1 to 5."
2521
+ },
2522
+ {
2523
+ "type": "paragraph",
2524
+ "text": "To compare payers before you buy, rank them by yield with payout and growth: `gloomberb fn DVD KO PEP JNJ`."
2525
+ },
2496
2526
  {
2497
2527
  "type": "details",
2498
2528
  "summary": "Fine print",
@@ -2501,6 +2531,7 @@
2501
2531
  "type": "list",
2502
2532
  "items": [
2503
2533
  "Targets need not add up to 100%; the report says what is unallocated.",
2534
+ "Income uses trailing dividends, not announced ones. DRIP holds dividends, prices and exchange rates where they are today and reinvests once a year; it is an illustration, not a forecast.",
2504
2535
  "Trades use the current price and leave out fees, taxes and lot sizes.",
2505
2536
  "A broker portfolio uses the cash its account reports.",
2506
2537
  "In the PF pane the columns read `WEIGHT`, `TGT WT`, `DRIFT` and `TRADE`."
@@ -2510,7 +2541,7 @@
2510
2541
  },
2511
2542
  {
2512
2543
  "type": "paragraph",
2513
- "text": "Related: [PF](/docs/functions#pf), [CLI](/docs/cli-functions#portfolios-and-notes)."
2544
+ "text": "Related: [PF](/docs/functions#pf), [CLI](/docs/cli-functions#portfolios-and-notes). Methodology: [dividend income and DRIP](https://github.com/gloom-sh/gloomberb/blob/main/docs/research-data.md#portfolio-income-and-drip)."
2514
2545
  }
2515
2546
  ]
2516
2547
  },
@@ -5273,6 +5304,10 @@
5273
5304
  "`financials`, `fundamentals`, `valuation`, `events`, `analyst` `<symbol>`",
5274
5305
  "Revenue and EPS, profile, multiples, dividends and splits, ratings and targets"
5275
5306
  ],
5307
+ [
5308
+ "`fn DVD <symbols>`",
5309
+ "Dividend yield and history; several symbols rank in one table by yield, with payout, growth, last ex-date and pay date"
5310
+ ],
5276
5311
  [
5277
5312
  "`holders`, `insider`, `13f`, `filings` `<symbol>`",
5278
5313
  "Holders, insiders, institutions and funds, SEC filings"
@@ -5335,7 +5370,7 @@
5335
5370
  "rows": [
5336
5371
  [
5337
5372
  "`portfolio list|show|create|delete <name>`",
5338
- "Manual portfolios; `show` lists value, weight, target, drift and the trade to rebalance, and `show --explain` adds what those terms mean"
5373
+ "Manual portfolios; `show` lists value, weight, a year of dividend income and its yield, target, drift and the trade to rebalance; `show --explain` adds what those terms mean, and `show --drip [--years 1-5] [--withholding <pct>]` projects reinvested dividends"
5339
5374
  ],
5340
5375
  [
5341
5376
  "`portfolio add|remove <portfolio> <symbols...> [--file <csv|txt>]`",
@@ -5453,7 +5488,7 @@
5453
5488
  },
5454
5489
  {
5455
5490
  "type": "paragraph",
5456
- "text": "`gloomberb catalog <function>` lists a function's options. `shot` also takes `--tab <id>`."
5491
+ "text": "`gloomberb catalog <function>` lists a function's options. `shot` also takes `--tab <id>`. `shot` draws a function's options as its pane does: `gloomberb shot 13F 0001067983 --compare SPY` opens the fund's overlap with SPY. An option only the text report reads, such as `--limit`, fails `shot` with exit 1 and names the `fn` command that reads it, instead of saving the pane without it."
5457
5492
  },
5458
5493
  {
5459
5494
  "type": "paragraph",
@@ -7546,7 +7581,7 @@
7546
7581
  {
7547
7582
  "url": "/academy/futures-commodities-energy/futures-from-zero",
7548
7583
  "title": "Futures from zero (FUT)",
7549
- "summary": "A futures contract is a standard, exchange-traded promise to buy or sell a set quantity on a set month at a price agreed today, settled with daily margin, and FUT shows the most active months across markets.",
7584
+ "summary": "A futures contract is a standard, exchange-traded promise to buy or sell a set quantity on a set month at a price agreed today, settled with daily margin, and FUT shows each market's front month.",
7550
7585
  "chapter": "Futures, commodities and energy",
7551
7586
  "minutes": 5
7552
7587
  },
@@ -7646,7 +7681,7 @@
7646
7681
  "title": "Credit default swaps (CDS, CDX, SOVR)",
7647
7682
  "summary": "A credit default swap is insurance on a borrower's default, and CDS, CDX and SOVR show reported trades on companies, the main indices and 5-year country spreads.",
7648
7683
  "chapter": "Rates, bonds and credit",
7649
- "minutes": 4
7684
+ "minutes": 5
7650
7685
  },
7651
7686
  {
7652
7687
  "url": "/academy/rates-bonds-credit/credit/debt-and-covenants",
package/src/i18n/es.ts CHANGED
@@ -380,8 +380,7 @@ export const es: Record<string, string> = {
380
380
  "Insider transactions for a ticker; alone, the companies whose insiders are buying or selling.": "Operaciones de insiders de un ticker; sin ticker, las empresas cuyos insiders están comprando o vendiendo.",
381
381
  "Recent SEC filings for US equities": "Presentaciones recientes ante la SEC de acciones de EE. UU.",
382
382
  "Recent SEC filings for the selected ticker.": "Presentaciones recientes ante la SEC del ticker seleccionado.",
383
- "Price trigger alerts with desktop notifications": "Alertas de precio con notificaciones de escritorio",
384
- "Price trigger alerts with notifications": "Alertas de precio con notificaciones",
383
+ "Price, earnings, filing, news and flow alerts": "Alertas de precio, resultados, presentaciones, noticias y flujo de opciones",
385
384
  "Create a price alert from a symbol, condition, and target price": "Crear una alerta de precio con símbolo, condición y precio objetivo",
386
385
  "Public market heatmap for the largest US stocks and ETFs.": "Mapa de calor de las mayores acciones y ETF de EE. UU.",
387
386
  "Top gainers, losers, most active, and trending tickers": "Mayores alzas, bajas, más activos y tickers en tendencia",
@@ -665,7 +664,7 @@ export const es: Record<string, string> = {
665
664
  "Real-time": "Tiempo real",
666
665
  "real-time options": "opciones en tiempo real",
667
666
  "mixed real-time and delayed options": "opciones mixtas en tiempo real y diferidas",
668
- "options delayed fallback": "respaldo diferido de opciones",
667
+ "Delayed options quotes, real-time stream unavailable": "Cotizaciones de opciones diferidas, flujo en tiempo real no disponible",
669
668
  "crossed quote": "cotización cruzada",
670
669
  "one-sided quote": "cotización unilateral",
671
670
  "no bid/ask": "sin compra/venta",
@@ -1626,4 +1625,11 @@ export const es: Record<string, string> = {
1626
1625
  "It is kept once it has been read with a connection.": "Se guarda al leerla una vez con conexión.",
1627
1626
  "Academy: {title}": "Academia: {title}",
1628
1627
  "{minutes} min": "{minutes} min",
1628
+ "Delisted {date}": "Excluida de bolsa el {date}",
1629
+ "Last traded {date}": "Última negociación el {date}",
1630
+ "Account data": "Datos de la cuenta",
1631
+ "Sync with Gloom Cloud": "Sincronizar con Gloom Cloud",
1632
+ "Keep on this device": "Mantener en este dispositivo",
1633
+ "Daily roundups, the weekly brief, position alerts, the mobile app and Ask Gloom will go without this account.": "Los resúmenes diarios, el informe semanal, las alertas de posiciones, la app móvil y Ask Gloom no incluirán esta cuenta.",
1634
+ "Account data stays on this device, out of Gloom Cloud": "Los datos de la cuenta se quedan en este dispositivo, fuera de Gloom Cloud",
1629
1635
  };
package/src/i18n/ja.ts CHANGED
@@ -381,8 +381,7 @@ export const ja: Record<string, string> = {
381
381
  "Insider transactions for a ticker; alone, the companies whose insiders are buying or selling.": "銘柄のインサイダー取引。銘柄を指定しないと、インサイダーが買っている、または売っている企業の一覧。",
382
382
  "Recent SEC filings for US equities": "米国株の最新 SEC 開示",
383
383
  "Recent SEC filings for the selected ticker.": "選択した銘柄の最新 SEC 開示。",
384
- "Price trigger alerts with desktop notifications": "デスクトップ通知による価格トリガーアラート",
385
- "Price trigger alerts with notifications": "通知付きの価格トリガーアラート",
384
+ "Price, earnings, filing, news and flow alerts": "価格、決算、開示、ニュース、オプションフローのアラート",
386
385
  "Create a price alert from a symbol, condition, and target price": "銘柄コード、条件、目標価格から価格アラートを作成",
387
386
  "Public market heatmap for the largest US stocks and ETFs.": "米国大型株と ETF の市場ヒートマップ。",
388
387
  "Top gainers, losers, most active, and trending tickers": "値上がり、値下がり、出来高、注目銘柄",
@@ -679,7 +678,7 @@ export const ja: Record<string, string> = {
679
678
  "Go Pro for real-time data at gloom.sh/cloud, free for 7 days.": "gloom.sh/cloud で Pro にアップグレードするとリアルタイムデータを 7 日間無料で利用できます。",
680
679
  "real-time options": "リアルタイムオプション",
681
680
  "mixed real-time and delayed options": "リアルタイムと遅延の混在オプション",
682
- "options delayed fallback": "オプション遅延フォールバック",
681
+ "Delayed options quotes, real-time stream unavailable": "オプション気配値は遅延中、リアルタイム配信は利用できません",
683
682
  "crossed quote": "クロス気配",
684
683
  "one-sided quote": "片側気配",
685
684
  "no bid/ask": "気配なし",
@@ -1622,4 +1621,11 @@ export const ja: Record<string, string> = {
1622
1621
  "It is kept once it has been read with a connection.": "一度オンラインで読むと保存されます。",
1623
1622
  "Academy: {title}": "アカデミー: {title}",
1624
1623
  "{minutes} min": "{minutes} 分",
1624
+ "Delisted {date}": "上場廃止 {date}",
1625
+ "Last traded {date}": "最終取引 {date}",
1626
+ "Account data": "口座データ",
1627
+ "Sync with Gloom Cloud": "Gloom Cloud と同期",
1628
+ "Keep on this device": "このデバイスに保存",
1629
+ "Daily roundups, the weekly brief, position alerts, the mobile app and Ask Gloom will go without this account.": "デイリーまとめ、週次ブリーフ、ポジションアラート、モバイルアプリ、Ask Gloom にはこの口座が含まれなくなります。",
1630
+ "Account data stays on this device, out of Gloom Cloud": "口座データはこのデバイスに保存され、Gloom Cloud には送られません",
1625
1631
  };
package/src/i18n/ko.ts CHANGED
@@ -379,8 +379,7 @@ export const ko: Record<string, string> = {
379
379
  "Insider transactions for a ticker; alone, the companies whose insiders are buying or selling.": "종목의 내부자 거래. 종목 없이 열면 내부자가 매수 또는 매도 중인 기업 목록.",
380
380
  "Recent SEC filings for US equities": "미국 주식의 최신 SEC 공시",
381
381
  "Recent SEC filings for the selected ticker.": "선택 종목의 최신 SEC 공시.",
382
- "Price trigger alerts with desktop notifications": "데스크톱 알림이 있는 목표가 알림",
383
- "Price trigger alerts with notifications": "알림이 있는 목표가 알림",
382
+ "Price, earnings, filing, news and flow alerts": "가격, 실적, 공시, 뉴스, 옵션 플로우 알림",
384
383
  "Create a price alert from a symbol, condition, and target price": "종목코드, 조건 및 목표가로 가격 알림 생성",
385
384
  "Public market heatmap for the largest US stocks and ETFs.": "미국 대형주 및 ETF 시장 히트맵.",
386
385
  "Top gainers, losers, most active, and trending tickers": "상승률·하락률·거래량 상위 및 인기 종목",
@@ -677,7 +676,7 @@ export const ko: Record<string, string> = {
677
676
  "Go Pro for real-time data at gloom.sh/cloud, free for 7 days.": "gloom.sh/cloud에서 Pro로 업그레이드하면 실시간 데이터를 7일간 무료로 사용할 수 있습니다.",
678
677
  "real-time options": "실시간 옵션",
679
678
  "mixed real-time and delayed options": "실시간 및 지연 옵션 혼합",
680
- "options delayed fallback": "옵션 지연 대체 데이터",
679
+ "Delayed options quotes, real-time stream unavailable": "옵션 시세 지연, 실시간 스트림 사용 불가",
681
680
  "crossed quote": "교차 호가",
682
681
  "one-sided quote": "일방 호가",
683
682
  "no bid/ask": "호가 없음",
@@ -1620,4 +1619,11 @@ export const ko: Record<string, string> = {
1620
1619
  "It is kept once it has been read with a connection.": "연결된 상태에서 한 번 읽으면 저장됩니다.",
1621
1620
  "Academy: {title}": "아카데미: {title}",
1622
1621
  "{minutes} min": "{minutes}분",
1622
+ "Delisted {date}": "상장폐지 {date}",
1623
+ "Last traded {date}": "최종 거래 {date}",
1624
+ "Account data": "계좌 데이터",
1625
+ "Sync with Gloom Cloud": "Gloom Cloud와 동기화",
1626
+ "Keep on this device": "이 기기에 보관",
1627
+ "Daily roundups, the weekly brief, position alerts, the mobile app and Ask Gloom will go without this account.": "일일 요약, 주간 브리핑, 포지션 알림, 모바일 앱, Ask Gloom에 이 계좌가 포함되지 않습니다.",
1628
+ "Account data stays on this device, out of Gloom Cloud": "계좌 데이터는 Gloom Cloud에 올라가지 않고 이 기기에 남습니다",
1623
1629
  };
package/src/i18n/zh-cn.ts CHANGED
@@ -328,7 +328,7 @@ export const zhCN: Record<string, string> = {
328
328
  "Insider Trading": "内部人交易",
329
329
  "SEC": "SEC 文件",
330
330
  "Notes": "笔记",
331
- "Alerts": "价格提醒",
331
+ "Alerts": "提醒",
332
332
  "Market Heatmap": "市场热力图",
333
333
  "Market Movers": "市场异动",
334
334
  "Sector Performance": "板块表现",
@@ -381,8 +381,7 @@ export const zhCN: Record<string, string> = {
381
381
  "Insider transactions for a ticker; alone, the companies whose insiders are buying or selling.": "某只股票的内部人交易;不指定股票时,列出内部人正在买入或卖出的公司。",
382
382
  "Recent SEC filings for US equities": "美股最新 SEC 申报文件",
383
383
  "Recent SEC filings for the selected ticker.": "所选股票的最新 SEC 申报文件。",
384
- "Price trigger alerts with desktop notifications": "带桌面通知的价格触发提醒",
385
- "Price trigger alerts with notifications": "带通知的价格触发提醒",
384
+ "Price, earnings, filing, news and flow alerts": "价格、财报、申报文件、新闻和期权资金流提醒",
386
385
  "Create a price alert from a symbol, condition, and target price": "用代码、条件和目标价创建价格提醒",
387
386
  "Public market heatmap for the largest US stocks and ETFs.": "美股大盘股与 ETF 的市场热力图。",
388
387
  "Top gainers, losers, most active, and trending tickers": "涨幅榜、跌幅榜、成交活跃与热门股票",
@@ -679,7 +678,7 @@ export const zhCN: Record<string, string> = {
679
678
  "Go Pro for real-time data at gloom.sh/cloud, free for 7 days.": "在 gloom.sh/cloud 升级 Pro 获取实时数据,免费试用 7 天。",
680
679
  "real-time options": "实时期权",
681
680
  "mixed real-time and delayed options": "实时与延迟期权混合",
682
- "options delayed fallback": "期权延迟备用数据",
681
+ "Delayed options quotes, real-time stream unavailable": "期权报价延迟,实时数据流不可用",
683
682
  "crossed quote": "交叉报价",
684
683
  "one-sided quote": "单边报价",
685
684
  "no bid/ask": "无买卖报价",
@@ -1622,4 +1621,11 @@ export const zhCN: Record<string, string> = {
1622
1621
  "It is kept once it has been read with a connection.": "联网阅读过一次后即会保存。",
1623
1622
  "Academy: {title}": "学院:{title}",
1624
1623
  "{minutes} min": "{minutes} 分钟",
1624
+ "Delisted {date}": "已退市 {date}",
1625
+ "Last traded {date}": "最后交易 {date}",
1626
+ "Account data": "账户数据",
1627
+ "Sync with Gloom Cloud": "与 Gloom Cloud 同步",
1628
+ "Keep on this device": "保留在此设备上",
1629
+ "Daily roundups, the weekly brief, position alerts, the mobile app and Ask Gloom will go without this account.": "每日汇总、每周简报、持仓提醒、移动应用和 Ask Gloom 将不再包含此账户。",
1630
+ "Account data stays on this device, out of Gloom Cloud": "账户数据保留在此设备上,不上传到 Gloom Cloud",
1625
1631
  };
package/src/i18n/zh-tw.ts CHANGED
@@ -328,7 +328,7 @@ export const zhTW: Record<string, string> = {
328
328
  "Insider Trading": "內部人士交易",
329
329
  "SEC": "SEC 申報",
330
330
  "Notes": "筆記",
331
- "Alerts": "價格提醒",
331
+ "Alerts": "提醒",
332
332
  "Market Heatmap": "市場熱力圖",
333
333
  "Market Movers": "市場異動",
334
334
  "Sector Performance": "類股表現",
@@ -381,8 +381,7 @@ export const zhTW: Record<string, string> = {
381
381
  "Insider transactions for a ticker; alone, the companies whose insiders are buying or selling.": "某檔股票的內部人士交易;不指定股票時,列出內部人士正在買進或賣出的公司。",
382
382
  "Recent SEC filings for US equities": "美股最新 SEC 申報檔案",
383
383
  "Recent SEC filings for the selected ticker.": "所選股票的最新 SEC 申報檔案。",
384
- "Price trigger alerts with desktop notifications": "透過桌面通知的價格觸發提醒",
385
- "Price trigger alerts with notifications": "透過通知的價格觸發提醒",
384
+ "Price, earnings, filing, news and flow alerts": "價格、財報、申報文件、新聞與選擇權資金流提醒",
386
385
  "Create a price alert from a symbol, condition, and target price": "用代號、條件和目標價建立價格提醒",
387
386
  "Public market heatmap for the largest US stocks and ETFs.": "美股大盤股與 ETF 的市場熱力圖。",
388
387
  "Top gainers, losers, most active, and trending tickers": "漲幅榜、跌幅榜、成交活躍與熱門股票",
@@ -679,7 +678,7 @@ export const zhTW: Record<string, string> = {
679
678
  "Go Pro for real-time data at gloom.sh/cloud, free for 7 days.": "在 gloom.sh/cloud 升級 Pro 取得即時資料,免費試用 7 天。",
680
679
  "real-time options": "即時選擇權",
681
680
  "mixed real-time and delayed options": "即時與延遲選擇權混合",
682
- "options delayed fallback": "選擇權延遲備援資料",
681
+ "Delayed options quotes, real-time stream unavailable": "選擇權報價延遲,即時資料流無法使用",
683
682
  "crossed quote": "交叉報價",
684
683
  "one-sided quote": "單邊報價",
685
684
  "no bid/ask": "無買賣報價",
@@ -1622,4 +1621,11 @@ export const zhTW: Record<string, string> = {
1622
1621
  "It is kept once it has been read with a connection.": "連線閱讀過一次後就會儲存。",
1623
1622
  "Academy: {title}": "學院:{title}",
1624
1623
  "{minutes} min": "{minutes} 分鐘",
1624
+ "Delisted {date}": "已下市 {date}",
1625
+ "Last traded {date}": "最後交易 {date}",
1626
+ "Account data": "帳戶資料",
1627
+ "Sync with Gloom Cloud": "與 Gloom Cloud 同步",
1628
+ "Keep on this device": "保留在此裝置上",
1629
+ "Daily roundups, the weekly brief, position alerts, the mobile app and Ask Gloom will go without this account.": "每日摘要、每週簡報、持倉提醒、行動應用程式和 Ask Gloom 將不再包含此帳戶。",
1630
+ "Account data stays on this device, out of Gloom Cloud": "帳戶資料保留在此裝置上,不上傳至 Gloom Cloud",
1625
1631
  };
@@ -0,0 +1,80 @@
1
+ import { futuresContractByCode, type FuturesContract } from "./futures-board";
2
+
3
+ /**
4
+ * The names a reader types for the commodities on the futures board, by the
5
+ * board code they trade under. A news search that names one ("arabica",
6
+ * "sugar prices") offers the future's own news route (news KC=F), and a
7
+ * future's news searches the stories of its commodity by the first name
8
+ * listed for its code (KC=F reads "coffee"): news is filed under companies,
9
+ * and the service matches the same names to the stories filed under each
10
+ * future. Longer names win where one holds another ("soybean oil", "oil"),
11
+ * and a name in any of its forms counts (hogs, soybeans), as the service
12
+ * reads it. A null code is an oil no future trades: "palm oil" is not crude.
13
+ */
14
+ const COMMODITY_NAMES: ReadonlyArray<readonly [name: string, code: string | null]> = [
15
+ ["coffee", "KC"], ["arabica", "KC"],
16
+ ["sugar", "SB"], ["cocoa", "CC"], ["cotton", "CT"], ["orange juice", "OJ"], ["lumber", "LBR"],
17
+ ["wheat", "ZW"], ["wheat", "KE"], ["corn", "ZC"],
18
+ ["soybean", "ZS"], ["soy", "ZS"], ["soybean meal", "ZM"], ["soybean oil", "ZL"], ["soy oil", "ZL"],
19
+ // Cattle finds the ranchers' and packers' stories "live cattle" misses; a bare "hog" finds Harley-Davidson (HOG).
20
+ ["cattle", "LE"], ["live cattle", "LE"], ["lean hog", "HE"], ["hog", "HE"],
21
+ ["gold", "GC"], ["silver", "SI"], ["copper", "HG"], ["platinum", "PL"], ["palladium", "PA"],
22
+ ["aluminum", "ALI"], ["aluminium", "ALI"],
23
+ ["oil", "CL"], ["crude oil", "CL"], ["crude", "CL"], ["wti", "CL"], ["oil", "QM"], ["oil", "MCL"],
24
+ ["brent", "BZ"], ["heating oil", "HO"], ["gasoline", "RB"],
25
+ ["natural gas", "NG"], ["natgas", "NG"], ["natural gas", "QG"], ["natural gas", "MNG"], ["natural gas", "HH"],
26
+ ...["palm", "olive", "cooking", "vegetable", "corn", "edible", "sunflower", "canola", "rapeseed", "coconut", "peanut", "sesame",
27
+ "avocado", "cottonseed", "linseed", "flaxseed", "fish", "castor", "essential", "hemp", "cbd", "motor", "engine",
28
+ "lubricating", "baby", "snake"].map((kind) => [`${kind} oil`, null] as const),
29
+ ];
30
+
31
+ /** Words that end in s without being plurals, as the service keeps them whole. */
32
+ const NOT_PLURAL = new Set(["news", "series", "species"]);
33
+
34
+ /**
35
+ * A word and its simple singular or plural, as the service's search reads a
36
+ * word: hogs and hog, soybeans and soybean, gases and gas.
37
+ */
38
+ function wordForms(word: string): string[] {
39
+ if (!/^\p{L}+$/u.test(word) || NOT_PLURAL.has(word)) return [word];
40
+ if (word.length > 3 && word.endsWith("s") && !/(ss|us|is)$/.test(word)) {
41
+ const singulars = [word.slice(0, -1)];
42
+ if (word.length > 4 && word.endsWith("ies")) singulars.push(`${word.slice(0, -3)}y`);
43
+ else if (/(s|x|z|ch|sh)es$/.test(word)) singulars.push(word.slice(0, -2));
44
+ return [word, ...singulars];
45
+ }
46
+ if (word.length < 3) return [word];
47
+ const plural = /[^aeiou]y$/.test(word) ? `${word.slice(0, -1)}ies` : /(s|x|z|ch|sh)$/.test(word) ? `${word}es` : `${word}s`;
48
+ return [word, plural];
49
+ }
50
+
51
+ const PHRASES = COMMODITY_NAMES.map(([name, code]) => ({ words: name.split(" "), code }))
52
+ .sort((a, b) => b.words.length - a.words.length);
53
+
54
+ /** The words of a text as the service reads them: lower case, split on anything but letters and digits. */
55
+ const words = (text: string) => text.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
56
+
57
+ /** Whether the typed words are the name's, each in any of its forms. */
58
+ const sameWords = (typed: readonly string[], name: readonly string[]) => typed.length === name.length
59
+ && name.every((word, index) => wordForms(typed[index]!).includes(word));
60
+
61
+ /** The first commodity a text names, as its future on the board: "arabica" and "sugar prices" name KC and SB; "palm oil" names none. */
62
+ export function commodityNamedIn(text: string): FuturesContract | null {
63
+ const typed = words(text);
64
+ for (let index = 0; index < typed.length;) {
65
+ const phrase = PHRASES.find((entry) => sameWords(typed.slice(index, index + entry.words.length), entry.words));
66
+ if (phrase?.code) return futuresContractByCode(phrase.code);
67
+ index += phrase?.words.length ?? 1;
68
+ }
69
+ return null;
70
+ }
71
+
72
+ /** Whether the text is only a commodity's name, in any of its forms: "soybeans" searches what "soybean" does. */
73
+ export function isCommodityName(text: string, name: string): boolean {
74
+ return sameWords(words(text), words(name));
75
+ }
76
+
77
+ /** The name a future's stories are searched by: coffee for KC=F, wheat for ZW=F and KE=F. Null for a future with no commodity name (indices, rates, currencies, TTF). */
78
+ export function commoditySearchName(contract: Pick<FuturesContract, "code">): string | null {
79
+ return COMMODITY_NAMES.find(([, code]) => code === contract.code)?.[0] ?? null;
80
+ }
@@ -66,11 +66,13 @@ export function loadOptionsEntry(options: {
66
66
  const attempt = createAttempt(dataProvider.id, startedAt, "unsupported", "UNSUPPORTED_RANGE", "Options are not available");
67
67
  return store.update(key, (current) => errorEntry(current, attempt));
68
68
  }
69
+ // This path has no handle on the provider's cache, so a refresh it asks for must reach the source, and a
70
+ // stored chain past its stale time (kept for two days) is refetched rather than shown as current.
69
71
  const data = await dataProvider.getOptionsChain(
70
72
  request.instrument.symbol,
71
73
  request.instrument.exchange ?? "",
72
74
  request.expirationDate,
73
- toMarketDataContext(request.instrument),
75
+ { ...toMarketDataContext(request.instrument), cacheMode: forceRefresh ? "refresh" : "current" },
74
76
  );
75
77
  const attempts = [createAttempt(dataProvider.id, startedAt, data.expirationDates.length > 0 ? "success" : "empty", data.expirationDates.length === 0 ? "NO_DATA" : undefined)];
76
78
  return store.update(key, (current) => ({
@@ -61,8 +61,10 @@ export function normalizeFreshChartData(
61
61
  : request.granularity === "detail" ? request.barSize : undefined;
62
62
  const session = parseHistorySession(history?.session, { symbol: target.symbol, exchange: target.exchange ?? "",
63
63
  interval: interval ?? undefined }) ?? undefined;
64
+ // A listing that no longer trades ends on its last session for good.
64
65
  if (
65
- isIntradayChartRequest(request, history)
66
+ !history?.delisting
67
+ && isIntradayChartRequest(request, history)
66
68
  && isPriceHistoryStaleForCurrentWindow(normalized, Date.now(), { symbol: target.symbol, exchange: target.exchange,
67
69
  intervalMs: interval ? priceHistoryIntervalMs(interval) : undefined, session, fetchedAt: fetchedAt ?? undefined })
68
70
  ) {
@@ -45,6 +45,8 @@ export interface FuturesContract {
45
45
  * index, and RS1, MES, MYM, M2K, MCL, MNG and HH are listed abroad.
46
46
  */
47
47
  bareCode?: true;
48
+ /** Everyday names the board's own does not hold: oil is WTI crude, not heating or soybean oil. */
49
+ aliases?: readonly string[];
48
50
  }
49
51
 
50
52
  /** 0.005 -> 3, 0.25 -> 2, 1 -> 0. Written for ticks, not general numbers. */
@@ -100,7 +102,7 @@ export const FUTURES_CONTRACTS: FuturesContract[] = [
100
102
  { symbol: "ZB=F", code: "ZB", name: "30-Year T-Bond", sector: "rates", venue: "CBT", bareCode: true },
101
103
  { symbol: "UB=F", code: "UB", name: "Ultra T-Bond", sector: "rates", venue: "CBT", bareCode: true },
102
104
 
103
- { symbol: "CL=F", code: "CL", name: "WTI Crude Oil", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.01 },
105
+ { symbol: "CL=F", code: "CL", name: "WTI Crude Oil", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.01, aliases: ["oil"] },
104
106
  { symbol: "BZ=F", code: "BZ", name: "Brent Crude Oil", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.01 },
105
107
  { symbol: "NG=F", code: "NG", name: "Natural Gas", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.001 },
106
108
  // Quoted in euros per MWh.
@@ -197,6 +199,41 @@ export function futuresBoardContract(value: unknown): FuturesContract | null {
197
199
  return BY_SYMBOL.get(typed(value)) ?? futuresContractByCode(value);
198
200
  }
199
201
 
202
+ const nameWords = (text: string) => text.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
203
+
204
+ /**
205
+ * The item a typed name means: every word of it starts a word of the item's
206
+ * name ("orange juice", "sugar" for Sugar #11, "soybean" for Soybeans). Among
207
+ * those that match, the name with the fewest other words wins, then the
208
+ * list's order: "crude" is WTI before Brent and the micro, "yen" the Japanese
209
+ * yen before the Nikkei quoted in yen. A name of fewer than three letters
210
+ * matches nothing, so a slip of a code does not land on a random row.
211
+ */
212
+ export function bestNameMatch<T>(items: readonly T[], names: (item: T) => readonly string[], value: unknown): T | null {
213
+ const wanted = typeof value === "string" ? nameWords(value) : [];
214
+ if (wanted.join("").length < 3) return null;
215
+ let best: T | null = null;
216
+ let fewest = Number.POSITIVE_INFINITY;
217
+ for (const item of items) {
218
+ for (const name of names(item)) {
219
+ const have = nameWords(name);
220
+ if (have.length >= fewest || !wanted.every((word) => have.some((part) => part.startsWith(word)))) continue;
221
+ best = item;
222
+ fewest = have.length;
223
+ }
224
+ }
225
+ return best;
226
+ }
227
+
228
+ /**
229
+ * The board row a commodity's name stands for, as a reader types it into a
230
+ * futures function: cocoa, coffee, sugar, cotton, orange juice, gold, copper,
231
+ * crude, natural gas. Codes and symbols are `futuresBoardContract`'s.
232
+ */
233
+ export function futuresContractByName(value: unknown): FuturesContract | null {
234
+ return bestNameMatch(FUTURES_CONTRACTS, (contract) => [contract.name, ...contract.aliases ?? []], value);
235
+ }
236
+
200
237
  /**
201
238
  * The future a bare symbol typed for a security stands for: a code no listed
202
239
  * security answers to (TTF is TTF=F). Null for every other symbol, and for a