gloomberb 0.18.2 → 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 (954) 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/patches/electrobun@1.18.1.patch +106 -5
  6. package/src/account/checkout-handoff.tsx +225 -0
  7. package/src/account/device-signin-dialog.tsx +2 -2
  8. package/src/account/device-signin.ts +2 -2
  9. package/src/account/upgrade-dialog.tsx +1 -1
  10. package/src/api-client/askg.ts +2 -2
  11. package/src/api-client/auth.ts +2 -2
  12. package/src/api-client/central-bank-rates.ts +6 -0
  13. package/src/api-client/collections.ts +5 -1
  14. package/src/api-client/cot.ts +2 -0
  15. package/src/api-client/crypto-etf-flows.ts +37 -0
  16. package/src/api-client/crypto-markets.ts +60 -0
  17. package/src/api-client/data.ts +99 -5
  18. package/src/api-client/doe.ts +15 -0
  19. package/src/api-client/equity-screener.ts +28 -0
  20. package/src/api-client/exchange-announcements.ts +38 -0
  21. package/src/api-client/fund-facts.ts +39 -0
  22. package/src/api-client/futures-curve.ts +9 -1
  23. package/src/api-client/hiring.ts +301 -0
  24. package/src/api-client/index.ts +24 -5
  25. package/src/api-client/market-discovery.ts +14 -0
  26. package/src/api-client/members.ts +6 -0
  27. package/src/api-client/mna.ts +6 -0
  28. package/src/api-client/paths.ts +18 -1
  29. package/src/api-client/request.ts +26 -7
  30. package/src/api-client/short-side-publications.ts +37 -0
  31. package/src/api-client/socket.ts +64 -4
  32. package/src/api-client/swap-curve.ts +35 -0
  33. package/src/api-client/telemetry.ts +17 -0
  34. package/src/api-client/themes.ts +7 -1
  35. package/src/api-client/types.ts +90 -2
  36. package/src/app/global-shortcuts.ts +1 -16
  37. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  38. package/src/app/runtime/desktop-deeplink.ts +5 -5
  39. package/src/app/runtime/plugin-bindings.ts +2 -2
  40. package/src/app/runtime/startup.ts +13 -0
  41. package/src/app/runtime/update.ts +28 -8
  42. package/src/app/star-prompt/status-line.tsx +2 -2
  43. package/src/architecture/core-builtin-allowlist.json +5 -2
  44. package/src/architecture/pane-tabs-allowlist.json +65 -0
  45. package/src/architecture/ui-literals-allowlist.json +3 -3
  46. package/src/architecture/ui-tokens-allowlist.json +1 -1
  47. package/src/brokers/broker-portfolio-sync.ts +37 -0
  48. package/src/brokers/directory.ts +11 -0
  49. package/src/brokers/logos.ts +3 -1
  50. package/src/brokers/signed-in/adapter.ts +304 -26
  51. package/src/brokers/signed-in/client.ts +14 -2
  52. package/src/brokers/signed-in/connect.ts +10 -2
  53. package/src/brokers/sync-broker-instance.ts +9 -1
  54. package/src/capabilities/chart-series.ts +22 -6
  55. package/src/cli/bank-section.ts +1 -1
  56. package/src/cli/base-converter.ts +23 -14
  57. package/src/cli/central-bank-events.ts +1 -1
  58. package/src/cli/command-options.ts +59 -4
  59. package/src/cli/commands/api.ts +9 -6
  60. package/src/cli/commands/broker.ts +2 -2
  61. package/src/cli/commands/command-utils.ts +2 -2
  62. package/src/cli/commands/crypto-hints.ts +7 -20
  63. package/src/cli/commands/fred-series.ts +4 -2
  64. package/src/cli/commands/keybindings.ts +2 -2
  65. package/src/cli/commands/market.ts +1189 -296
  66. package/src/cli/commands/news-hints.ts +2 -2
  67. package/src/cli/commands/news-search.ts +59 -6
  68. package/src/cli/commands/options-leaps.ts +41 -26
  69. package/src/cli/commands/overview.ts +121 -48
  70. package/src/cli/commands/plugins.ts +9 -9
  71. package/src/cli/commands/remote.ts +13 -10
  72. package/src/cli/commands/search.ts +64 -44
  73. package/src/cli/commands/system.ts +27 -19
  74. package/src/cli/commands/themes.ts +1 -1
  75. package/src/cli/commands/ticker.ts +272 -70
  76. package/src/cli/context.ts +3 -2
  77. package/src/cli/desktop-pane-shot-view.ts +2 -2
  78. package/src/cli/desktop-pane-shot.ts +1 -1
  79. package/src/cli/earnings-calendar.ts +4 -4
  80. package/src/cli/entry.ts +18 -1
  81. package/src/cli/errors.ts +20 -2
  82. package/src/cli/exit-codes.ts +1 -1
  83. package/src/cli/export-source.ts +10 -4
  84. package/src/cli/freshness.ts +2 -8
  85. package/src/cli/fx-forward.ts +130 -0
  86. package/src/cli/fx-pair.ts +10 -9
  87. package/src/cli/glossary.ts +64 -20
  88. package/src/cli/help.ts +20 -14
  89. package/src/cli/history-export.ts +126 -0
  90. package/src/cli/history-rows.ts +196 -43
  91. package/src/cli/index-roots.ts +5 -45
  92. package/src/cli/index.ts +32 -18
  93. package/src/cli/issuer-membership.ts +103 -0
  94. package/src/cli/known-gaps.ts +118 -25
  95. package/src/cli/listing-arg.ts +315 -43
  96. package/src/cli/name-entries.ts +73 -22
  97. package/src/cli/native-smoke.ts +2 -0
  98. package/src/cli/not-a-ticker.ts +19 -9
  99. package/src/cli/opentui-libc.ts +5 -0
  100. package/src/cli/options.ts +12 -0
  101. package/src/cli/pane-functions/capabilities.ts +77 -20
  102. package/src/cli/pane-functions/catalog.ts +40 -23
  103. package/src/cli/pane-functions/discovery.ts +1 -1
  104. package/src/cli/pane-functions/dom.ts +12 -8
  105. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  106. package/src/cli/pane-functions/freshness.ts +174 -23
  107. package/src/cli/pane-functions/function-help.ts +66 -27
  108. package/src/cli/pane-functions/headless.ts +48 -16
  109. package/src/cli/pane-functions/index.ts +82 -21
  110. package/src/cli/pane-functions/options.ts +22 -2
  111. package/src/cli/pane-functions/report-notices.ts +12 -4
  112. package/src/cli/pane-functions/report.ts +5 -5
  113. package/src/cli/pane-functions/resolver.ts +65 -14
  114. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  115. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  116. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  117. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  118. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  119. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  120. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  121. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  122. package/src/cli/pane-functions/shot-options.ts +8 -3
  123. package/src/cli/peso-dollar-rates.ts +79 -0
  124. package/src/cli/quote-answer.ts +38 -3
  125. package/src/cli/report-tables.ts +190 -27
  126. package/src/cli/restore-plugins.ts +29 -14
  127. package/src/cli/result.ts +122 -25
  128. package/src/cli/series-search.ts +5 -5
  129. package/src/cli/statement-filings.ts +19 -0
  130. package/src/cli/suffixed-listing-rows.ts +49 -0
  131. package/src/cli/symbol-args.ts +50 -15
  132. package/src/cli/symbol-cells.ts +120 -0
  133. package/src/cli/symbol-list.ts +226 -60
  134. package/src/cli/symbol-rows.ts +131 -25
  135. package/src/cli/ticker-resolution.ts +108 -11
  136. package/src/cli/treasury-yields.ts +5 -5
  137. package/src/cli/types.ts +2 -0
  138. package/src/cli/uncovered-instrument.ts +3 -3
  139. package/src/cli/unknown-command.ts +6 -6
  140. package/src/components/chart/composite/chart-layout.ts +131 -0
  141. package/src/components/chart/composite/composite-chart.tsx +387 -21
  142. package/src/components/chart/composite/drawing-store.ts +26 -6
  143. package/src/components/chart/composite/interactions.ts +9 -3
  144. package/src/components/chart/composite/legend.tsx +75 -3
  145. package/src/components/chart/composite/levels.ts +5 -0
  146. package/src/components/chart/composite/panel-gestures.ts +41 -0
  147. package/src/components/chart/composite/panel-labels.ts +2 -1
  148. package/src/components/chart/composite/panel-surface.tsx +316 -11
  149. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  150. package/src/components/chart/composite/rasterizer.ts +44 -19
  151. package/src/components/chart/composite/scene.ts +16 -4
  152. package/src/components/chart/composite/text-renderer.ts +48 -21
  153. package/src/components/chart/composite/toolbar.tsx +52 -5
  154. package/src/components/chart/composite/types.ts +19 -0
  155. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  156. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  157. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  158. package/src/components/chart/composite/value-scale.ts +149 -0
  159. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  160. package/src/components/chart/core/pointer.ts +2 -0
  161. package/src/components/chart-table/index.ts +2 -0
  162. package/src/components/chart-table/read.tsx +74 -0
  163. package/src/components/command-bar/commands/collection-list.ts +41 -19
  164. package/src/components/command-bar/commands/collection.ts +9 -3
  165. package/src/components/command-bar/commands/direct/index.ts +1 -1
  166. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  167. package/src/components/command-bar/pane-templates/items.ts +59 -6
  168. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  169. package/src/components/command-bar/routes/root/command-items.ts +32 -6
  170. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  171. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  172. package/src/components/command-bar/routes/root/results.ts +18 -4
  173. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  174. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  175. package/src/components/command-bar/routes/root/selection.ts +6 -1
  176. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  177. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  178. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  179. package/src/components/command-bar/selection-runtime.ts +50 -10
  180. package/src/components/command-bar/surface/index.tsx +24 -2
  181. package/src/components/command-bar/view-model.ts +7 -0
  182. package/src/components/command-bar/workflow/broker.ts +2 -2
  183. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  184. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  185. package/src/components/command-bar/workflow/fields.ts +8 -2
  186. package/src/components/command-bar/workflow/ops.ts +18 -4
  187. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  188. package/src/components/command-bar/workflow/submit.ts +3 -2
  189. package/src/components/command-bar/workflow/tickers.ts +5 -1
  190. package/src/components/company-logo.tsx +39 -0
  191. package/src/components/data-table/sections.ts +4 -2
  192. package/src/components/data-table/view.tsx +23 -3
  193. package/src/components/form-modal/confirm.tsx +2 -1
  194. package/src/components/form-modal/request.ts +5 -0
  195. package/src/components/form-modal/routes.ts +4 -1
  196. package/src/components/index.ts +13 -6
  197. package/src/components/layout/detached-pane-shell.tsx +1 -0
  198. package/src/components/layout/floating-pane.tsx +1 -0
  199. package/src/components/layout/header.tsx +234 -60
  200. package/src/components/layout/market-summary.ts +9 -6
  201. package/src/components/layout/pane/capture-status.ts +1 -1
  202. package/src/components/layout/pane/footer/model.ts +11 -5
  203. package/src/components/layout/pane/header.tsx +10 -3
  204. package/src/components/layout/pane/index.tsx +1 -0
  205. package/src/components/layout/pane/pane-tabs.tsx +9 -1
  206. package/src/components/layout/shell/chrome.ts +19 -6
  207. package/src/components/layout/shell/index.tsx +2 -1
  208. package/src/components/layout/shell/pane/layers.tsx +19 -1
  209. package/src/components/layout/status-bar.tsx +2 -2
  210. package/src/components/market-board/index.tsx +11 -3
  211. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  212. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  213. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  214. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  215. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  216. package/src/components/pane-settings-dialog/value.ts +8 -1
  217. package/src/components/pane-settings-dialog.tsx +44 -13
  218. package/src/components/sign-in-code-panel.tsx +27 -19
  219. package/src/components/ui/column-grid.tsx +48 -4
  220. package/src/components/ui/country-flag-art.tsx +180 -0
  221. package/src/components/ui/country-flag.tsx +118 -12
  222. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  223. package/src/components/ui/data-table/opentui/model.ts +109 -2
  224. package/src/components/ui/data-table/types.ts +1 -1
  225. package/src/components/ui/display.tsx +5 -1
  226. package/src/components/ui/index.ts +3 -1
  227. package/src/components/ui/logo-mark.tsx +11 -2
  228. package/src/components/ui/query-bar.tsx +1 -1
  229. package/src/components/ui/row-notes.ts +79 -0
  230. package/src/components/ui/stat-grid.tsx +28 -3
  231. package/src/components/ui/status.tsx +3 -1
  232. package/src/core/app-services.ts +4 -0
  233. package/src/core/state/app/layout.ts +4 -4
  234. package/src/data/cached-query.ts +8 -1
  235. package/src/data/config/chart-settings.ts +3 -3
  236. package/src/data/config/home.ts +10 -2
  237. package/src/data/config/layout.ts +4 -1
  238. package/src/data/config/store/node.ts +4 -0
  239. package/src/data/config/store/normalize.ts +13 -3
  240. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  241. package/src/data/json-storage.ts +2 -0
  242. package/src/data/saved-copies.ts +84 -0
  243. package/src/docs/snapshot.json +65 -32
  244. package/src/i18n/es.ts +51 -12
  245. package/src/i18n/ja.ts +51 -12
  246. package/src/i18n/ko.ts +51 -12
  247. package/src/i18n/zh-cn.ts +51 -12
  248. package/src/i18n/zh-tw.ts +51 -12
  249. package/src/layout/desks.ts +1 -1
  250. package/src/layout/launch-layout.ts +1 -1
  251. package/src/layout/pane-manager/floating-actions.ts +5 -3
  252. package/src/layout/pane-manager/floating.ts +43 -1
  253. package/src/layout/pane-manager/index.ts +2 -0
  254. package/src/layout/selected-ticker.ts +74 -0
  255. package/src/market-data/depositary-pair.ts +251 -0
  256. package/src/market-data/futures-board.ts +1 -1
  257. package/src/market-data/futures-contract.ts +124 -40
  258. package/src/market-data/fx-closes.ts +17 -2
  259. package/src/market-data/hooks.tsx +19 -11
  260. package/src/market-data/market/change-basis.ts +49 -7
  261. package/src/market-data/market/freshness.ts +34 -5
  262. package/src/market-data/market/period-return.ts +163 -0
  263. package/src/market-data/market/trading-sessions.ts +13 -0
  264. package/src/market-data/market/year-to-date.ts +8 -13
  265. package/src/market-data/performance.ts +20 -14
  266. package/src/market-data/perpetual-premium.ts +32 -0
  267. package/src/market-data/published-apac-sessions.ts +2 -1
  268. package/src/market-data/published-futures-sessions.ts +69 -0
  269. package/src/market-data/quotes/contributions.ts +5 -1
  270. package/src/market-data/quotes/freshness.ts +42 -0
  271. package/src/market-data/quotes/intraday-bar.ts +37 -0
  272. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  273. package/src/market-data/quotes/resolution.ts +4 -2
  274. package/src/market-data/tax-equivalent.ts +1 -1
  275. package/src/market-data/ticker-price-returns.ts +3 -1
  276. package/src/news/aggregator.ts +5 -1
  277. package/src/news/news-model.ts +4 -0
  278. package/src/news/types.ts +11 -0
  279. package/src/notifications/app-notifier.ts +1 -1
  280. package/src/plugins/auto-update.ts +2 -2
  281. package/src/plugins/builtin/account-management/index.tsx +1 -0
  282. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  283. package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
  284. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  285. package/src/plugins/builtin/alerts/cli.ts +485 -76
  286. package/src/plugins/builtin/alerts/command.ts +5 -10
  287. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  288. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  289. package/src/plugins/builtin/alerts/events.ts +108 -5
  290. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  291. package/src/plugins/builtin/alerts/format.ts +2 -1
  292. package/src/plugins/builtin/alerts/headless.ts +100 -39
  293. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  294. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  295. package/src/plugins/builtin/alerts/index.tsx +45 -18
  296. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  297. package/src/plugins/builtin/alerts/levels.ts +3 -3
  298. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  299. package/src/plugins/builtin/alerts/price.ts +35 -0
  300. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  301. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  302. package/src/plugins/builtin/alerts/research-rules.ts +77 -3
  303. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  304. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  305. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  306. package/src/plugins/builtin/alerts/storage.ts +13 -10
  307. package/src/plugins/builtin/alerts/targets.ts +12 -3
  308. package/src/plugins/builtin/analytics/index.tsx +8 -2
  309. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  310. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  311. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  312. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  313. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  314. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  315. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  316. package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
  317. package/src/plugins/builtin/attention/pane.tsx +22 -16
  318. package/src/plugins/builtin/awards/headless.ts +7 -3
  319. package/src/plugins/builtin/awards/model.ts +18 -0
  320. package/src/plugins/builtin/awards/pane.tsx +12 -9
  321. package/src/plugins/builtin/backtest/export.ts +1 -1
  322. package/src/plugins/builtin/backtest/headless.ts +3 -3
  323. package/src/plugins/builtin/backtest/rules.ts +41 -5
  324. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  325. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  326. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  327. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  328. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  329. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  330. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  331. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  332. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  333. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  334. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  335. package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
  336. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  337. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  338. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  339. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  340. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  341. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  342. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  343. package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
  344. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  345. package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
  346. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  347. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  348. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  349. package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
  350. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  351. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  352. package/src/plugins/builtin/catalysts/client.ts +2 -2
  353. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  354. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  355. package/src/plugins/builtin/catalysts/model.ts +49 -4
  356. package/src/plugins/builtin/catalysts/pane.tsx +9 -11
  357. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  358. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  359. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  360. package/src/plugins/builtin/changelog/index.tsx +1 -0
  361. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  362. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  363. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  364. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  365. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  366. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  367. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  368. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  369. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  370. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  371. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  372. package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
  373. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  374. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  375. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  376. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  377. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  378. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  379. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  380. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  381. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  382. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  383. package/src/plugins/builtin/chat/people.ts +1 -1
  384. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  385. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  386. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  387. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  388. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  389. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  390. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  391. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  392. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  393. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  394. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  395. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  396. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  397. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  398. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  399. package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
  400. package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
  401. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  402. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  403. package/src/plugins/builtin/company-attention/client.ts +117 -1
  404. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  405. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  406. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  407. package/src/plugins/builtin/company-attention/model.ts +33 -7
  408. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  409. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  410. package/src/plugins/builtin/company-attention/pane.tsx +89 -31
  411. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  412. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  413. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  414. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  415. package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
  416. package/src/plugins/builtin/composite-plugins.ts +2 -1
  417. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  418. package/src/plugins/builtin/connections/index.ts +1 -0
  419. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  420. package/src/plugins/builtin/correlation/headless.ts +7 -4
  421. package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
  422. package/src/plugins/builtin/correlation/settings.ts +1 -0
  423. package/src/plugins/builtin/cot/headless.ts +28 -6
  424. package/src/plugins/builtin/cot/model.ts +12 -0
  425. package/src/plugins/builtin/cot/pane.tsx +7 -5
  426. package/src/plugins/builtin/cpi/headless.ts +5 -1
  427. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  428. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  429. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  430. package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
  431. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  432. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  433. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  434. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  435. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  436. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  437. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  438. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  439. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  440. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  441. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  442. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  443. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  444. package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
  445. package/src/plugins/builtin/debug/index.tsx +1 -0
  446. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  447. package/src/plugins/builtin/docs/index.tsx +1 -1
  448. package/src/plugins/builtin/docs/pane.tsx +2 -2
  449. package/src/plugins/builtin/docs/targets.ts +1 -1
  450. package/src/plugins/builtin/doe/client.ts +5 -1
  451. package/src/plugins/builtin/doe/headless.ts +12 -6
  452. package/src/plugins/builtin/doe/model.ts +43 -6
  453. package/src/plugins/builtin/doe/pane.tsx +19 -12
  454. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  455. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  456. package/src/plugins/builtin/earnings/board.tsx +253 -50
  457. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  458. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  459. package/src/plugins/builtin/earnings/client.ts +4 -3
  460. package/src/plugins/builtin/earnings/headless.ts +53 -15
  461. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  462. package/src/plugins/builtin/earnings/index.tsx +15 -22
  463. package/src/plugins/builtin/earnings/model.ts +17 -12
  464. package/src/plugins/builtin/earnings/scope.ts +89 -0
  465. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  466. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  467. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  468. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  469. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  470. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  471. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  472. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  473. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  474. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  475. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  476. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  477. package/src/plugins/builtin/econ/index.tsx +112 -25
  478. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  479. package/src/plugins/builtin/econ/types.ts +32 -1
  480. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  481. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  482. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  483. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  484. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  485. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  486. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  487. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  488. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  489. package/src/plugins/builtin/equity-screener/headless.ts +77 -5
  490. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  491. package/src/plugins/builtin/equity-screener/model.ts +34 -0
  492. package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
  493. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  494. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  495. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  496. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  497. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  498. package/src/plugins/builtin/exposure/headless.ts +51 -6
  499. package/src/plugins/builtin/exposure/index.tsx +28 -2
  500. package/src/plugins/builtin/exposure/model.ts +7 -0
  501. package/src/plugins/builtin/exposure/pane.tsx +16 -10
  502. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  503. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  504. package/src/plugins/builtin/futures/model.ts +10 -9
  505. package/src/plugins/builtin/futures/returns.ts +8 -36
  506. package/src/plugins/builtin/futures/table.tsx +1 -1
  507. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  508. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  509. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  510. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  511. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  512. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  513. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  514. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  515. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  516. package/src/plugins/builtin/gpu/board.tsx +4 -1
  517. package/src/plugins/builtin/gpu/changes.tsx +10 -10
  518. package/src/plugins/builtin/gpu/equities.tsx +4 -1
  519. package/src/plugins/builtin/gpu/headless.ts +9 -4
  520. package/src/plugins/builtin/gpu/history.tsx +4 -2
  521. package/src/plugins/builtin/gpu/pane.tsx +5 -3
  522. package/src/plugins/builtin/help/index.tsx +13 -3
  523. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  524. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  525. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  526. package/src/plugins/builtin/holders/client.ts +15 -2
  527. package/src/plugins/builtin/holders/format.ts +28 -17
  528. package/src/plugins/builtin/holders/headless.ts +48 -8
  529. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  530. package/src/plugins/builtin/holders/pane.tsx +79 -15
  531. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  532. package/src/plugins/builtin/holders/table-model.ts +2 -1
  533. package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
  534. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  535. package/src/plugins/builtin/insider/base-values.ts +11 -7
  536. package/src/plugins/builtin/insider/client.ts +3 -0
  537. package/src/plugins/builtin/insider/headless.ts +20 -7
  538. package/src/plugins/builtin/insider/index.tsx +17 -8
  539. package/src/plugins/builtin/insider/issuer.ts +34 -4
  540. package/src/plugins/builtin/insider/signals-client.ts +3 -3
  541. package/src/plugins/builtin/insider/signals.tsx +1 -1
  542. package/src/plugins/builtin/insider/table-model.ts +35 -13
  543. package/src/plugins/builtin/insider/table.tsx +5 -2
  544. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  545. package/src/plugins/builtin/iv-history/client.ts +20 -0
  546. package/src/plugins/builtin/iv-history/events.ts +145 -0
  547. package/src/plugins/builtin/iv-history/format.ts +3 -0
  548. package/src/plugins/builtin/iv-history/headless.ts +91 -7
  549. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  550. package/src/plugins/builtin/iv-history/model.ts +13 -4
  551. package/src/plugins/builtin/iv-history/series.ts +3 -1
  552. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  553. package/src/plugins/builtin/jobs/model.ts +4 -15
  554. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  555. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  556. package/src/plugins/builtin/jodi/pane.tsx +14 -8
  557. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  558. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  559. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  560. package/src/plugins/builtin/macro-day/model.ts +29 -8
  561. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  562. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  563. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  564. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  565. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  566. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  567. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  568. package/src/plugins/builtin/market-movers/client.ts +36 -21
  569. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  570. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  571. package/src/plugins/builtin/market-movers/screener.ts +33 -11
  572. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  573. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  574. package/src/plugins/builtin/market-movers/table.ts +4 -1
  575. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  576. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  577. package/src/plugins/builtin/members/headless.ts +6 -5
  578. package/src/plugins/builtin/members/pane.tsx +11 -4
  579. package/src/plugins/builtin/mna/client.ts +1 -0
  580. package/src/plugins/builtin/mna/detail.tsx +20 -32
  581. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  582. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  583. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  584. package/src/plugins/builtin/mna/headless.ts +6 -13
  585. package/src/plugins/builtin/mna/model.ts +93 -15
  586. package/src/plugins/builtin/mna/pane.tsx +5 -4
  587. package/src/plugins/builtin/news/headless.ts +12 -6
  588. package/src/plugins/builtin/news/index.tsx +10 -1
  589. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  590. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  591. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  592. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  593. package/src/plugins/builtin/notes/cli.ts +50 -15
  594. package/src/plugins/builtin/notes/export.ts +17 -6
  595. package/src/plugins/builtin/notes/files.ts +16 -5
  596. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  597. package/src/plugins/builtin/options/carry.ts +2 -2
  598. package/src/plugins/builtin/options/enrichment-model.ts +10 -9
  599. package/src/plugins/builtin/options/index.tsx +1 -1
  600. package/src/plugins/builtin/options/model-spot.ts +70 -4
  601. package/src/plugins/builtin/options/view.tsx +51 -23
  602. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  603. package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
  604. package/src/plugins/builtin/options-positioning/headless.ts +11 -3
  605. package/src/plugins/builtin/options-positioning/model.ts +24 -0
  606. package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
  607. package/src/plugins/builtin/options-scenario/client.ts +142 -29
  608. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  609. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  610. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  611. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  612. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  613. package/src/plugins/builtin/options-scenario/headless.ts +49 -21
  614. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  615. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  616. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  617. package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
  618. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  619. package/src/plugins/builtin/perps/freshness.ts +8 -5
  620. package/src/plugins/builtin/perps/headless.ts +3 -1
  621. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  622. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  623. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  624. package/src/plugins/builtin/perps/pane.tsx +36 -17
  625. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  626. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  627. package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
  628. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
  629. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  630. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  631. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  632. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  633. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  634. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  635. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  636. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  637. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  638. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  639. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  640. package/src/plugins/builtin/power/client.ts +6 -3
  641. package/src/plugins/builtin/power/evidence.ts +22 -7
  642. package/src/plugins/builtin/power/gas.tsx +5 -1
  643. package/src/plugins/builtin/power/pane.tsx +44 -32
  644. package/src/plugins/builtin/power/prices.tsx +10 -3
  645. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  646. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  647. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  648. package/src/plugins/builtin/research/event-model.ts +3 -1
  649. package/src/plugins/builtin/research/event-sources.ts +12 -4
  650. package/src/plugins/builtin/research/index.tsx +2 -1
  651. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  652. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  653. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  654. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  655. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  656. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  657. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  658. package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
  659. package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
  660. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  661. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  662. package/src/plugins/builtin/seasonality/client.ts +2 -1
  663. package/src/plugins/builtin/sec/forms.ts +13 -0
  664. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  665. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  666. package/src/plugins/builtin/sec/headless.ts +85 -8
  667. package/src/plugins/builtin/sec/index.tsx +58 -12
  668. package/src/plugins/builtin/sectors/client.ts +6 -4
  669. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  670. package/src/plugins/builtin/series-inventory.ts +2 -0
  671. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  672. package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
  673. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  674. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  675. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  676. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  677. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  678. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  679. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  680. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  681. package/src/plugins/builtin/shared/research-trading.tsx +23 -0
  682. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  683. package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
  684. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  685. package/src/plugins/builtin/shared/volatility/options.ts +2 -1
  686. package/src/plugins/builtin/short-interest/client.ts +2 -0
  687. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  688. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  689. package/src/plugins/builtin/short-interest/model.ts +70 -19
  690. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  691. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  692. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  693. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  694. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  695. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  696. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  697. package/src/plugins/builtin/short-interest/types.ts +9 -0
  698. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  699. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  700. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  701. package/src/plugins/builtin/social-mentions/client.ts +2 -1
  702. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  703. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  704. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  705. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  706. package/src/plugins/builtin/themes/headless.ts +8 -5
  707. package/src/plugins/builtin/themes/model.ts +14 -4
  708. package/src/plugins/builtin/themes/pane.tsx +24 -5
  709. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  710. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  711. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  712. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  713. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  714. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  715. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  716. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  717. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  718. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  719. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  720. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  721. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  722. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  723. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  724. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  725. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  726. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  727. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  728. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  729. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  730. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  731. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  732. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  733. package/src/plugins/builtin/vol-surface/client.ts +28 -7
  734. package/src/plugins/builtin/vol-surface/headless.ts +43 -15
  735. package/src/plugins/builtin/vol-surface/model.ts +34 -12
  736. package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
  737. package/src/plugins/builtin/vol-surface/stored.ts +34 -3
  738. package/src/plugins/builtin/vol-surface/tables.ts +14 -0
  739. package/src/plugins/builtin/volatility/model.ts +5 -10
  740. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  741. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  742. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  743. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  744. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  745. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  746. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  747. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  748. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  749. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  750. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  751. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  752. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  753. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  754. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  755. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  756. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  757. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  758. package/src/plugins/bundle.ts +1 -1
  759. package/src/plugins/catalog-browser.ts +2 -1
  760. package/src/plugins/compat.ts +3 -3
  761. package/src/plugins/dependencies.ts +75 -14
  762. package/src/plugins/extracted-plugins.ts +132 -34
  763. package/src/plugins/host-link.ts +149 -34
  764. package/src/plugins/installer.ts +35 -10
  765. package/src/plugins/loader.ts +206 -38
  766. package/src/plugins/manager-node.ts +2 -2
  767. package/src/plugins/marketplace/deactivation.ts +22 -0
  768. package/src/plugins/marketplace/model.ts +2 -2
  769. package/src/plugins/marketplace/packs.ts +1 -1
  770. package/src/plugins/ownership.ts +1 -1
  771. package/src/plugins/peer-retry.ts +155 -0
  772. package/src/plugins/registry/contributions.ts +3 -1
  773. package/src/plugins/registry/index.ts +4 -3
  774. package/src/plugins/registry/plugin-state.ts +3 -0
  775. package/src/plugins/seed-notice.ts +20 -0
  776. package/src/plugins/shortcut-argument.ts +39 -0
  777. package/src/portfolio/allocation.ts +1 -1
  778. package/src/portfolio/collection-name.ts +31 -0
  779. package/src/portfolio/column-values.ts +10 -8
  780. package/src/portfolio/cost-fx.ts +296 -19
  781. package/src/portfolio/manual-lots.ts +75 -0
  782. package/src/portfolio/mutations.ts +60 -22
  783. package/src/portfolio/suffixed-listings.ts +209 -0
  784. package/src/portfolio/totals-currency.ts +24 -0
  785. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  786. package/src/public/time-series.ts +11 -8
  787. package/src/remote/schema.ts +1 -1
  788. package/src/renderers/browser/config-host.ts +3 -0
  789. package/src/renderers/browser/main.tsx +23 -3
  790. package/src/renderers/dom/boot-frame-page.ts +187 -0
  791. package/src/renderers/dom/boot-frame.ts +237 -0
  792. package/src/renderers/dom/build-assets.ts +46 -8
  793. package/src/renderers/dom/desktop/controls.tsx +1 -1
  794. package/src/renderers/dom/desktop/query-bar.tsx +2 -0
  795. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  796. package/src/renderers/dom/host/ascii-text.ts +16 -2
  797. package/src/renderers/dom/host/box.tsx +43 -2
  798. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  799. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  800. package/src/renderers/dom/host/image-surface.tsx +49 -0
  801. package/src/renderers/dom/host/media-surface.tsx +24 -18
  802. package/src/renderers/dom/host/mouse.ts +30 -0
  803. package/src/renderers/dom/host/size-observer.ts +1 -1
  804. package/src/renderers/dom/host/style.ts +1 -1
  805. package/src/renderers/dom/host/tabs.tsx +16 -5
  806. package/src/renderers/dom/host/top-surface.ts +127 -0
  807. package/src/renderers/dom/styles.css +115 -0
  808. package/src/renderers/dom/test-utils.tsx +2 -1
  809. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  810. package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
  811. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  812. package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
  813. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  814. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  815. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  816. package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
  817. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  818. package/src/renderers/electrobun/bun/index.ts +11 -1
  819. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  820. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  821. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  822. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  823. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  824. package/src/renderers/electrobun/view/config-host.ts +3 -0
  825. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  826. package/src/renderers/electrobun/view/main.tsx +30 -4
  827. package/src/renderers/electrobun/view/news-source.ts +9 -7
  828. package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
  829. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  830. package/src/renderers/opentui/browser-open.ts +88 -0
  831. package/src/renderers/opentui/host.tsx +5 -14
  832. package/src/renderers/opentui/image/loader.ts +3 -2
  833. package/src/renderers/opentui/native-smoke.ts +10 -1
  834. package/src/renderers/opentui/pane-image/index.ts +2 -1
  835. package/src/renderers/opentui/render-lib.ts +253 -0
  836. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  837. package/src/renderers/opentui/start.tsx +8 -1
  838. package/src/renderers/share/layout-view.tsx +2 -2
  839. package/src/renderers/share/main.tsx +4 -4
  840. package/src/renderers/share/view.tsx +1 -1
  841. package/src/series/resolve.ts +22 -6
  842. package/src/series/standalone.ts +30 -2
  843. package/src/series/types.ts +8 -1
  844. package/src/shares/api.ts +4 -1
  845. package/src/shares/pane.ts +1 -1
  846. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  847. package/src/sources/gloomberb-cloud/index.ts +39 -16
  848. package/src/sources/gloomberb-cloud/news.ts +39 -0
  849. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  850. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  851. package/src/sources/listing-symbols.ts +37 -0
  852. package/src/sources/provider-errors.ts +16 -2
  853. package/src/sources/provider-router/financial-routes.ts +21 -3
  854. package/src/sources/provider-router/financials.ts +15 -2
  855. package/src/sources/provider-router/history.ts +30 -8
  856. package/src/sources/provider-router/index.ts +16 -0
  857. package/src/sources/provider-router/primary.ts +1 -1
  858. package/src/state/app/bootstrap.ts +23 -0
  859. package/src/state/hooks/inline-tickers.ts +30 -5
  860. package/src/sync/controller.ts +1 -1
  861. package/src/sync/core-contributors.ts +46 -14
  862. package/src/team/collections-sync.ts +2 -1
  863. package/src/team/collections.ts +178 -17
  864. package/src/telemetry/crash-reports.ts +21 -4
  865. package/src/telemetry/update-failures-node.ts +59 -0
  866. package/src/telemetry/update-failures.ts +307 -0
  867. package/src/test-support/builtin-panes.ts +1 -1
  868. package/src/theme/colors.ts +3 -30
  869. package/src/theme/ui-tokens.ts +37 -1
  870. package/src/tickers/company-name-listing.ts +215 -36
  871. package/src/tickers/company-name.ts +43 -0
  872. package/src/tickers/index-roots.ts +47 -0
  873. package/src/tickers/instrument-label.ts +5 -1
  874. package/src/tickers/listing-fate.ts +30 -0
  875. package/src/tickers/metadata.ts +10 -0
  876. package/src/tickers/perpetual-listing.ts +5 -2
  877. package/src/tickers/search/home-listing.ts +75 -0
  878. package/src/tickers/search/index.ts +76 -27
  879. package/src/tickers/search/ranking.ts +54 -4
  880. package/src/tickers/search/upsert.ts +29 -0
  881. package/src/tickers/terminal-codes.ts +416 -40
  882. package/src/time-series/bar-aggregation.ts +243 -0
  883. package/src/time-series/base-series.ts +307 -0
  884. package/src/time-series/chart-bounds.ts +349 -0
  885. package/src/time-series/chart-seed.ts +142 -0
  886. package/src/time-series/economic.ts +5 -0
  887. package/src/time-series/fundamentals.ts +18 -3
  888. package/src/time-series/history-acquisition.ts +499 -0
  889. package/src/time-series/leverage.ts +100 -0
  890. package/src/time-series/market-resolution.ts +4 -2
  891. package/src/time-series/market.ts +2 -1
  892. package/src/time-series/price-comparison.ts +175 -30
  893. package/src/time-series/range.ts +9 -1
  894. package/src/time-series/resolution.ts +174 -16
  895. package/src/time-series/resolve-context.ts +157 -0
  896. package/src/time-series/resolve.ts +126 -1577
  897. package/src/time-series/series-name.ts +38 -0
  898. package/src/time-series/series-presentation.ts +208 -0
  899. package/src/time-series/spec.ts +11 -6
  900. package/src/time-series/studies.ts +109 -12
  901. package/src/time-series/tail-reconcile.ts +121 -0
  902. package/src/time-series/types.ts +29 -2
  903. package/src/time-series/use-chart-resolution.ts +4 -5
  904. package/src/types/broker.ts +10 -0
  905. package/src/types/config.ts +14 -0
  906. package/src/types/data-provider.ts +20 -0
  907. package/src/types/exchange-rate.ts +6 -0
  908. package/src/types/financials.ts +104 -7
  909. package/src/types/headless.ts +83 -6
  910. package/src/types/instrument.ts +3 -0
  911. package/src/types/issuer-listings.ts +28 -0
  912. package/src/types/plugin.ts +65 -8
  913. package/src/types/price-history.ts +2 -0
  914. package/src/types/ticker.ts +13 -0
  915. package/src/types/trading.ts +59 -1
  916. package/src/ui/ascii-font.ts +13 -1
  917. package/src/ui/host.tsx +6 -1
  918. package/src/updater/command-names.ts +175 -0
  919. package/src/updater/failure.ts +163 -0
  920. package/src/updater/index.ts +97 -28
  921. package/src/utils/calendar-date.ts +32 -15
  922. package/src/utils/cash-runway.ts +241 -0
  923. package/src/utils/central-banks.ts +42 -0
  924. package/src/utils/cli-output.ts +259 -80
  925. package/src/utils/contract-month.ts +16 -0
  926. package/src/utils/crypto-pair.ts +61 -3
  927. package/src/utils/currency-pair.ts +26 -0
  928. package/src/utils/currency-units.ts +29 -0
  929. package/src/utils/datetime-format.ts +10 -0
  930. package/src/utils/debug-log.ts +1 -1
  931. package/src/utils/decimal-comma.ts +39 -6
  932. package/src/utils/exchange-announcements.ts +71 -0
  933. package/src/utils/exchange-rate-snapshot.ts +10 -0
  934. package/src/utils/financial-statements.ts +83 -4
  935. package/src/utils/format.ts +34 -16
  936. package/src/utils/fundamentals.ts +150 -34
  937. package/src/utils/fx-market-hours.ts +10 -1
  938. package/src/utils/latest-financial-period.ts +8 -0
  939. package/src/utils/linux-libc.ts +54 -0
  940. package/src/utils/market-capitalization.ts +111 -15
  941. package/src/utils/max-drawdown.ts +64 -0
  942. package/src/utils/network-failure.ts +83 -0
  943. package/src/utils/option-expiry.ts +139 -7
  944. package/src/utils/price-earnings.ts +11 -5
  945. package/src/utils/price-history.ts +18 -8
  946. package/src/utils/price-window.ts +131 -0
  947. package/src/utils/release-date.ts +47 -0
  948. package/src/utils/sec.ts +71 -0
  949. package/src/utils/throttled-fetch.ts +11 -4
  950. package/src/utils/trailing-eps.ts +67 -0
  951. package/src/utils/typed-text.ts +21 -0
  952. package/src/utils/utc-time.ts +24 -1
  953. package/src/version.ts +6 -0
  954. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -12,6 +12,9 @@ export const VCA_DEFINITIONS = [
12
12
  "VIX is Cboe's 30-day S&P 500 implied vol from the whole SPX strike strip, skew included; IV30 here is at the money, so VIX usually reads higher.",
13
13
  ] as const;
14
14
 
15
+ /** Words for implied volatility that are no function's code: `fn IVOL` names HIVG and OVDV, which list them as `suggestFor`. */
16
+ export const IMPLIED_VOL_WORDS = ["IVOL", "IV", "OVOL", "IMPVOL", "IMPLIEDVOL"];
17
+
15
18
  /**
16
19
  * A skew column's header names its sign, since the conventions differ: the
17
20
  * 25-delta skew is put minus call (HIVG, VCA), the risk reversal call minus
@@ -2,10 +2,19 @@ import type { HeadlessPaneDefinition } from "../../../types/plugin";
2
2
  import { resolveHeadlessInstrument } from "../shared/headless-market-data";
3
3
  import { createRealizedVolatilityDependencies, loadRealizedVolatilityHistory } from "../realized-vol/client";
4
4
  import { createHvDependencies, loadIvHistory, loadIvScreen, loadScreenVolatilities } from "./client";
5
- import { formatPoints, formatRank, formatSpot, formatStat, formatVol, readingLabel, sharedDates, skewHeader, VCA_DEFINITIONS, verdictLabel } from "./format";
5
+ import { formatPoints, formatRank, formatSpot, formatStat, formatVol, IMPLIED_VOL_WORDS, readingLabel, sharedDates, skewHeader, VCA_DEFINITIONS, verdictLabel } from "./format";
6
6
  import { HV_WINDOWS, type HvWindow, type IvLookback, type IvStatRow, projectIvHistory, projectRichCheap, type RichCheapRow, richCheapDates, screenCoverage, VCA_LIMIT, VCA_PRESETS } from "./model";
7
7
  import { vcaUniverse } from "./universe";
8
- import { listingFateNotes, loadListingFate, MovedSymbolError } from "../../../tickers/listing-fate";
8
+ import { offsetText, releaseOffsetRows } from "./events";
9
+ import { loadMacroReleases } from "../macro-day/client";
10
+ import { MACRO_EVENT_LABELS, MACRO_RELEASE_SOURCES, staleMacroReleasesNotice, US_MACRO_EVENT_KINDS, type MacroRelease, type UsMacroEventKind,
11
+ type MacroReleaseList } from "../macro-day/releases";
12
+ import { lookupScheduledDates } from "../alerts/scheduled";
13
+ import { fetchCpiBoard } from "../cpi/client";
14
+ import { fetchRatePath } from "../rate-path/client";
15
+ import type { HeadlessPaneContext } from "../../../types/headless";
16
+ import { zonedDateKey } from "../../../utils/zoned-date-time";
17
+ import { listingFateNotes, listingFateReport, loadListingFate, MovedSymbolError } from "../../../tickers/listing-fate";
9
18
  import { startTickerChangeLookup } from "../../../tickers/ticker-changes";
10
19
 
11
20
  const METHODOLOGY = "docs/research-data.md#implied-volatility-history";
@@ -17,23 +26,33 @@ export const ivHistoryHeadless: HeadlessPaneDefinition<"bundle"> = {
17
26
  usListingsOnly: "Implied volatility history",
18
27
  freshness: { status: "not-a-feed", basis: "daily implied volatility", cadence: "daily", observedKey: "date", oldest: null },
19
28
  describe: (args) => `HIVG ${args.symbols[0] ?? ""}`,
20
- discovery: { aliases: ["HIVG"], screenshotReadiness: "live-dom", dataRequirements: ["Cloud stored implied volatility", "Daily price history"],
29
+ discovery: { aliases: ["HIVG"], suggestFor: IMPLIED_VOL_WORDS, screenshotReadiness: "live-dom", dataRequirements: ["Cloud stored implied volatility", "Daily price history"],
21
30
  limitations: ["History starts February 2024 (daily option trade closes).", "Rank and percentile use trade-close readings only.",
22
31
  "IV1Y needs long-dated trades: it can start later, has gaps, and ranks from 60 prior sessions.",
23
32
  "skew25d (put-call) and rr25d (call-put) come from the daily quote captures and are blank before the first one."] },
24
33
  options: [
25
34
  { key: "lookback", type: "enum", values: [{ value: "1Y" }, { value: "2Y" }, { value: "ALL" }], defaultValue: "1Y", description: "Visible history" },
26
35
  { key: "hvWindow", type: "enum", values: HV_WINDOWS.map((window) => ({ value: String(window) })), defaultValue: "20", description: "Realized volatility window in sessions" },
36
+ { key: "event", type: "enum", aliases: ["release"], values: US_MACRO_EVENT_KINDS.map((value) => ({ value, ...value === "jobs" ? { aliases: ["nfp", "payrolls"] } : {} })),
37
+ description: "One row per release of this kind whose session at --offset has closed (the next scheduled FOMC or CPI included), in place of the daily history",
38
+ example: "--event fomc --offset -6", shot: { reportOnly: "lists the readings around past release days" } },
39
+ { key: "offset", type: "integer", minimum: -60, maximum: 60, defaultValue: 0,
40
+ description: "Sessions from each release with --event: 0 is the first session on or after the release day, -6 the sixth session before that",
41
+ example: "--event cpi --offset -1", shot: { reportOnly: "picks the session read around each release" } },
27
42
  ],
28
43
  async load(args, ctx) {
44
+ const event = typeof args.options.event === "string" && args.options.event ? args.options.event as UsMacroEventKind : null;
45
+ const offset = Number(args.options.offset) || 0;
46
+ if (!event && offset !== 0) throw new Error("--offset counts sessions from a release day: add --event fomc, cpi or jobs.");
29
47
  const instrument = await resolveHeadlessInstrument(ctx, args.symbols[0]!);
30
48
  // What became of the symbol, as `quote` reads it, looked up beside the figures: FB's are the fund listed
31
49
  // there now, TWTR stopped trading, and HFC, which became DINO, has none of its own.
32
50
  const changes = startTickerChangeLookup(ctx.marketData, instrument.symbol, instrument.exchange);
33
51
  const quote = ctx.marketData.getQuote(instrument.symbol, instrument.exchange ?? "").catch(() => null);
34
- const [payload, prices] = await Promise.all([
52
+ const [payload, prices, releases] = await Promise.all([
35
53
  loadIvHistory(instrument.symbol, { signal: ctx.signal }, ctx.apiClient),
36
54
  loadRealizedVolatilityHistory({ instrument, signal: ctx.signal }, createRealizedVolatilityDependencies(ctx.marketData)),
55
+ event ? eventReleases(event, ctx) : null,
37
56
  ]);
38
57
  const fate = await loadListingFate(instrument, ctx.marketData, { quote, changes });
39
58
  if (fate.moved) throw new MovedSymbolError(fate.moved);
@@ -57,11 +76,47 @@ export const ivHistoryHeadless: HeadlessPaneDefinition<"bundle"> = {
57
76
  const skewColumns = [{ key: "skew25d", header: skewHeader("skew25d", "put-call"), format: points },
58
77
  { key: "rr25d", header: skewHeader("rr25d", "call-put"), format: points }];
59
78
  const served = model.iv30.length > 0 || prices.history.length > 0;
60
- const fateNotes = listingFateNotes(fate, { served });
61
79
  // With nothing served, the fate is why: no "not a ticker" or missing-history errors beside it.
62
- const errors = !served && fateNotes.length > 0 ? []
63
- : [prices.error, ...model.warnings].filter((value): value is string => !!value);
80
+ const { notes: fateNotes, errors } = listingFateReport(fate, { served },
81
+ [prices.error, ...model.warnings].filter((value): value is string => !!value));
64
82
  const notes = [...fateNotes, ...[model.oneYearNote, model.skewNote].filter((note): note is string => !!note)];
83
+ if (event && releases) {
84
+ const lookback = String(args.options.lookback) as IvLookback;
85
+ const label = MACRO_EVENT_LABELS[event];
86
+ const offsets = releaseOffsetRows(model, releases.list.releases, event, offset, {
87
+ lookback, readThrough: payload.coverage?.backfilledThrough ?? null });
88
+ const plural = (count: number, one: string, many: string) => count === 1 ? one : many;
89
+ const eventNotes = [
90
+ offsets.beforeLookback > 0
91
+ ? `${offsets.beforeLookback} earlier ${label} ${plural(offsets.beforeLookback, "release is", "releases are")} outside the ${lookback} lookback; --lookback ALL adds ${plural(offsets.beforeLookback, "it", "them")}.` : null,
92
+ // Said once the lookback says nothing: the history's own start is then where the rows stop.
93
+ offsets.beforeHistory > 0 && offsets.beforeLookback === 0
94
+ ? `${offsets.beforeHistory} earlier ${label} ${plural(offsets.beforeHistory, "release predates", "releases predate")} the IV history, which starts ${offsets.historyStart}.` : null,
95
+ offsets.pending.length > 0
96
+ ? `Left out ${label} ${offsets.pending.join(", ")}: no closing reading yet for ${plural(offsets.pending.length, "its session", "their sessions")} at --offset ${offset}.` : null,
97
+ releases.upcomingNote,
98
+ staleMacroReleasesNotice(releases.list),
99
+ ].filter((note): note is string => !!note);
100
+ const eventColumns = [{ key: "releaseDate", header: "Release date" }, { key: "session", header: "Session" },
101
+ ...historyColumns.slice(1), ...skewColumns];
102
+ return {
103
+ sections: [{
104
+ title: `${label} releases, ${offsetText(offset)}`,
105
+ // The export names the release and the offset on every row, so files of several offsets or releases join.
106
+ columns: [{ key: "release", header: "Release" }, eventColumns[0]!, { key: "offset", header: "Offset (sessions)" }, ...eventColumns.slice(1)],
107
+ rows: offsets.rows.map(({ date, ...row }) => ({ ...row, session: date, release: label })),
108
+ textColumns: offsets.rows.some((row) => row.skew25d != null) ? eventColumns : eventColumns.slice(0, -skewColumns.length),
109
+ }],
110
+ complete: payload.status === "ready" && errors.length === 0,
111
+ unavailableSymbols: offsets.rows.some((row) => row.iv30 != null) ? [] : [instrument.symbol], errors,
112
+ ...(notes.length + eventNotes.length > 0 ? { notes: [...notes, ...eventNotes] } : {}),
113
+ // Dated by the history read, not by the newest release's session: an old release is no stale reading.
114
+ ...(model.asOf ? { freshness: { asOf: model.asOf } } : {}),
115
+ metadata: { status: payload.status, coverage: payload.coverage, event, offset, releasesThrough: releases.list.coveredThrough,
116
+ nextRelease: releases.upcoming,
117
+ releaseSource: MACRO_RELEASE_SOURCES[event], unit: "decimal annualized volatility", methodology: METHODOLOGY },
118
+ };
119
+ }
65
120
  return {
66
121
  sections: [
67
122
  { title: "Statistics", columns: [
@@ -153,3 +208,32 @@ export const ivScreenHeadless: HeadlessPaneDefinition<"bundle"> = {
153
208
  };
154
209
  },
155
210
  };
211
+
212
+ /**
213
+ * The releases of `event` HIVG reads around: the days MDAY studies (the list
214
+ * the app ships with, extended by Gloom Cloud's), and the next one scheduled,
215
+ * from the CPI board's release calendar or the FOMC meetings WIRP prices, as
216
+ * scheduled alerts read them. Payrolls have no schedule to read.
217
+ */
218
+ async function eventReleases(event: UsMacroEventKind, ctx: HeadlessPaneContext): Promise<{
219
+ list: MacroReleaseList; upcoming: string | null; upcomingNote: string | null;
220
+ }> {
221
+ const label = MACRO_EVENT_LABELS[event];
222
+ const [published, next] = await Promise.all([
223
+ loadMacroReleases({}, () => ctx.apiClient.getCloudMacroReleaseDays()),
224
+ event === "jobs" ? null : lookupScheduledDates([{ kind: "macro", event }], {
225
+ earnings: async () => [],
226
+ cpi: () => fetchCpiBoard(ctx.apiClient),
227
+ fomc: async () => (await fetchRatePath(ctx.apiClient)).meetings,
228
+ }, zonedDateKey(Date.now(), "America/New_York")).then((dates) => dates.get(`macro:${event}`) ?? { date: null }),
229
+ ]);
230
+ const upcoming = next && "date" in next ? next.date : null;
231
+ const listed = upcoming != null && published.releases.some((release) => release.kind === event && release.date === upcoming);
232
+ const releases: MacroRelease[] = upcoming && !listed ? [...published.releases, { kind: event, date: upcoming }] : published.releases;
233
+ return {
234
+ list: { ...published, releases },
235
+ upcoming,
236
+ upcomingNote: next == null ? `The next ${label} release is not scheduled here, so it has no row yet.`
237
+ : "error" in next ? `The next ${label} date could not be loaded (${next.error}), so it has no row.` : null,
238
+ };
239
+ }
@@ -37,7 +37,7 @@ export const ivHistoryModule: PluginModule = {
37
37
  {
38
38
  id: "iv-screen-pane", paneId: "iv-screen", label: "Volatility Rich/Cheap",
39
39
  description: "IV rank, percentile, one-year IV, term slope, skew and IV/HV across a list, ranked rich to cheap.",
40
- // Where a put seller finds rich premium; OSA owns the exact put-selling phrases and ranks first on them.
40
+ // Where a put seller finds rich premium; CSP and OSA own the exact put-selling phrases and rank first on them.
41
41
  keywords: ["vca", "rich", "cheap", "iv rank", "implied volatility", "screen", "cash-secured puts", "selling puts", "short-put candidates",
42
42
  "csp candidates", "wheel candidates"],
43
43
  shortcut: { prefix: "VCA", argKind: "ticker-list" as const, argOptional: true }, headless: ivScreenHeadless,
@@ -2,6 +2,16 @@ import type { PricePoint } from "../../../types/financials";
2
2
  import { rollingRealizedVolatility } from "../shared/volatility";
3
3
  import type { IvCoverageStatus, IvHistoryPayload, IvMethod, IvPoint, IvScreenRow, IvStats } from "./client";
4
4
 
5
+ /**
6
+ * A history's warnings in words for the reader. A symbol demand coverage could
7
+ * not take (unavailable, with the server's queue wording as its warning) is
8
+ * said plainly instead: none of its history is being collected, so nothing is
9
+ * promised.
10
+ */
11
+ export function ivHistoryWarnings(payload: Pick<IvHistoryPayload, "status" | "symbol" | "warnings">): string[] {
12
+ return payload.status === "unavailable" && payload.warnings.length ? [`No IV history for ${payload.symbol} yet.`] : [...payload.warnings];
13
+ }
14
+
5
15
  export const HV_WINDOWS = [20, 30] as const;
6
16
  export type HvWindow = (typeof HV_WINDOWS)[number];
7
17
  export type IvLookback = "1Y" | "2Y" | "ALL";
@@ -159,7 +169,7 @@ export function projectIvHistory(
159
169
  ): IvHistoryModel {
160
170
  const lookback = options.lookback ?? "1Y";
161
171
  const window = options.hvWindow ?? 20;
162
- const warnings = [...payload.warnings];
172
+ const warnings = ivHistoryWarnings(payload);
163
173
  const tradeIv30 = byMethod(payload.series, "trade-close", "iv30");
164
174
  const latestDate = [payload.latest?.date, tradeIv30.at(-1) && day(tradeIv30.at(-1)!.date)].filter((value): value is string => !!value).sort().at(-1) ?? null;
165
175
  const start = latestDate ? lookbackStart(latestDate, lookback) : null;
@@ -358,9 +368,8 @@ export function screenCoverage(
358
368
  notes.push(`Backfilling: ${backfilling.map((row) => row.backfilledThrough ? `${row.symbol} through ${row.backfilledThrough}` : row.symbol).join(", ")}.`);
359
369
  }
360
370
  if (final.length) notes.push(`No options history: ${final.map((row) => row.symbol).join(", ")}.`);
361
- const reasons = new Map<string, string[]>();
362
- for (const row of uncovered) reasons.set(row.warning!, [...(reasons.get(row.warning!) ?? []), row.symbol]);
363
- for (const [reason, symbols] of reasons) notes.push(`Not queued: ${symbols.join(", ")}. ${reason}`);
371
+ // The server's queue wording (why demand coverage could not take them) is not repeated: none of their history is being collected, so nothing is promised.
372
+ if (uncovered.length) notes.push(`No IV history yet: ${uncovered.map((row) => row.symbol).join(", ")}.`);
364
373
  const pending = [...queued, ...backfilling, ...uncovered];
365
374
  return { notes, pending: pending.map((row) => row.symbol),
366
375
  missing: pending.filter((row) => row.iv30 == null && row.date == null).map((row) => row.symbol) };
@@ -1,5 +1,6 @@
1
1
  import type { SeriesDefinition } from "../../../series/types";
2
2
  import { loadIvHistory, type IvPoint } from "./client";
3
+ import { ivHistoryWarnings } from "./model";
3
4
 
4
5
  const TENORS: ReadonlyArray<readonly [key: "iv30" | "iv90" | "iv365", label: string]> = [
5
6
  ["iv30", "30-day"],
@@ -18,12 +19,13 @@ export const IV_SERIES: readonly SeriesDefinition[] = TENORS.map(([key, label]):
18
19
  input: "ticker",
19
20
  load: async ({ ticker, signal }) => {
20
21
  const payload = await loadIvHistory(ticker!, { ...(signal ? { signal } : {}) });
22
+ const warnings = ivHistoryWarnings(payload);
21
23
  return {
22
24
  points: payload.series.map((point: IvPoint) => ({
23
25
  date: point.sessionDate,
24
26
  value: point[key] == null ? null : point[key]! * 100,
25
27
  })),
26
- ...(payload.warnings.length ? { warning: payload.warnings.join("; ") } : {}),
28
+ ...(warnings.length ? { warning: warnings.join("; ") } : {}),
27
29
  };
28
30
  },
29
31
  }));
@@ -5,7 +5,7 @@ import { proLockNote, type FreeRoute } from "../shared/pro-lock-note";
5
5
 
6
6
  /** HIRE's preview, for a company whose careers system it reads: Coffee Holding (JVA) is mapped but uncovered. */
7
7
  const HIRE_ROUTE: FreeRoute = {
8
- text: (ticker, company) => `gloomberb fn HIRE ${ticker} previews ${company}'s hiring with its latest roles, without the full history.`,
8
+ text: (ticker, company) => `gloom fn HIRE ${ticker} previews ${company}'s hiring with its latest roles, without the full history.`,
9
9
  answers: async (symbol, context) => {
10
10
  const data = await fetchAttention("hiring", symbol, { limit: 1 }, context.apiClient, context.signal) as HiringPayload;
11
11
  return data.evidence.length + data.series.length + data.functions.length > 0;
@@ -9,6 +9,9 @@ import type {
9
9
  } from "../../../api-client/types";
10
10
  import { formatCompact, formatNumber } from "../../../utils/format";
11
11
  import { compareSortValues } from "../../../utils/sort-values";
12
+ import { formatSalaryRange, postingTitle } from "../shared/job-posting";
13
+
14
+ export { formatSalaryRange };
12
15
 
13
16
  /**
14
17
  * Pure projections from the cloud payload to what the pane, the research tab
@@ -110,20 +113,6 @@ export function formatShare(share: number): string {
110
113
  return `${formatNumber(share * 100, share >= 0.1 ? 0 : 1)}%`;
111
114
  }
112
115
 
113
- export function formatSalaryRange(
114
- min: number | null,
115
- max: number | null,
116
- currency: string | null,
117
- period: string | null,
118
- ): string {
119
- if (min == null && max == null) return "";
120
- const symbol = currency === "USD" ? "$" : currency === "EUR" ? "€" : currency === "GBP" ? "£" : currency ? `${currency} ` : "";
121
- const fmt = (value: number) => (period === "hour" ? formatNumber(value, 0) : formatCompact(value));
122
- const range = min != null && max != null && min !== max
123
- ? `${symbol}${fmt(min)}–${fmt(max)}`
124
- : `${symbol}${fmt((min ?? max)!)}`;
125
- return period === "hour" ? `${range}/h` : period === "month" ? `${range}/mo` : range;
126
- }
127
116
 
128
117
  /** "3d", "6w", "4mo" from an ISO date, with a `+` when the date is a floor. */
129
118
  export function formatAge(posted: string | null, precision: string | null, now = new Date()): string {
@@ -162,7 +151,7 @@ export function buildPostingRows(postings: readonly CloudJobsPosting[], now = ne
162
151
  return postings.map((posting) => ({
163
152
  key: String(posting.id),
164
153
  posting,
165
- title: posting.title,
154
+ title: postingTitle(posting.title),
166
155
  function: functionLabel(posting.function),
167
156
  seniority: seniorityLabel(posting.seniority),
168
157
  location: posting.remote && !/remote/i.test(posting.location ?? "")
@@ -32,6 +32,7 @@ import { useAsyncResource } from "../../../react/async-resource";
32
32
  import { useShortcut } from "../../../react/input";
33
33
  import { colors } from "../../../theme/colors";
34
34
  import { Box, Text, TextAttributes, useRendererHost, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
35
+ import { withCountryFlag } from "../../../components/ui/country-flag";
35
36
  import { formatNumber } from "../../../utils/format";
36
37
  import { isPlainKey } from "../../../utils/keyboard";
37
38
  import { nextHeaderSort } from "../../../utils/sort-values";
@@ -85,7 +86,7 @@ function HiringProWall({ symbol, exchange, width, height }: { symbol: string | n
85
86
  placement="jobs-wall"
86
87
  symbol={symbol} exchange={exchange} width={width} height={height}
87
88
  title="Hiring data is part of Gloom Cloud Pro."
88
- message={`Gloomberb reads every listed company's own careers system daily: open roles over time, hiring by function and location, new roles, and pay ranges.${symbol ? ` Open ${symbol}'s hiring picture with Pro.` : ""}`}
89
+ message={`Gloom reads every listed company's own careers system daily: open roles over time, hiring by function and location, new roles, and pay ranges.${symbol ? ` Open ${symbol}'s hiring picture with Pro.` : ""}`}
89
90
  />
90
91
  );
91
92
  }
@@ -486,7 +487,7 @@ function CompanyView({
486
487
  <Box flexDirection="column" paddingX={1} paddingTop={1}>
487
488
  {countryRows.length === 0
488
489
  ? <Text fg={colors.textDim}>No locations in the postings collected so far.</Text>
489
- : <ShareBars rows={countryRows} width={Math.min(width - 2, 80)} color={colors.warning} showDelta />}
490
+ : <ShareBars rows={countryRows} width={Math.min(width - 2, 80)} color={colors.warning} showDelta flags />}
490
491
  </Box>
491
492
  ) : tab === "seniority" ? (
492
493
  <Box flexDirection="column" paddingX={1} paddingTop={1}>
@@ -575,7 +576,7 @@ function CompanyPanel({
575
576
  <PaneStatusBody
576
577
  empty
577
578
  emptyTitle={`No careers system found for ${symbol}.`}
578
- emptyMessage="Gloomberb reads companies' own careers systems. This one either has none we can read or lists roles only on third-party job boards."
579
+ emptyMessage="Gloom reads companies' own careers systems. This one either has none we can read or lists roles only on third-party job boards."
579
580
  retry={{ onRetry: reload, pending: loading, label: "Look again", pendingLabel: "Looking again...", unchanged: "Still no careers system." }}
580
581
  />
581
582
  );
@@ -682,9 +683,10 @@ function HomeView({ width, height, focused, registrationId }: { width: number; h
682
683
  case "function":
683
684
  return { text: row.function, color: colors.textDim };
684
685
  case "country":
685
- return { text: row.country, color: colors.textDim };
686
+ // The column has room for the flag beside the code and its share.
687
+ return withCountryFlag({ text: row.country, color: colors.textDim }, row.mover.topCountry?.code, nativePaneChrome === true);
686
688
  }
687
- }, []);
689
+ }, [nativePaneChrome]);
688
690
 
689
691
  if (status === "loading" && !data) return <PaneStatusBody loading align="center" loadingLabel="Loading hiring data..." />;
690
692
  if (status === "error" && !data) return <PaneStatusBody error={error ?? "Could not load hiring data."} errorTitle="Could not load hiring data." retry={{ onRetry: reload }} />;
@@ -1,5 +1,6 @@
1
+ import { COUNTRY_FLAG_CELLS, CountryFlagLead } from "../../../components/ui/country-flag";
1
2
  import { RatioBar } from "../../../components/ui/ratio-bar";
2
- import { Box, Text, TextAttributes } from "../../../ui";
3
+ import { Box, Text, TextAttributes, useUiCapabilities } from "../../../ui";
3
4
  import { colors } from "../../../theme/colors";
4
5
  import { formatNumber, truncateToDisplayWidth } from "../../../utils/format";
5
6
  import type { ShareBarRow } from "./model";
@@ -16,6 +17,8 @@ export interface ShareBarsProps {
16
17
  color?: string;
17
18
  /** Show the 30d delta column when any row has one. */
18
19
  showDelta?: boolean;
20
+ /** Rows are countries: the desktop and the web lead each with its flag. */
21
+ flags?: boolean;
19
22
  }
20
23
 
21
24
  const COUNT_WIDTH = 6;
@@ -36,9 +39,11 @@ function deltaColor(delta: number | null): string {
36
39
  return delta > 0 ? colors.positive : colors.negative;
37
40
  }
38
41
 
39
- export function ShareBars({ rows, width, color = colors.borderFocused, showDelta = false }: ShareBarsProps) {
42
+ export function ShareBars({ rows, width, color = colors.borderFocused, showDelta = false, flags = false }: ShareBarsProps) {
43
+ const desktop = useUiCapabilities().nativePaneChrome === true;
44
+ const flagged = flags && desktop;
40
45
  const hasDelta = showDelta && rows.some((row) => row.delta != null && row.delta !== 0);
41
- const labelWidth = labelWidthFor(width);
46
+ const labelWidth = labelWidthFor(width) + (flagged ? COUNTRY_FLAG_CELLS : 0);
42
47
  const trailing = COUNT_WIDTH + SHARE_WIDTH + (hasDelta ? DELTA_WIDTH + 1 : 0) + 2;
43
48
  const barWidth = Math.max(4, width - labelWidth - trailing - 2);
44
49
 
@@ -46,9 +51,10 @@ export function ShareBars({ rows, width, color = colors.borderFocused, showDelta
46
51
  <Box flexDirection="column" width={width} data-gloom-ui="share-bars">
47
52
  {rows.map((row) => (
48
53
  <Box key={row.key} flexDirection="row" height={1} alignItems="center">
49
- <Box width={labelWidth} flexShrink={0} overflow="hidden">
54
+ <Box width={labelWidth} flexShrink={0} overflow="hidden" flexDirection="row" alignItems="center">
55
+ {flagged ? <CountryFlagLead value={row.key === "rest" ? null : row.label} reserve /> : null}
50
56
  <Text fg={row.key === "rest" ? colors.textDim : colors.text}>
51
- {truncateToDisplayWidth(row.label, labelWidth - 1)}
57
+ {truncateToDisplayWidth(row.label, labelWidth - 1 - (flagged ? COUNTRY_FLAG_CELLS : 0))}
52
58
  </Text>
53
59
  </Box>
54
60
  <RatioBar ratio={row.ratio} width={barWidth} color={color} track />
@@ -13,7 +13,8 @@ import { useAsyncResource } from "../../../react/async-resource";
13
13
  import { useAutoRefresh } from "../../../react/auto-refresh";
14
14
  import { useThemeColors } from "../../../theme/theme-context";
15
15
  import type { PaneProps } from "../../../types/plugin";
16
- import { Box, TextAttributes } from "../../../ui";
16
+ import { Box, TextAttributes, useUiCapabilities } from "../../../ui";
17
+ import { withCountryFlag, withFlagRoom } from "../../../components/ui/country-flag";
17
18
  import { usePluginPaneState } from "../../runtime";
18
19
  import { fetchBalances } from "./client";
19
20
  import {
@@ -39,11 +40,16 @@ export function JodiPane({ focused, width, height }: PaneProps) {
39
40
  const balances = resource.data;
40
41
  const gas = balances?.gas ?? null;
41
42
  const [storedTab, setTab] = usePluginPaneState<string>("commodity", "oil");
42
- const tab: BalanceCommodity = gas && storedTab === "gas" ? "gas" : "oil";
43
+ const tab: BalanceCommodity = storedTab === "gas" ? "gas" : "oil";
43
44
  const board = tab === "gas" ? gas : balances?.oil ?? null;
44
45
  const rows = board?.rows ?? EMPTY_ROWS;
45
46
  const [selectedId, setSelectedId] = usePluginPaneState<string | null>("selected", null);
46
- const columns = useMemo(() => balanceColumns(tab), [tab]);
47
+ // The desktop and the web lead each country with its flag.
48
+ const flagged = useUiCapabilities().nativePaneChrome === true;
49
+ const columns = useMemo(
50
+ () => balanceColumns(tab).map((column) => (column.id === "country" ? withFlagRoom(column, flagged) : column)),
51
+ [flagged, tab],
52
+ );
47
53
  const refresh = useCallback(() => {
48
54
  resource.reload();
49
55
  }, [resource.reload]);
@@ -54,7 +60,7 @@ export function JodiPane({ focused, width, height }: PaneProps) {
54
60
  const selectTab = useCallback((value: string) => {
55
61
  setTab(value === "gas" ? "gas" : "oil");
56
62
  }, [setTab]);
57
- const { strip: tabs, rows: tabRows } = usePaneTabs(gas ? {
63
+ const { strip: tabs, rows: tabRows } = usePaneTabs({
58
64
  tabs: TABS,
59
65
  activeValue: tab,
60
66
  onSelect: selectTab,
@@ -62,7 +68,7 @@ export function JodiPane({ focused, width, height }: PaneProps) {
62
68
  compact: true,
63
69
  variant: "underline",
64
70
  queryBarWidth: width,
65
- } : null);
71
+ });
66
72
  const info = useMemo(
67
73
  () => (resource.error || !board ? [] : [{ id: "month", parts: [{ text: formatBalanceMonth(board.month) }] }]),
68
74
  [board, resource.error],
@@ -84,7 +90,7 @@ export function JodiPane({ focused, width, height }: PaneProps) {
84
90
  });
85
91
  switch (column.id) {
86
92
  case "country":
87
- return { text: row.country, color: colors.textBright, attributes: TextAttributes.BOLD };
93
+ return withCountryFlag({ text: row.country, color: colors.textBright, attributes: TextAttributes.BOLD }, row.country, flagged);
88
94
  case "month":
89
95
  return { text: row.month ? formatBalanceMonth(row.month) : "—", value: row.month, color: colors.textMuted };
90
96
  case "production":
@@ -102,7 +108,7 @@ export function JodiPane({ focused, width, height }: PaneProps) {
102
108
  default:
103
109
  return { text: "" };
104
110
  }
105
- }, [colors]);
111
+ }, [colors, flagged]);
106
112
 
107
113
  if (!balances) {
108
114
  return (
@@ -139,7 +145,7 @@ export function JodiPane({ focused, width, height }: PaneProps) {
139
145
  onRootKeyDown={onRootKeyDown}
140
146
  renderCell={renderCell}
141
147
  selectedTextOverridesCellColor
142
- emptyStateTitle="No balances for this month."
148
+ emptyStateTitle={board ? "No balances for this month." : tab === "gas" ? "Gas balances unavailable." : "Oil balances unavailable."}
143
149
  />
144
150
  </Box>
145
151
  );
@@ -111,6 +111,7 @@ export const layoutManagerModule: PluginModule = {
111
111
  name: "Layouts",
112
112
  icon: "L",
113
113
  component: LayoutMarketplacePane,
114
+ reportFreshness: { status: "not-a-feed", basis: "layout listings" },
114
115
  defaultPosition: "right",
115
116
  defaultMode: "floating",
116
117
  defaultFloatingSize: { width: 118, height: 34 },
@@ -1,8 +1,9 @@
1
1
  import type { HeadlessPaneDefinition } from "../../../types/plugin";
2
2
  import { resolveHeadlessInstrument } from "../shared/headless-market-data";
3
3
  import { loadMacroDayEarnings, loadMacroDayHistory, loadMacroReleases, macroDayEarningsNotice } from "./client";
4
- import { macroDayEventLabel, projectMacroDays, type MacroDayStats } from "./model";
5
- import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, MACRO_RELEASE_SOURCES, staleMacroReleasesNotice } from "./releases";
4
+ import { macroDayEventLabel, macroDayStats, matchesSurprise, projectMacroDays, type MacroDayStats } from "./model";
5
+ import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, MACRO_RELEASE_SOURCES, MACRO_SURPRISE_LABELS, MACRO_SURPRISES, staleMacroReleasesNotice,
6
+ type MacroEventKind, type MacroSurprise } from "./releases";
6
7
 
7
8
  // A mean that rounds to zero reads 0.00%, never -0.00%.
8
9
  const percent = (value: unknown) => typeof value !== "number" ? "--" : /[1-9]/.test((value * 100).toFixed(2)) ? `${(value * 100).toFixed(2)}%` : "0.00%";
@@ -17,12 +18,16 @@ export const macroDayHeadless: HeadlessPaneDefinition<"bundle"> = {
17
18
  describe: (args) => `MDAY ${args.symbols[0] ?? ""}`,
18
19
  discovery: { screenshotReadiness: "live-dom", limitations: [
19
20
  "US listings; close-to-close on the release day.",
20
- "Published CPI, jobs and FOMC days; sessions after the list's last covered day (releasesThrough) are left out.",
21
+ "Published CPI, jobs and FOMC days, and Brazil's IPCA days from Gloom Cloud; sessions after the list's last covered day (releasesThrough) are left out.",
22
+ "Actual, forecast and prior for the days Gloom Cloud has them (the US headlines from its kept economic calendar, IPCA from the central bank's SGS series); --surprise keeps the days that came in hot, cool or in line with the forecast.",
21
23
  "A release day that is also the reaction session of the company's own earnings report is marked earnings and left out of the release averages and the normal day.",
22
24
  ] },
23
25
  options: [
24
26
  { key: "release", type: "enum", values: [{ value: "all" }, ...MACRO_EVENT_KINDS.map((value) => ({ value }))], defaultValue: "all",
25
27
  description: "Release the pane lists", pluginState: { pluginId: "ticker-research", key: "release" } },
28
+ { key: "surprise", type: "enum", values: [{ value: "all" }, ...MACRO_SURPRISES.map((value) => ({ value }))], defaultValue: "all",
29
+ description: "Release days whose print came in above (hot), below (cool) or at (in-line) the forecast",
30
+ example: "--release cpi --surprise hot", pluginState: { pluginId: "ticker-research", key: "surprise" } },
26
31
  { key: "lookbackYears", type: "integer", minimum: 1, maximum: 5, defaultValue: 5, description: "Years of daily closes" },
27
32
  ],
28
33
  async load(args, ctx) {
@@ -35,17 +40,25 @@ export const macroDayHeadless: HeadlessPaneDefinition<"bundle"> = {
35
40
  const notes = [staleMacroReleasesNotice(releases), macroDayEarningsNotice(earnings)].filter((note): note is string => !!note);
36
41
  const row = (label: string, stats: MacroDayStats) => ({ label, ...stats });
37
42
  const release = String(args.options.release ?? "all");
38
- const events = release === "all" ? model.events : model.events.filter((event) => event.kind === release);
43
+ const surprise = String(args.options.surprise ?? "all") as MacroSurprise | "all";
44
+ const events = model.events.filter((event) => (release === "all" || event.kind === release) && matchesSurprise(event, surprise));
45
+ // The days the filter keeps get a row of their own: how the name moved on hot CPI days.
46
+ const selected = surprise === "all" ? [] : [row(`${MACRO_SURPRISE_LABELS[surprise]} ${release === "all" ? "release"
47
+ : MACRO_EVENT_LABELS[release as MacroEventKind]}`, macroDayStats(events, model.normal.meanAbs))];
39
48
  return {
40
49
  sections: [
41
50
  { title: "By release", columns: [{ key: "label", header: "Day" }, { key: "count", header: "Days" },
42
51
  { key: "meanAbs", header: "Avg |move|", format: percent }, { key: "multiple", header: "vs normal", format: multiple },
43
52
  { key: "mean", header: "Avg move", format: percent }, { key: "hitRate", header: "Up", format: share }],
44
- rows: [...MACRO_EVENT_KINDS.map((kind) => row(MACRO_EVENT_LABELS[kind], model.byKind[kind])),
45
- row("Any release", model.allEvents), ...(model.earnings.count ? [row("Earnings", model.earnings)] : []), row("Normal day", model.normal)] },
53
+ rows: [...model.kinds.map((kind) => row(MACRO_EVENT_LABELS[kind], model.byKind[kind])), ...selected,
54
+ row(model.kinds.includes("ipca") ? "Any US release" : "Any release", model.allEvents), ...(model.earnings.count ? [row("Earnings", model.earnings)] : []), row("Normal day", model.normal)] },
46
55
  { title: "Release days", columns: [{ key: "date", header: "Date" }, { key: "event", header: "Release" },
56
+ { key: "actual", header: "Actual" }, { key: "forecast", header: "Forecast" }, { key: "prior", header: "Prior" },
57
+ { key: "surprise", header: "Surprise" },
47
58
  { key: "session", header: "Session" }, { key: "move", header: "Move", format: percent }, { key: "multiple", header: "vs normal", format: multiple }],
48
- rows: events.map((event) => ({ ...event, event: macroDayEventLabel(event) })) },
59
+ rows: events.map(({ figures, ...event }) => ({ ...event, event: macroDayEventLabel(event), actual: figures?.actual ?? null,
60
+ forecast: figures?.forecast ?? null, prior: figures?.prior ?? null, surprise: figures?.surprise ?? null,
61
+ ...(figures ? { headline: figures.event } : {}) })) },
49
62
  ],
50
63
  complete: !history.stale && !earnings.stale && !history.error && !notes.length && model.events.length > 0,
51
64
  unavailableSymbols: model.events.length ? [] : [instrument.symbol],
@@ -15,8 +15,9 @@ export const macroDayModule: PluginModule = {
15
15
  }],
16
16
  paneTemplates: [{ ...createTickerSurfacePaneTemplate({
17
17
  id: "macro-day-pane", paneId: "macro-day", label: "Macro-Day Reaction",
18
- description: "How a name moves on CPI, jobs and FOMC days against a normal day: average move, direction, hit rate and every release day.",
19
- keywords: ["mday", "macro day", "cpi day", "fomc day", "jobs day", "nfp", "payrolls", "event study", "release reaction"],
18
+ description: "How a name moves on CPI, jobs, FOMC and Brazil IPCA days against a normal day: average move, direction, hit rate, and every release day with its actual, forecast and prior.",
19
+ keywords: ["mday", "macro day", "cpi day", "fomc day", "jobs day", "nfp", "payrolls", "event study", "release reaction", "ipca",
20
+ "hot cpi", "cpi surprise", "release surprise"],
20
21
  shortcut: "MDAY", publicShare: true,
21
22
  }), headless: macroDayHeadless }],
22
23
  setup(ctx) { macroReleaseCache.attach(ctx.persistence); },
@@ -1,7 +1,8 @@
1
1
  import type { EarningsTiming } from "../../../api-client/earnings";
2
2
  import type { PricePoint } from "../../../types/financials";
3
3
  import { zonedDateTimeParts } from "../../../utils/zoned-date-time";
4
- import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, type MacroEventKind, type MacroRelease } from "./releases";
4
+ import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, US_MACRO_EVENT_KINDS, type MacroEventKind, type MacroRelease, type MacroReleaseFigures,
5
+ type MacroSurprise } from "./releases";
5
6
 
6
7
  const DAY_MS = 86_400_000;
7
8
  /** Longest calendar gap between two closes that is still one session apart: Thursday to Monday over a Friday holiday. */
@@ -28,6 +29,8 @@ export interface MacroDayEvent {
28
29
  move: number;
29
30
  /** |move| over the normal day's average |move|. */
30
31
  multiple: number | null;
32
+ /** What the release came out with, when the list has it. */
33
+ figures: MacroReleaseFigures | null;
31
34
  }
32
35
 
33
36
  export interface MacroDayStats {
@@ -44,13 +47,19 @@ export interface MacroDayModel {
44
47
  symbol: string;
45
48
  /** Newest first. */
46
49
  events: MacroDayEvent[];
50
+ /** The kinds the list carries: the US releases, and IPCA when Gloom Cloud lists its days. */
51
+ kinds: MacroEventKind[];
47
52
  /** Without the earnings days. */
48
53
  byKind: Record<MacroEventKind, MacroDayStats>;
49
- /** Every release day of the three kinds together, without the earnings days; a day with two releases counts once. */
54
+ /**
55
+ * Every US release day together, without the earnings days; a day with two
56
+ * releases counts once. IPCA days are summed up on their own only, so a US
57
+ * name's figures do not move with Brazil's calendar.
58
+ */
50
59
  allEvents: MacroDayStats;
51
- /** Release days that are the ticker's earnings reaction, which no other figure counts; a day with two releases counts once. */
60
+ /** US release days that are the ticker's earnings reaction, which no other figure counts; a day with two releases counts once. */
52
61
  earnings: MacroDayStats;
53
- /** Sessions with no release of the three kinds, and none of the earnings days among them. */
62
+ /** Sessions with no US release, and none of the earnings days among them. */
54
63
  normal: MacroDayStats;
55
64
  start: string | null;
56
65
  asOf: string | null;
@@ -70,6 +79,15 @@ function sessionDate(time: number): string {
70
79
  const dayNumber = (date: string) => Date.parse(`${date}T00:00:00Z`) / DAY_MS;
71
80
  const isWeekday = (date: string) => { const day = new Date(`${date}T00:00:00Z`).getUTCDay(); return day > 0 && day < 6; };
72
81
 
82
+ /** The figures over some of the model's release days (the hot CPI days): their moves, the earnings days left out as the kinds' are. */
83
+ export function macroDayStats(events: readonly MacroDayEvent[], normalAbs: number | null): MacroDayStats {
84
+ return stats(events.filter((event) => !event.earnings).map((event) => event.move), normalAbs);
85
+ }
86
+
87
+ /** Whether a release day's print matches a surprise filter; `all` matches every day, figures or not. */
88
+ export const matchesSurprise = (event: Pick<MacroDayEvent, "figures">, surprise: MacroSurprise | "all") =>
89
+ surprise === "all" || event.figures?.surprise === surprise;
90
+
73
91
  function stats(moves: number[], normalAbs: number | null): MacroDayStats {
74
92
  if (!moves.length) return { count: 0, meanAbs: null, mean: null, hitRate: null, multiple: null };
75
93
  const meanAbs = moves.reduce((sum, move) => sum + Math.abs(move), 0) / moves.length;
@@ -99,6 +117,8 @@ function earningsReactionSessions(reports: readonly MacroDayEarningsReport[], se
99
117
  return reacted;
100
118
  }
101
119
 
120
+ const US_KINDS: ReadonlySet<MacroEventKind> = new Set(US_MACRO_EVENT_KINDS);
121
+
102
122
  /**
103
123
  * Close to close on the release day: 8:30 ET releases land before the open
104
124
  * and 14:00 FOMC statements before the close, so the release day's close
@@ -129,7 +149,8 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
129
149
  const sessions = [...byDate.keys()].sort();
130
150
  const last = sessions.at(-1) ?? null;
131
151
  const empty = (): MacroDayStats => stats([], null);
132
- if (!last) return { symbol: options.symbol, events: [], byKind: { cpi: empty(), jobs: empty(), fomc: empty() },
152
+ const kinds = MACRO_EVENT_KINDS.filter((kind) => US_KINDS.has(kind) || options.releases.some((release) => release.kind === kind));
153
+ if (!last) return { symbol: options.symbol, events: [], kinds, byKind: { cpi: empty(), jobs: empty(), fomc: empty(), ipca: empty() },
133
154
  allEvents: empty(), earnings: empty(), normal: empty(), start: null, asOf: null };
134
155
 
135
156
  // Sessions after the published lists end may be unlisted release days, so they are left out of both sides.
@@ -157,8 +178,8 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
157
178
  const session = sessions[at]!;
158
179
  const move = moves.get(session);
159
180
  if (move == null || (session !== release.date && skipsAnotherWeekday(release.date, sessions[at - 1]!, session))) continue;
160
- reactionSessions.add(session);
161
- found.push({ kind: release.kind, date: release.date, session, move });
181
+ if (US_KINDS.has(release.kind)) reactionSessions.add(session);
182
+ found.push({ kind: release.kind, date: release.date, session, move, figures: release.figures ?? null });
162
183
  }
163
184
 
164
185
  const normalMoves = [...moves].filter(([date]) => !reactionSessions.has(date)).map(([, move]) => move);
@@ -170,7 +191,7 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
170
191
  const byKind = Object.fromEntries(MACRO_EVENT_KINDS.map((kind) =>
171
192
  [kind, stats(events.filter((event) => event.kind === kind && !event.earnings).map((event) => event.move), normalAbs)])) as Record<MacroEventKind, MacroDayStats>;
172
193
  const sessionMoves = (flagged: boolean) => [...reactionSessions].filter((session) => reacted.has(session) === flagged).map((session) => moves.get(session)!);
173
- return { symbol: options.symbol, events, byKind, allEvents: stats(sessionMoves(false), normalAbs), earnings: stats(sessionMoves(true), normalAbs),
194
+ return { symbol: options.symbol, events, kinds, byKind, allEvents: stats(sessionMoves(false), normalAbs), earnings: stats(sessionMoves(true), normalAbs),
174
195
  normal, start, asOf: end };
175
196
  }
176
197