gloomberb 0.16.3 → 0.16.5

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 (820) hide show
  1. package/README.md +14 -91
  2. package/package.json +7 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
  11. package/src/account/upgrade-personalization.ts +57 -0
  12. package/src/account/upgrade-tickers.ts +124 -0
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/askg.ts +43 -0
  15. package/src/api-client/auth.ts +15 -0
  16. package/src/api-client/beneficial-owners.ts +4 -0
  17. package/src/api-client/chat.ts +19 -0
  18. package/src/api-client/company-kpis.ts +14 -2
  19. package/src/api-client/data.ts +58 -18
  20. package/src/api-client/earnings.ts +6 -0
  21. package/src/api-client/futures-curve.ts +56 -0
  22. package/src/api-client/index.ts +16 -1
  23. package/src/api-client/market-discovery.ts +10 -1
  24. package/src/api-client/normalizers.ts +27 -0
  25. package/src/api-client/paths.ts +95 -23
  26. package/src/api-client/request.ts +2 -1
  27. package/src/api-client/research-activity.ts +46 -10
  28. package/src/api-client/socket.ts +39 -8
  29. package/src/api-client/types.ts +74 -2
  30. package/src/api-client/upgrade-experiment.ts +90 -0
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +26 -2
  33. package/src/app/keybindings/actions.ts +10 -0
  34. package/src/app/pane-runtime/index.tsx +8 -0
  35. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  36. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  37. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  38. package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
  39. package/src/app/runtime/desktop-deeplink.ts +5 -0
  40. package/src/app/star-prompt/model.ts +98 -0
  41. package/src/app/star-prompt/runtime.ts +41 -0
  42. package/src/app/star-prompt/status-line.tsx +190 -0
  43. package/src/app.tsx +13 -7
  44. package/src/architecture/core-builtin-allowlist.json +61 -0
  45. package/src/brokers/signed-in/adapter.ts +33 -2
  46. package/src/brokers/signed-in/client.ts +10 -0
  47. package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
  48. package/src/brokers/signed-in/sign-in.ts +62 -5
  49. package/src/capabilities/chart-series.ts +11 -1
  50. package/src/capabilities/registry.ts +8 -1
  51. package/src/capabilities/types.ts +2 -0
  52. package/src/cli/commands/crypto-hints.ts +19 -4
  53. package/src/cli/commands/fred-series.ts +61 -0
  54. package/src/cli/commands/market.ts +744 -181
  55. package/src/cli/commands/news-hints.ts +62 -0
  56. package/src/cli/commands/news-search.ts +53 -0
  57. package/src/cli/commands/options-chain.ts +172 -0
  58. package/src/cli/commands/options-leaps.ts +425 -0
  59. package/src/cli/commands/overview.ts +251 -40
  60. package/src/cli/commands/remote.ts +2 -1
  61. package/src/cli/commands/search.ts +109 -15
  62. package/src/cli/commands/system.ts +151 -24
  63. package/src/cli/commands/themes.ts +64 -0
  64. package/src/cli/commands/ticker.ts +149 -40
  65. package/src/cli/context.ts +45 -14
  66. package/src/cli/desktop-pane-shot.ts +150 -17
  67. package/src/cli/earnings-calendar.ts +71 -0
  68. package/src/cli/errors.ts +25 -2
  69. package/src/cli/freshness.ts +22 -8
  70. package/src/cli/fx-pair.ts +57 -0
  71. package/src/cli/glossary.ts +429 -0
  72. package/src/cli/help.ts +14 -1
  73. package/src/cli/history-rows.ts +48 -7
  74. package/src/cli/index-roots.ts +58 -0
  75. package/src/cli/index.ts +29 -12
  76. package/src/cli/known-gaps.ts +27 -0
  77. package/src/cli/listing-arg.ts +595 -26
  78. package/src/cli/not-a-ticker.ts +44 -0
  79. package/src/cli/options.ts +50 -6
  80. package/src/cli/pane-functions/access-gate.ts +5 -0
  81. package/src/cli/pane-functions/capabilities.ts +11 -4
  82. package/src/cli/pane-functions/catalog.ts +48 -7
  83. package/src/cli/pane-functions/data.ts +48 -13
  84. package/src/cli/pane-functions/discovery.ts +1 -0
  85. package/src/cli/pane-functions/dom.ts +41 -19
  86. package/src/cli/pane-functions/freshness.ts +531 -32
  87. package/src/cli/pane-functions/function-help.ts +77 -25
  88. package/src/cli/pane-functions/headless.ts +50 -21
  89. package/src/cli/pane-functions/index.ts +66 -10
  90. package/src/cli/pane-functions/market-session.ts +147 -0
  91. package/src/cli/pane-functions/options.ts +77 -25
  92. package/src/cli/pane-functions/report-notices.ts +81 -0
  93. package/src/cli/pane-functions/report.ts +19 -8
  94. package/src/cli/pane-functions/resolver.ts +53 -18
  95. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  96. package/src/cli/pane-functions/screenshot.ts +199 -30
  97. package/src/cli/registry.ts +2 -1
  98. package/src/cli/report-tables.ts +3 -0
  99. package/src/cli/result.ts +53 -13
  100. package/src/cli/row-window.ts +76 -0
  101. package/src/cli/scroll-truncation.ts +34 -0
  102. package/src/cli/staged-tickers.ts +52 -0
  103. package/src/cli/symbol-args.ts +9 -0
  104. package/src/cli/symbol-list.ts +172 -0
  105. package/src/cli/ticker-resolution.ts +223 -30
  106. package/src/cli/types.ts +5 -0
  107. package/src/components/chart/composite/axis-overlays.tsx +6 -2
  108. package/src/components/chart/composite/composite-chart.tsx +83 -10
  109. package/src/components/chart/composite/legend.tsx +88 -8
  110. package/src/components/chart/composite/panel-surface.tsx +44 -17
  111. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  112. package/src/components/chart/composite/rasterizer.ts +64 -4
  113. package/src/components/chart/composite/series-cues.ts +71 -0
  114. package/src/components/chart/composite/text-renderer.ts +16 -8
  115. package/src/components/chart/composite/types.ts +3 -0
  116. package/src/components/command-bar/commands/direct/index.ts +9 -1
  117. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  118. package/src/components/command-bar/commands/registry.ts +7 -0
  119. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  120. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  121. package/src/components/command-bar/panel/index.tsx +11 -3
  122. package/src/components/command-bar/panel/runtime.ts +3 -0
  123. package/src/components/command-bar/panel/types.ts +2 -0
  124. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  125. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  126. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  127. package/src/components/command-bar/routes/root/results.ts +40 -10
  128. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  129. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  130. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  131. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  132. package/src/components/command-bar/surface/index.tsx +18 -4
  133. package/src/components/command-bar/theme-picker.tsx +48 -13
  134. package/src/components/command-bar/workflow/ops.ts +5 -3
  135. package/src/components/command-bar/workflow/tickers.ts +23 -4
  136. package/src/components/data-table/view.tsx +28 -9
  137. package/src/components/layout/detached-pane-shell.tsx +9 -0
  138. package/src/components/layout/floating-pane.tsx +9 -2
  139. package/src/components/layout/header.tsx +20 -5
  140. package/src/components/layout/market-summary.ts +23 -9
  141. package/src/components/layout/pane/content.tsx +40 -29
  142. package/src/components/layout/pane/cycle-order.ts +2 -11
  143. package/src/components/layout/pane/footer/index.tsx +6 -2
  144. package/src/components/layout/pane/footer/model.ts +35 -1
  145. package/src/components/layout/pane/header.tsx +26 -2
  146. package/src/components/layout/pane/index.tsx +12 -2
  147. package/src/components/layout/pane/sidebar.tsx +78 -10
  148. package/src/components/layout/pane/title.ts +1 -1
  149. package/src/components/layout/presentation.ts +22 -0
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/drag/index.ts +43 -9
  152. package/src/components/layout/shell/drag/live.ts +87 -6
  153. package/src/components/layout/shell/drag/runtime.ts +62 -20
  154. package/src/components/layout/shell/index.tsx +71 -12
  155. package/src/components/layout/shell/layout-state.ts +5 -11
  156. package/src/components/layout/shell/menu.ts +33 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +2 -1
  159. package/src/components/layout/shell/pane/layers.tsx +216 -28
  160. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  161. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  162. package/src/components/layout/shell/shortcuts.ts +5 -2
  163. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  164. package/src/components/layout/shell/visible-layout.ts +44 -1
  165. package/src/components/layout/status-bar.tsx +4 -1
  166. package/src/components/markdown-text.tsx +69 -23
  167. package/src/components/metric-treemap/heat-surface.tsx +37 -9
  168. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  169. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/index.tsx +1 -1
  171. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  172. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  173. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  174. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  175. package/src/components/onboarding/onboarding-wizard.tsx +50 -41
  176. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  177. package/src/components/onboarding/pro-step-layout.ts +86 -0
  178. package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
  179. package/src/components/onboarding/wizard-account.ts +2 -2
  180. package/src/components/pane-template-wizard.tsx +9 -1
  181. package/src/components/price-selector-dialog.tsx +11 -2
  182. package/src/components/sign-in-gate.tsx +3 -3
  183. package/src/components/ticker/list-table-view.tsx +24 -1
  184. package/src/components/ui/action-row.tsx +2 -1
  185. package/src/components/ui/button.tsx +17 -1
  186. package/src/components/ui/choice-dialog.tsx +6 -4
  187. package/src/components/ui/confirm-dialog.tsx +28 -18
  188. package/src/components/ui/data-table/index.tsx +49 -0
  189. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  190. package/src/components/ui/data-table/types.ts +20 -1
  191. package/src/components/ui/data-table/visible-range.ts +2 -0
  192. package/src/components/ui/dialog-actions.tsx +64 -0
  193. package/src/components/ui/display.tsx +17 -3
  194. package/src/components/ui/frame.tsx +35 -2
  195. package/src/components/ui/icon.tsx +13 -2
  196. package/src/components/ui/index.ts +1 -1
  197. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  198. package/src/core/connection-health.ts +1 -1
  199. package/src/core/state/app/layout-reducer.ts +89 -3
  200. package/src/core/state/app/state.ts +8 -5
  201. package/src/core/state/app/types.ts +13 -2
  202. package/src/data/cached-query.ts +2 -0
  203. package/src/data/config/layout.ts +55 -21
  204. package/src/data/config/store/fold-panes.ts +149 -0
  205. package/src/data/config/store/migrations.ts +7 -0
  206. package/src/data/config/store/node.ts +27 -6
  207. package/src/data/config/store/normalize.ts +44 -5
  208. package/src/data/ticker-repository.ts +5 -0
  209. package/src/data/ticker-store.ts +15 -0
  210. package/src/docs/content.ts +215 -0
  211. package/src/docs/load.ts +139 -0
  212. package/src/docs/requests.ts +39 -0
  213. package/src/docs/snapshot.chunk.ts +8 -0
  214. package/src/docs/snapshot.json +7416 -0
  215. package/src/docs/topics.ts +216 -0
  216. package/src/i18n/es.ts +75 -5
  217. package/src/i18n/ja.ts +75 -5
  218. package/src/i18n/ko.ts +75 -5
  219. package/src/i18n/zh-cn.ts +75 -5
  220. package/src/i18n/zh-tw.ts +75 -5
  221. package/src/layout/desks.ts +2 -3
  222. package/src/layout/pane-layout-move.ts +264 -0
  223. package/src/layout/pane-manager/dock-tree.ts +18 -0
  224. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  225. package/src/layout/pane-manager/index.ts +2 -0
  226. package/src/market-data/coordinator/chart.ts +10 -4
  227. package/src/market-data/coordinator/entries.ts +7 -1
  228. package/src/market-data/coordinator/index.ts +6 -3
  229. package/src/market-data/coordinator/quotes.ts +2 -2
  230. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  231. package/src/market-data/futures-contract.ts +151 -0
  232. package/src/market-data/hooks.tsx +10 -2
  233. package/src/market-data/market/format.ts +39 -21
  234. package/src/market-data/market/freshness.ts +193 -30
  235. package/src/market-data/market/status.ts +59 -23
  236. package/src/market-data/options-alternatives.ts +69 -0
  237. package/src/market-data/published-apac-sessions.ts +23 -1
  238. package/src/market-data/quotes/contributions.ts +22 -2
  239. package/src/market-data/quotes/metadata.ts +8 -9
  240. package/src/market-data/quotes/resolution.ts +2 -0
  241. package/src/market-data/quotes/screener-live-quotes.ts +61 -9
  242. package/src/market-data/result-types.ts +2 -0
  243. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  244. package/src/plugins/builtin/account-management/model.ts +2 -56
  245. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  246. package/src/plugins/builtin/account-management/pane.tsx +37 -8
  247. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  248. package/src/plugins/builtin/alerts/cli.ts +313 -47
  249. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  250. package/src/plugins/builtin/alerts/events.ts +23 -2
  251. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  252. package/src/plugins/builtin/alerts/history.ts +2 -0
  253. package/src/plugins/builtin/alerts/index.tsx +41 -9
  254. package/src/plugins/builtin/alerts/pane.tsx +8 -0
  255. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  256. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  257. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  258. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  259. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  260. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  261. package/src/plugins/builtin/alerts/targets.ts +92 -0
  262. package/src/plugins/builtin/analytics/index.tsx +4 -2
  263. package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
  264. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  265. package/src/plugins/builtin/analytics/risk-model.ts +71 -12
  266. package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
  267. package/src/plugins/builtin/attention/index.tsx +2 -0
  268. package/src/plugins/builtin/attention/pane.tsx +3 -1
  269. package/src/plugins/builtin/attention/series.ts +26 -0
  270. package/src/plugins/builtin/awards/index.tsx +2 -0
  271. package/src/plugins/builtin/awards/pane.tsx +3 -1
  272. package/src/plugins/builtin/awards/series.ts +29 -0
  273. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  274. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  275. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  276. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  277. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  278. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  279. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  280. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  281. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  282. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  283. package/src/plugins/builtin/cds/client.ts +70 -13
  284. package/src/plugins/builtin/cds/headless.ts +116 -19
  285. package/src/plugins/builtin/cds/index.tsx +3 -1
  286. package/src/plugins/builtin/cds/model.ts +193 -31
  287. package/src/plugins/builtin/cds/pane.tsx +56 -14
  288. package/src/plugins/builtin/cds/series.ts +19 -0
  289. package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
  290. package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
  291. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
  292. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  293. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  294. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  295. package/src/plugins/builtin/chart-composer/headless.ts +8 -3
  296. package/src/plugins/builtin/chart-composer/index.tsx +9 -2
  297. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  298. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  299. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  300. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  301. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  302. package/src/plugins/builtin/chat/channels.ts +34 -36
  303. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  304. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  305. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  306. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  307. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  308. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  309. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  310. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  311. package/src/plugins/builtin/chat/controller/index.ts +50 -0
  312. package/src/plugins/builtin/chat/conversations.ts +256 -0
  313. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  314. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  315. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  316. package/src/plugins/builtin/chat/index.tsx +40 -2
  317. package/src/plugins/builtin/chat/layout.ts +2 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  319. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  321. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  322. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  323. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  324. package/src/plugins/builtin/chat/pane.tsx +8 -0
  325. package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
  326. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  327. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  328. package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
  329. package/src/plugins/builtin/cloud/askg/model.ts +156 -78
  330. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  331. package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
  332. package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
  333. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  334. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  335. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  336. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  337. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  338. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  339. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  340. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
  341. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  342. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  343. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  344. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  345. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  346. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  347. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
  348. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  349. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  350. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  351. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
  352. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
  353. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  355. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  356. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  359. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  360. package/src/plugins/builtin/company-attention/headless.ts +19 -5
  361. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  362. package/src/plugins/builtin/company-attention/model.ts +26 -7
  363. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  364. package/src/plugins/builtin/company-attention/series.ts +52 -0
  365. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  366. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  367. package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
  368. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  369. package/src/plugins/builtin/composite-plugins.ts +116 -67
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  374. package/src/plugins/builtin/credit-boards/index.tsx +23 -21
  375. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  376. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  377. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  378. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  379. package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
  380. package/src/plugins/builtin/credit-conditions/series.ts +26 -0
  381. package/src/plugins/builtin/credit-documents/headless.ts +31 -1
  382. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  383. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  384. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  385. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  386. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  387. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  388. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  389. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  390. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  391. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  392. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  393. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  394. package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
  395. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  396. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  397. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  398. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  399. package/src/plugins/builtin/docs/index.tsx +68 -0
  400. package/src/plugins/builtin/docs/pane.tsx +426 -0
  401. package/src/plugins/builtin/docs/targets.ts +72 -0
  402. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  403. package/src/plugins/builtin/doe/index.tsx +2 -0
  404. package/src/plugins/builtin/doe/series.ts +62 -0
  405. package/src/plugins/builtin/earnings/client.ts +3 -2
  406. package/src/plugins/builtin/earnings/format.ts +1 -5
  407. package/src/plugins/builtin/earnings/headless.ts +58 -6
  408. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  409. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  410. package/src/plugins/builtin/earnings/history.tsx +7 -3
  411. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  412. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  413. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  414. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  415. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  416. package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
  417. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  418. package/src/plugins/builtin/econ/index.tsx +70 -22
  419. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  420. package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
  421. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  422. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  423. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  424. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  425. package/src/plugins/builtin/executives/data.ts +17 -6
  426. package/src/plugins/builtin/executives/pane.tsx +16 -7
  427. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  428. package/src/plugins/builtin/exposure/pane.tsx +3 -1
  429. package/src/plugins/builtin/fear-greed/index.tsx +4 -0
  430. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  431. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  432. package/src/plugins/builtin/futures/index.tsx +43 -3
  433. package/src/plugins/builtin/futures/model.ts +1 -1
  434. package/src/plugins/builtin/futures/returns.ts +1 -1
  435. package/src/plugins/builtin/futures/series.ts +13 -0
  436. package/src/plugins/builtin/futures/table.tsx +1 -1
  437. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  438. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  439. package/src/plugins/builtin/futures-curve/headless.ts +70 -9
  440. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  441. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  442. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  443. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  444. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  445. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  446. package/src/plugins/builtin/gpu/board.tsx +13 -10
  447. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  448. package/src/plugins/builtin/gpu/client.ts +19 -1
  449. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  450. package/src/plugins/builtin/gpu/headless.ts +64 -27
  451. package/src/plugins/builtin/gpu/history.tsx +3 -3
  452. package/src/plugins/builtin/gpu/index.tsx +2 -0
  453. package/src/plugins/builtin/gpu/model.ts +114 -20
  454. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  455. package/src/plugins/builtin/gpu/series.ts +38 -0
  456. package/src/plugins/builtin/help/function-card.tsx +25 -6
  457. package/src/plugins/builtin/help/index.tsx +18 -8
  458. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  459. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  460. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  461. package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
  462. package/src/plugins/builtin/holders/client.ts +22 -3
  463. package/src/plugins/builtin/holders/format.ts +18 -3
  464. package/src/plugins/builtin/holders/headless.ts +42 -134
  465. package/src/plugins/builtin/holders/pane.tsx +14 -4
  466. package/src/plugins/builtin/holders/report-header.ts +40 -5
  467. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  468. package/src/plugins/builtin/insider/client.ts +35 -20
  469. package/src/plugins/builtin/insider/headless.ts +41 -11
  470. package/src/plugins/builtin/insider/index.tsx +27 -10
  471. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  472. package/src/plugins/builtin/insider/issuer.ts +49 -0
  473. package/src/plugins/builtin/insider/model.ts +3 -0
  474. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  475. package/src/plugins/builtin/iv-history/client.ts +26 -6
  476. package/src/plugins/builtin/iv-history/format.ts +33 -2
  477. package/src/plugins/builtin/iv-history/headless.ts +27 -12
  478. package/src/plugins/builtin/iv-history/index.tsx +5 -3
  479. package/src/plugins/builtin/iv-history/model.ts +172 -20
  480. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  481. package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
  482. package/src/plugins/builtin/iv-history/series.ts +29 -0
  483. package/src/plugins/builtin/jobs/headless.ts +28 -3
  484. package/src/plugins/builtin/jobs/index.tsx +3 -1
  485. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  486. package/src/plugins/builtin/jobs/series.ts +19 -0
  487. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  488. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  489. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  490. package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
  491. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  492. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  493. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  494. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  495. package/src/plugins/builtin/macro-day/client.ts +68 -3
  496. package/src/plugins/builtin/macro-day/headless.ts +18 -12
  497. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  498. package/src/plugins/builtin/macro-day/model.ts +66 -15
  499. package/src/plugins/builtin/macro-day/pane.tsx +34 -20
  500. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  501. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  502. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  503. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  504. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  505. package/src/plugins/builtin/market-heatmap/model.ts +102 -3
  506. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  507. package/src/plugins/builtin/market-movers/client.ts +7 -5
  508. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  509. package/src/plugins/builtin/market-movers/index.tsx +11 -3
  510. package/src/plugins/builtin/market-movers/model.ts +101 -17
  511. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  512. package/src/plugins/builtin/market-movers/table.ts +50 -23
  513. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  514. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  515. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  516. package/src/plugins/builtin/members/headless.ts +7 -2
  517. package/src/plugins/builtin/members/model.ts +31 -3
  518. package/src/plugins/builtin/members/pane.tsx +3 -6
  519. package/src/plugins/builtin/mna/headless.ts +15 -3
  520. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  521. package/src/plugins/builtin/money-markets/series.ts +41 -0
  522. package/src/plugins/builtin/news/headless.ts +9 -2
  523. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  524. package/src/plugins/builtin/notes/cli.ts +12 -7
  525. package/src/plugins/builtin/openfda/client.ts +1 -1
  526. package/src/plugins/builtin/options/carry.ts +95 -0
  527. package/src/plugins/builtin/options/index.tsx +58 -5
  528. package/src/plugins/builtin/options/strike-window.ts +183 -0
  529. package/src/plugins/builtin/options/table.ts +55 -3
  530. package/src/plugins/builtin/options/types.ts +8 -1
  531. package/src/plugins/builtin/options/view.tsx +162 -13
  532. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  533. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  534. package/src/plugins/builtin/options-positioning/headless.ts +5 -2
  535. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  536. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  537. package/src/plugins/builtin/options-scenario/client.ts +75 -18
  538. package/src/plugins/builtin/options-scenario/headless.ts +72 -24
  539. package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
  540. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  541. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  542. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  543. package/src/plugins/builtin/pe-band/model.ts +2 -2
  544. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  545. package/src/plugins/builtin/perps/client.ts +40 -6
  546. package/src/plugins/builtin/perps/equity-row.tsx +33 -8
  547. package/src/plugins/builtin/perps/freshness.ts +66 -0
  548. package/src/plugins/builtin/perps/headless.ts +45 -30
  549. package/src/plugins/builtin/perps/index.tsx +18 -1
  550. package/src/plugins/builtin/perps/model.ts +32 -6
  551. package/src/plugins/builtin/perps/pane.tsx +76 -20
  552. package/src/plugins/builtin/perps/series.ts +76 -0
  553. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  554. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  555. package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
  556. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  557. package/src/plugins/builtin/plugin-module.ts +90 -4
  558. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  559. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
  560. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  561. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
  562. package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
  563. package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
  564. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
  565. package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
  566. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  567. package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
  568. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  569. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  570. package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
  571. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
  572. package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
  573. package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
  574. package/src/plugins/builtin/power/client.ts +16 -0
  575. package/src/plugins/builtin/power/evidence.ts +6 -2
  576. package/src/plugins/builtin/power/headless.ts +71 -7
  577. package/src/plugins/builtin/power/index.tsx +4 -1
  578. package/src/plugins/builtin/power/model.ts +72 -1
  579. package/src/plugins/builtin/power/pane.tsx +32 -9
  580. package/src/plugins/builtin/rate-path/headless.ts +11 -3
  581. package/src/plugins/builtin/realized-vol/headless.ts +8 -0
  582. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  583. package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
  584. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  585. package/src/plugins/builtin/research/event-model.ts +68 -24
  586. package/src/plugins/builtin/research/events-headless.ts +2 -1
  587. package/src/plugins/builtin/research/headless.ts +2 -1
  588. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  589. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  590. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  591. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  592. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  593. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  594. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  595. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  596. package/src/plugins/builtin/seasonality/client.ts +15 -7
  597. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  598. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  599. package/src/plugins/builtin/seasonality/model.ts +119 -0
  600. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  601. package/src/plugins/builtin/sec/index.tsx +5 -5
  602. package/src/plugins/builtin/sectors/client.ts +10 -2
  603. package/src/plugins/builtin/sectors/headless.ts +35 -6
  604. package/src/plugins/builtin/sectors/index.tsx +18 -1
  605. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  606. package/src/plugins/builtin/series-inventory.ts +91 -0
  607. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  608. package/src/plugins/builtin/shared/command-tab.ts +69 -0
  609. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  610. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  611. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  612. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  613. package/src/plugins/builtin/shared/members-menu.tsx +4 -4
  614. package/src/plugins/builtin/shared/open-description.ts +29 -0
  615. package/src/plugins/builtin/shared/report-freshness.ts +59 -2
  616. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  617. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  618. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  619. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  620. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  621. package/src/plugins/builtin/short-interest/index.tsx +21 -4
  622. package/src/plugins/builtin/short-interest/series.ts +36 -0
  623. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  624. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  625. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  626. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  627. package/src/plugins/builtin/short-volume/index.tsx +3 -10
  628. package/src/plugins/builtin/short-volume/series.ts +23 -0
  629. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  630. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  631. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  632. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  633. package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
  634. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  635. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  636. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  637. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  638. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  639. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  640. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  641. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
  643. package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
  649. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  650. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  651. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  652. package/src/plugins/builtin/time-sales/headless.ts +1 -0
  653. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  654. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  655. package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
  656. package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
  657. package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
  658. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  659. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  660. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  661. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  662. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  663. package/src/plugins/builtin/vol-surface/headless.ts +125 -20
  664. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  665. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  666. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  667. package/src/plugins/builtin/volatility/index.tsx +2 -0
  668. package/src/plugins/builtin/volatility/series.ts +84 -0
  669. package/src/plugins/builtin/world-indices/client.ts +22 -4
  670. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  671. package/src/plugins/builtin/world-indices/model.ts +4 -2
  672. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  673. package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
  674. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  675. package/src/plugins/builtin/world-venue-map/index.ts +3 -2
  676. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
  677. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  678. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  679. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  680. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  681. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  682. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  683. package/src/plugins/builtin-editorial.ts +126 -0
  684. package/src/plugins/catalog-backend.ts +16 -9
  685. package/src/plugins/catalog-browser.ts +129 -64
  686. package/src/plugins/catalog-manifest.ts +73 -40
  687. package/src/plugins/catalog-ui.ts +26 -6
  688. package/src/plugins/extracted-plugins.ts +7 -1
  689. package/src/plugins/ownership.ts +150 -7
  690. package/src/plugins/plugin-functions.ts +54 -0
  691. package/src/plugins/plugin-off.ts +36 -0
  692. package/src/plugins/registry/host-actions.ts +16 -0
  693. package/src/plugins/registry/index.ts +173 -28
  694. package/src/plugins/registry/plugin-state.ts +25 -1
  695. package/src/plugins/runtime/context.tsx +29 -0
  696. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  697. package/src/portfolio/position-value.ts +40 -0
  698. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  699. package/src/public/time-series.ts +17 -0
  700. package/src/react/auto-refresh.ts +13 -3
  701. package/src/react/input.ts +48 -1
  702. package/src/remote/app-host.tsx +25 -4
  703. package/src/remote/confirm-change.tsx +85 -0
  704. package/src/remote/controller-utils.ts +8 -1
  705. package/src/remote/controller.ts +126 -59
  706. package/src/remote/matching.ts +69 -0
  707. package/src/remote/pane-screenshot.ts +47 -0
  708. package/src/remote/schema.ts +63 -1
  709. package/src/remote/semantic-tree.tsx +14 -0
  710. package/src/remote/types.ts +32 -0
  711. package/src/remote/watchlist.ts +306 -0
  712. package/src/renderers/browser/main.tsx +3 -2
  713. package/src/renderers/cloudflare/worker.ts +1 -1
  714. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  715. package/src/renderers/dom/data-table/index.tsx +33 -6
  716. package/src/renderers/dom/data-table/row.tsx +27 -1
  717. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  718. package/src/renderers/dom/desktop/controls.tsx +30 -23
  719. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  720. package/src/renderers/dom/desktop/icons.tsx +21 -0
  721. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  722. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  723. package/src/renderers/dom/host/box.tsx +4 -1
  724. package/src/renderers/dom/host/chart-surface.tsx +6 -2
  725. package/src/renderers/dom/host/drag-shield.ts +17 -6
  726. package/src/renderers/dom/host/live-frame.ts +14 -2
  727. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  728. package/src/renderers/dom/host/size-observer.ts +26 -0
  729. package/src/renderers/dom/host/surface-3d.tsx +7 -2
  730. package/src/renderers/dom/host/text.tsx +1 -1
  731. package/src/renderers/dom/input-host.tsx +6 -1
  732. package/src/renderers/dom/styles.css +74 -0
  733. package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
  734. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  735. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
  736. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  737. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
  738. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
  739. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  740. package/src/renderers/electrobun/view/main.tsx +6 -1
  741. package/src/renderers/opentui/input-host.tsx +6 -1
  742. package/src/renderers/opentui/start.tsx +9 -0
  743. package/src/series/capability.ts +75 -0
  744. package/src/series/csv.ts +160 -0
  745. package/src/series/files.ts +107 -0
  746. package/src/series/registry.ts +198 -0
  747. package/src/series/resolve.ts +107 -0
  748. package/src/series/standalone.ts +48 -0
  749. package/src/series/types.ts +145 -0
  750. package/src/series/validate.ts +171 -0
  751. package/src/shares/portable-layout.ts +16 -6
  752. package/src/sources/gloomberb-cloud/index.ts +26 -17
  753. package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
  754. package/src/sources/history-result.ts +1 -0
  755. package/src/sources/listing-symbols.ts +14 -5
  756. package/src/sources/provider-errors.ts +88 -3
  757. package/src/sources/provider-router/batches.ts +4 -1
  758. package/src/sources/provider-router/cache.ts +4 -2
  759. package/src/sources/provider-router/cached-routes.ts +9 -5
  760. package/src/sources/provider-router/financial-routes.ts +12 -5
  761. package/src/sources/provider-router/financials.ts +55 -15
  762. package/src/sources/provider-router/history.ts +68 -34
  763. package/src/sources/provider-router/index.ts +1 -1
  764. package/src/sources/provider-router/primary.ts +23 -5
  765. package/src/sources/provider-router/search.ts +1 -0
  766. package/src/sources/sec-edgar.ts +68 -8
  767. package/src/sync/core-contributors.ts +5 -3
  768. package/src/test-support/cli-context.ts +2 -1
  769. package/src/test-support/data-provider.ts +34 -0
  770. package/src/test-support/shell-pane-keys.tsx +1 -0
  771. package/src/theme/series-colors.ts +46 -0
  772. package/src/theme/themes.ts +149 -0
  773. package/src/tickers/company-name.ts +75 -0
  774. package/src/tickers/instrument-kind.ts +25 -0
  775. package/src/tickers/open-target.ts +3 -2
  776. package/src/tickers/search/index.ts +67 -9
  777. package/src/tickers/search/ranking.ts +78 -18
  778. package/src/tickers/search/types.ts +10 -2
  779. package/src/tickers/starter-symbols.ts +8 -0
  780. package/src/tickers/us-listing.ts +34 -0
  781. package/src/time-series/hooks.ts +9 -0
  782. package/src/time-series/resolve.ts +96 -30
  783. package/src/time-series/types.ts +4 -2
  784. package/src/time-series/use-chart-resolution.ts +32 -0
  785. package/src/types/config.ts +67 -1
  786. package/src/types/data-provider.ts +5 -0
  787. package/src/types/financials.ts +52 -1
  788. package/src/types/headless.ts +72 -0
  789. package/src/types/instrument.ts +8 -0
  790. package/src/types/plugin.ts +68 -3
  791. package/src/types/price-history.ts +7 -0
  792. package/src/types/ticker.ts +14 -0
  793. package/src/ui/host.tsx +26 -4
  794. package/src/ui/index.tsx +2 -0
  795. package/src/ui/live-resize.ts +81 -0
  796. package/src/ui/live-stretch.ts +121 -0
  797. package/src/ui/measured-cells.ts +58 -0
  798. package/src/ui/pane-fill.ts +11 -0
  799. package/src/utils/basis-points.ts +17 -0
  800. package/src/utils/cli-output.ts +21 -2
  801. package/src/utils/concurrency.ts +25 -0
  802. package/src/utils/crypto-pair.ts +20 -0
  803. package/src/utils/currency-pair.ts +19 -0
  804. package/src/utils/decimal-comma.ts +19 -0
  805. package/src/utils/dom-screenshot-css.ts +265 -0
  806. package/src/utils/dom-screenshot-rasters.ts +276 -0
  807. package/src/utils/dom-screenshot.ts +437 -52
  808. package/src/utils/exchange-rate-snapshot.ts +6 -2
  809. package/src/utils/exchanges.ts +120 -1
  810. package/src/utils/format.ts +17 -3
  811. package/src/utils/fundamentals.ts +66 -0
  812. package/src/utils/futures-generic.ts +6 -12
  813. package/src/utils/fx-market-hours.ts +44 -0
  814. package/src/utils/option-expiry.ts +126 -0
  815. package/src/utils/price-history.ts +130 -40
  816. package/src/utils/rpc-timeout-error.ts +6 -2
  817. package/src/utils/sec-eps-basis.ts +178 -36
  818. package/src/utils/sec.ts +98 -40
  819. package/src/utils/throttled-fetch.ts +51 -22
  820. package/src/utils/utc-time.ts +51 -4
@@ -0,0 +1,92 @@
1
+ import { useCallback } from "react";
2
+ import type { PaneHint } from "../../../components";
3
+ import type { PaneTemplateCreateOptions } from "../../../types/plugin";
4
+ import { usePluginAppActions } from "../../runtime";
5
+ import { RESEARCH_SEARCH_TEMPLATE_ID } from "../research-search/model";
6
+ import { useOpenDescription } from "../shared/open-description";
7
+ import { THIRTEENF_TEMPLATE_ID } from "../thirteenf/model";
8
+ import type { EventAlertRule } from "./events";
9
+ import type { AlertHistoryItem } from "./history";
10
+ import { isResearchAlertKind, readResearchRule } from "./research-rules";
11
+ import type { AlertRule } from "./types";
12
+
13
+ /** What an alert follows, read the same way from a saved rule and from a delivered alert. */
14
+ export interface AlertSubject {
15
+ kind: string;
16
+ symbol?: string;
17
+ exchange?: string;
18
+ marketId?: string;
19
+ /** A macro event rule's release: `cpi` or `fomc`. */
20
+ event?: string;
21
+ keyword?: string;
22
+ cik?: string;
23
+ }
24
+
25
+ /** A listing's DES, or a pane template and what it opens on. */
26
+ export type AlertTarget =
27
+ | { kind: "description"; symbol: string; exchange?: string }
28
+ | { kind: "pane"; templateId: string; options?: PaneTemplateCreateOptions };
29
+
30
+ const pane = (templateId: string, options?: PaneTemplateCreateOptions): AlertTarget =>
31
+ ({ kind: "pane", templateId, ...(options ? { options } : {}) });
32
+
33
+ /**
34
+ * The one map from what an alert follows to what it opens, for every rule kind and every delivered alert:
35
+ * a perpetual opens PERP on its market; a dated event the pane its date comes from (ERN, CPI, WIRP); catalyst,
36
+ * Congress and 13F rules their calendar or list, on the company or fund they name; any other rule on a security
37
+ * that listing's DES. A rule on no security opens the pane it watches (SRCH for a news keyword, FLOW for flow
38
+ * on the user's lists, FIRST for breaking news). Null when there is nothing to open.
39
+ */
40
+ export function alertTarget(subject: AlertSubject): AlertTarget | null {
41
+ const { kind, symbol } = subject;
42
+ switch (kind) {
43
+ case "perps_threshold": return subject.marketId ? pane("perps-pane", { arg: subject.marketId }) : null;
44
+ case "earnings_date":
45
+ case "earnings": return symbol ? pane("earnings-calendar-pane", { arg: symbol }) : null;
46
+ case "macro_event": return subject.event === "cpi" ? pane("cpi-pane") : subject.event === "fomc" ? pane("rate-path-pane") : null;
47
+ case "catalyst": return pane("catalysts-pane", symbol ? { symbol } : undefined);
48
+ case "congress_trade": return pane("congress-trades-pane");
49
+ case "thirteenf_filing": return pane(THIRTEENF_TEMPLATE_ID, subject.cik ? { arg: subject.cik } : undefined);
50
+ case "news_keyword": if (!symbol) return pane(RESEARCH_SEARCH_TEMPLATE_ID, subject.keyword ? { arg: subject.keyword } : undefined); break;
51
+ case "options_flow": if (!symbol) return pane("scanner-flow-pane"); break;
52
+ case "breaking_news": if (!symbol) return pane("news-breaking-pane"); break;
53
+ }
54
+ return symbol ? { kind: "description", symbol, ...(subject.exchange ? { exchange: subject.exchange } : {}) } : null;
55
+ }
56
+
57
+ /** A research rule's `US` is any US venue, which names no listing. */
58
+ const venue = (exchange: string | undefined) => exchange && exchange !== "US" ? exchange : undefined;
59
+
60
+ /** An Events rule: a ticker, a fund or a research rule's own fields. */
61
+ export function eventRuleSubject(rule: EventAlertRule): AlertSubject {
62
+ if (isResearchAlertKind(rule.kind)) {
63
+ const config = readResearchRule(rule.kind, rule.value);
64
+ return { kind: rule.kind, symbol: config?.symbol, exchange: venue(config?.exchange), marketId: config?.marketId, event: config?.event, keyword: config?.keyword };
65
+ }
66
+ return { kind: rule.kind, ...(rule.target === "ticker" ? { symbol: rule.value } : rule.target === "fund" ? { cik: rule.value } : {}) };
67
+ }
68
+
69
+ export const priceRuleSubject = (alert: AlertRule): AlertSubject => ({ kind: "price", symbol: alert.symbol, exchange: alert.exchange });
70
+
71
+ /** A delivered alert, from the fields its notification carries. */
72
+ export function deliveredAlertSubject(item: AlertHistoryItem): AlertSubject {
73
+ const text = (key: string) => {
74
+ const value = item.data?.[key];
75
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
76
+ };
77
+ return { kind: item.kind, symbol: text("symbol"), exchange: venue(text("exchange")), marketId: text("marketId"), event: text("event"), keyword: text("keyword"), cik: text("cik") };
78
+ }
79
+
80
+ /** The `v` hint each alerts tab gives its selected row, when the row has something to open. */
81
+ export const alertViewHints = (target: AlertTarget | null, open: (target: AlertTarget) => void): PaneHint[] =>
82
+ target ? [{ id: "view", key: "v", label: "iew", title: "View what it follows", onPress: () => open(target) }] : [];
83
+
84
+ /** Opens an alert's target: a DES the way every pane's `d` does, any other pane from its template. */
85
+ export function useOpenAlertTarget(): (target: AlertTarget) => void {
86
+ const openDescription = useOpenDescription();
87
+ const { createPaneFromTemplate } = usePluginAppActions();
88
+ return useCallback((target: AlertTarget) => {
89
+ if (target.kind === "description") openDescription(target.symbol, target.exchange);
90
+ else createPaneFromTemplate(target.templateId, target.options);
91
+ }, [createPaneFromTemplate, openDescription]);
92
+ }
@@ -450,13 +450,15 @@ export const portfolioAnalyticsModule: PluginModule = {
450
450
  component: PortfolioAnalyticsPane,
451
451
  headless: portfolioRiskHeadless,
452
452
  tableExport: true,
453
- settings: { fields: [
453
+ // The risk window reads as trailing until it is set.
454
+ settings: (context) => ({ values: { riskSince: context.settings.riskSince ?? "trailing" }, fields: [
454
455
  { key: "analyticsView", label: "View", type: "select", options: [{ value: "overview", label: "Overview" }, { value: "risk", label: "Risk depth" }] },
456
+ { key: "riskSince", label: "Risk window", type: "select", options: [{ value: "trailing", label: "Trailing 60 sessions" }, { value: "filed", label: "Since 13F filing" }] },
455
457
  { key: "riskEvidence", label: "Local evidence JSON", type: "text" },
456
458
  { key: "equityShift", label: "Index shift (%)", type: "text" },
457
459
  { key: "rateShift", label: "10Y shift (bp)", type: "text" },
458
460
  { key: "volShift", label: "VIX shift (points)", type: "text" },
459
- ] },
461
+ ] }),
460
462
  defaultPosition: "right",
461
463
  defaultMode: "floating",
462
464
  defaultFloatingSize: { width: 80, height: 30 },
@@ -11,8 +11,10 @@ import {
11
11
  riskCoverageShortfall,
12
12
  riskCoverageText,
13
13
  RISK_VIEWS,
14
+ riskEvidence,
14
15
  riskPercentile,
15
16
  riskValue,
17
+ sinceFallbackNote,
16
18
  type PortfolioRiskModel,
17
19
  type RiskCoverage,
18
20
  type RiskDisplayRow,
@@ -39,7 +41,8 @@ function displayRow(row: RiskDisplayRow) {
39
41
  value: riskValue(row),
40
42
  percentile: riskPercentile(row),
41
43
  asOf: row.asOf?.slice(0, 10) ?? null,
42
- detail: row.detail,
44
+ detail: riskEvidence(row),
45
+ ...(row.amount != null ? { amount: row.amount, currency: row.amountCurrency ?? null } : {}),
43
46
  };
44
47
  }
45
48
 
@@ -130,9 +133,16 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
130
133
  key: "view",
131
134
  type: "enum",
132
135
  settingKey: "riskView",
133
- defaultValue: "risk",
136
+ // No default: left out, the report prints every view.
134
137
  values: RISK_VIEWS.map((value) => ({ value })),
135
- description: "Portfolio risk view.",
138
+ description: "One portfolio risk view; every view when left out.",
139
+ },
140
+ {
141
+ key: "since",
142
+ type: "enum",
143
+ settingKey: "riskSince",
144
+ values: [{ value: "filed" }],
145
+ description: "Risk rows since the 13F filing date of a portfolio made with portfolio import --13f, instead of the trailing 60 sessions.",
136
146
  },
137
147
  {
138
148
  key: "evidence",
@@ -144,28 +154,25 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
144
154
  key: "equity-shift",
145
155
  type: "integer",
146
156
  settingKey: "equityShift",
147
- defaultValue: -10,
148
157
  minimum: -99,
149
158
  maximum: 100,
150
- description: "Independent index shock in percent.",
159
+ description: "Independent index shock in percent (-10 when left out).",
151
160
  },
152
161
  {
153
162
  key: "rate-shift",
154
163
  type: "integer",
155
164
  settingKey: "rateShift",
156
- defaultValue: 100,
157
165
  minimum: -500,
158
166
  maximum: 500,
159
- description: "Independent 10Y yield shock in basis points.",
167
+ description: "Independent 10Y yield shock in basis points (100 when left out).",
160
168
  },
161
169
  {
162
170
  key: "vol-shift",
163
171
  type: "integer",
164
172
  settingKey: "volShift",
165
- defaultValue: 10,
166
173
  minimum: -50,
167
174
  maximum: 100,
168
- description: "Independent VIX shock in index points.",
175
+ description: "Independent VIX shock in index points (10 when left out).",
169
176
  },
170
177
  ],
171
178
  describe: (args) =>
@@ -191,7 +198,8 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
191
198
  throw new Error(
192
199
  "Imported evidence belongs to a different portfolio or currency",
193
200
  );
194
- const view = String(args.options.view ?? "risk");
201
+ const requestedView = isRiskView(args.options.view) ? args.options.view : null;
202
+ const view: string = requestedView ?? "risk";
195
203
  const localOnly =
196
204
  ["performance", "attribution", "greeks"].includes(view) &&
197
205
  evidence != null;
@@ -226,7 +234,17 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
226
234
  rates: Number(args.options["rate-shift"] ?? 100),
227
235
  volatility: Number(args.options["vol-shift"] ?? 10),
228
236
  },
237
+ args.options.since === "filed" ? { since: "filed" } : {},
229
238
  );
239
+ // Options for views the report does not print are named, not dropped silently; the fallback from --since opens the report.
240
+ const fallback = sinceFallbackNote(local.portfolio);
241
+ const shifted = ["equity-shift", "rate-shift", "vol-shift"].filter((key) => args.options[key] != null);
242
+ const notices = [
243
+ ...(model.window.kind === "since-filed" ? [`Risk rows since the 13F filing on ${model.window.filed}, against ${model.benchmark}`] : []),
244
+ ...(args.options.since === "filed" && model.window.kind !== "since-filed" ? [fallback] : []),
245
+ ...(requestedView && requestedView !== "stress" && shifted.length ? [`${shifted.map((key) => `--${key}`).join(", ")} change${shifted.length === 1 ? "s" : ""} the stress view only, not --view ${requestedView}`] : []),
246
+ ...(requestedView && args.options.since != null && requestedView !== "risk" ? [`--since changes the risk view only, not --view ${requestedView}`] : []),
247
+ ];
230
248
  // A basket view is complete only when the basket covers every holding.
231
249
  const covered = model.coverage.leftOut.length === 0;
232
250
  const complete =
@@ -246,13 +264,13 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
246
264
  return {
247
265
  complete,
248
266
  errors: [...(shortfall ? [shortfall] : []), ...model.warnings],
249
- notes: [...riskCoverageNotices(model.coverage), ...model.notes],
250
- sections: RISK_VIEWS.map((view) => ({
267
+ notes: [...riskCoverageNotices(model.coverage), ...model.notes.filter((note) => note !== fallback)],
268
+ sections: (requestedView ? [requestedView] : RISK_VIEWS).map((view) => ({
251
269
  title: view,
252
270
  columns: RISK_COLUMNS,
253
271
  rows: model.rows[view].map(displayRow),
254
272
  })),
255
- metadata: { coverage: coverageSummary(model.coverage), model },
273
+ metadata: { coverage: coverageSummary(model.coverage), model, benchmark: model.benchmark, window: model.window, notices },
256
274
  };
257
275
  },
258
276
  compact(result, args) {
@@ -278,6 +296,8 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
278
296
  currency: model.portfolio.currency,
279
297
  },
280
298
  view,
299
+ benchmark: model.benchmark,
300
+ window: model.window,
281
301
  ...(basketView && model.coverage
282
302
  ? { coverage: coverageSummary(model.coverage, COMPACT_LEFT_OUT_LIMIT) }
283
303
  : {}),
@@ -186,28 +186,24 @@ const percentile = (
186
186
  };
187
187
  };
188
188
 
189
- export function rollingBasketRisk(
190
- sample: readonly RiskSamplePoint[],
191
- window = RISK_WINDOW,
192
- ): RiskStatistic[] {
193
- if (!Number.isInteger(window) || window < 60)
194
- throw new Error("Risk window must contain at least 60 daily sessions");
195
- const definitions = [
189
+ /** The return and risk statistics of a basket against its benchmark, over one window of paired sessions. */
190
+ function basketRiskDefinitions(benchmark: string) {
191
+ return [
196
192
  {
197
193
  id: "return",
198
- label: `${window}D basket return`,
194
+ name: "basket return",
199
195
  value: (rows: RiskSamplePoint[]) =>
200
196
  100 * compoundReturns(rows.map((row) => row.value)),
201
197
  },
202
198
  {
203
199
  id: "benchmark",
204
- label: `${window}D benchmark return`,
200
+ name: `benchmark return (${benchmark})`,
205
201
  value: (rows: RiskSamplePoint[]) =>
206
202
  100 * compoundReturns(rows.map((row) => row.benchmark)),
207
203
  },
208
204
  {
209
205
  id: "active",
210
- label: `${window}D active return`,
206
+ name: "active return",
211
207
  value: (rows: RiskSamplePoint[]) =>
212
208
  100 *
213
209
  (compoundReturns(rows.map((row) => row.value)) -
@@ -215,36 +211,56 @@ export function rollingBasketRisk(
215
211
  },
216
212
  {
217
213
  id: "volatility",
218
- label: `${window}D annualized volatility`,
219
- value: (rows: RiskSamplePoint[]) =>
220
- 100 * sampleVolatility(rows.map((row) => row.value))!,
214
+ name: "annualized volatility",
215
+ value: (rows: RiskSamplePoint[]) => {
216
+ const volatility = sampleVolatility(rows.map((row) => row.value));
217
+ return volatility == null ? null : 100 * volatility;
218
+ },
221
219
  },
222
220
  {
223
221
  id: "drawdown",
224
- label: `${window}D max drawdown`,
222
+ name: "max drawdown",
225
223
  value: (rows: RiskSamplePoint[]) =>
226
224
  100 * Math.min(0, ...drawdownPath(rows.map((row) => row.value))),
227
225
  },
228
226
  {
229
227
  id: "var",
230
- label: `1D VaR 95% (${window}D)`,
231
- value: (rows: RiskSamplePoint[]) =>
232
- 100 * historicalTail(rows.map((row) => row.value))!.var,
228
+ name: "1D VaR 95%",
229
+ value: (rows: RiskSamplePoint[]) => {
230
+ const tail = historicalTail(rows.map((row) => row.value));
231
+ return tail == null ? null : 100 * tail.var;
232
+ },
233
233
  },
234
234
  {
235
235
  id: "es",
236
- label: `1D expected shortfall (${window}D)`,
237
- value: (rows: RiskSamplePoint[]) =>
238
- 100 * historicalTail(rows.map((row) => row.value))!.expectedShortfall,
236
+ name: "1D expected shortfall",
237
+ value: (rows: RiskSamplePoint[]) => {
238
+ const tail = historicalTail(rows.map((row) => row.value));
239
+ return tail == null ? null : 100 * tail.expectedShortfall;
240
+ },
239
241
  },
240
242
  {
241
243
  id: "tracking",
242
- label: `${window}D tracking error`,
243
- value: (rows: RiskSamplePoint[]) =>
244
- 100 * sampleVolatility(rows.map((row) => row.value - row.benchmark))!,
244
+ name: "tracking error",
245
+ value: (rows: RiskSamplePoint[]) => {
246
+ const volatility = sampleVolatility(rows.map((row) => row.value - row.benchmark));
247
+ return volatility == null ? null : 100 * volatility;
248
+ },
245
249
  },
246
250
  ];
247
- return definitions.map((definition) => {
251
+ }
252
+ const TAIL_IDS = new Set(["var", "es"]);
253
+ const finiteOrNull = (value: number | null) =>
254
+ value != null && Number.isFinite(value) ? value : null;
255
+
256
+ export function rollingBasketRisk(
257
+ sample: readonly RiskSamplePoint[],
258
+ window = RISK_WINDOW,
259
+ benchmark = "SPY",
260
+ ): RiskStatistic[] {
261
+ if (!Number.isInteger(window) || window < 60)
262
+ throw new Error("Risk window must contain at least 60 daily sessions");
263
+ return basketRiskDefinitions(benchmark).map((definition) => {
248
264
  const history = sample.map((point, index) => {
249
265
  const rows = sample.slice(index - window + 1, index + 1);
250
266
  const contiguous =
@@ -252,10 +268,9 @@ export function rollingBasketRisk(
252
268
  rows.every(
253
269
  (row, i) => i === 0 || row.startDateKey === rows[i - 1]!.dateKey,
254
270
  );
255
- const value = contiguous ? definition.value(rows) : null;
256
271
  return {
257
272
  date: point.dateKey,
258
- value: value != null && Number.isFinite(value) ? value : null,
273
+ value: contiguous ? finiteOrNull(definition.value(rows)) : null,
259
274
  };
260
275
  });
261
276
  const latest = history.at(-1),
@@ -263,7 +278,9 @@ export function rollingBasketRisk(
263
278
  asOf = latest?.date ?? null;
264
279
  return {
265
280
  id: definition.id,
266
- label: definition.label,
281
+ label: TAIL_IDS.has(definition.id)
282
+ ? `${definition.name} (${window}D)`
283
+ : `${window}D ${definition.name}`,
267
284
  value,
268
285
  unit: "%" as const,
269
286
  asOf,
@@ -276,6 +293,53 @@ export function rollingBasketRisk(
276
293
  });
277
294
  }
278
295
 
296
+ /**
297
+ * The same statistics over every paired session since `since` (a 13F filing
298
+ * date), measured from the last close on or before it: the trailing
299
+ * contiguous run of sessions that end after that day. Each row's history is
300
+ * the statistic as of each session in the run; there is no rolling sample to
301
+ * rank it against, so it has no percentile. VaR and expected shortfall need
302
+ * 60 sessions.
303
+ */
304
+ export function sinceBasketRisk(
305
+ sample: readonly RiskSamplePoint[],
306
+ since: string,
307
+ benchmark = "SPY",
308
+ ): RiskStatistic[] {
309
+ let first = sample.length;
310
+ while (
311
+ first > 0 &&
312
+ sample[first - 1]!.dateKey > since &&
313
+ (first === sample.length || sample[first]!.startDateKey === sample[first - 1]!.dateKey)
314
+ )
315
+ first -= 1;
316
+ const rows = sample.slice(first);
317
+ const start = rows[0]?.startDateKey ?? since;
318
+ const capitalized = (text: string) => `${text[0]!.toUpperCase()}${text.slice(1)}`;
319
+ return basketRiskDefinitions(benchmark).map((definition) => {
320
+ const history = rows.map((point, index) => ({
321
+ date: point.dateKey,
322
+ value: finiteOrNull(definition.value(rows.slice(0, index + 1))),
323
+ }));
324
+ const value = history.at(-1)?.value ?? null,
325
+ asOf = rows.at(-1)?.dateKey ?? null;
326
+ return {
327
+ id: definition.id,
328
+ label: TAIL_IDS.has(definition.id)
329
+ ? `${definition.name} (since ${start})`
330
+ : `${capitalized(definition.name)} since ${start}`,
331
+ value,
332
+ unit: "%" as const,
333
+ asOf,
334
+ startDate: rows.length ? start : null,
335
+ // The sessions in the window, also when too few for a value (a tail estimate needs 60).
336
+ samples: rows.length,
337
+ rank: { ...historyStatistics([], value, { asOf: asOf ?? since }), percentile: null, rank: null },
338
+ history,
339
+ };
340
+ });
341
+ }
342
+
279
343
  export function rollingBeta(
280
344
  asset: readonly DatedReturn[],
281
345
  factor: readonly DatedReturn[],
@@ -1,11 +1,11 @@
1
1
  import { portfolioOptionGreeks } from "./risk-options";
2
2
  import type { Portfolio, TickerRecord } from "../../../types/ticker";
3
- import { formatNumber } from "../../../utils/format";
3
+ import { formatCurrency, formatNumber } from "../../../utils/format";
4
4
  import { resolveCurrencyUnit } from "../../../utils/currency-units";
5
5
  import {
6
6
  getPortfolioPositionMetrics,
7
7
  resolvePortfolioMarketValue,
8
- } from "../portfolio-list/position-metrics";
8
+ } from "../../../portfolio/position-metrics";
9
9
  import type { DatedReturn } from "./metrics";
10
10
  import {
11
11
  computeWeightedPortfolioReturns,
@@ -17,6 +17,7 @@ import {
17
17
  regressReturns,
18
18
  rollingBasketRisk,
19
19
  rollingBeta,
20
+ sinceBasketRisk,
20
21
  subtractReturns,
21
22
  } from "./risk-math";
22
23
  import {
@@ -97,7 +98,13 @@ export interface RiskDisplayRow {
97
98
  interaction?: number;
98
99
  /** Holdings rows only: why the holding is outside the covered basket. */
99
100
  leftOut?: string;
101
+ /** VaR and expected shortfall only: the loss `value` is on the covered basket's current value (`amountBase`), in `amountCurrency`. */
102
+ amount?: number;
103
+ amountCurrency?: string;
104
+ amountBase?: number;
100
105
  }
106
+ /** The tail-loss rows, which also read in money on the covered basket. */
107
+ const TAIL_ROW_IDS: ReadonlySet<string> = new Set(["var", "es"]);
101
108
  /**
102
109
  * Below half of market value the qualifying holdings are not most of the
103
110
  * account, so a basket estimate would mostly describe something other than it;
@@ -124,6 +131,22 @@ export interface RiskShifts {
124
131
  rates: number;
125
132
  volatility: number;
126
133
  }
134
+ /** The benchmark the basket's returns, active return and tracking error are measured against. */
135
+ const RISK_BENCHMARK = "SPY";
136
+
137
+ /**
138
+ * The window the risk rows cover: the trailing 60 sessions, or, with `since:
139
+ * "filed"`, every session since the filing date of a portfolio imported from
140
+ * a 13F.
141
+ */
142
+ export interface RiskWindowRequest {
143
+ since?: "filed";
144
+ }
145
+
146
+ /** Why a portfolio asked for risk since its filing shows the trailing window instead. */
147
+ export const sinceFallbackNote = (portfolio: Pick<Portfolio, "name">) =>
148
+ `"${portfolio.name}" was not imported from a 13F, so it has no filing date; the risk rows cover the trailing 60 sessions.`;
149
+
127
150
  const DEFAULT_RISK_SHIFTS: RiskShifts = {
128
151
  equity: -10,
129
152
  rates: 100,
@@ -287,6 +310,7 @@ export function buildPortfolioRisk(
287
310
  market: RiskMarketSnapshot,
288
311
  evidence: PortfolioRiskEvidence | null = null,
289
312
  shifts: RiskShifts = DEFAULT_RISK_SHIFTS,
313
+ window: RiskWindowRequest = {},
290
314
  ) {
291
315
  if (
292
316
  ![shifts.equity, shifts.rates, shifts.volatility].every(Number.isFinite) ||
@@ -469,9 +493,15 @@ export function buildPortfolioRisk(
469
493
  );
470
494
  return (instrument && byId.get(riskInstrumentId(instrument))?.returns) || [];
471
495
  };
472
- const benchmark = proxy("SPY"),
496
+ const benchmark = proxy(RISK_BENCHMARK),
473
497
  sample = pairedReturns(basket, benchmark);
474
- const metrics = rollingBasketRisk(sample);
498
+ // Since the filing only for a portfolio that has one; any other keeps the trailing window and says why.
499
+ const filed = window.since === "filed" ? portfolio.importedFrom?.filed ?? null : null;
500
+ if (window.since === "filed" && !filed)
501
+ notes.push(sinceFallbackNote(portfolio));
502
+ const metrics = filed
503
+ ? sinceBasketRisk(sample, filed, RISK_BENCHMARK)
504
+ : rollingBasketRisk(sample, undefined, RISK_BENCHMARK);
475
505
  const factors = [
476
506
  { id: "market", label: "Market (SPY)", series: benchmark },
477
507
  {
@@ -546,7 +576,9 @@ export function buildPortfolioRisk(
546
576
  if (factor.samples === 0)
547
577
  warnings.push(`${factor.label}: no matched factor history`);
548
578
  if (sufficient && metrics.every((row) => row.value == null))
549
- warnings.push("Fewer than 60 consecutive matched completed daily returns.");
579
+ warnings.push(filed
580
+ ? `No completed session since the 13F filing on ${filed} yet.`
581
+ : "Fewer than 60 consecutive matched completed daily returns.");
550
582
  const performance = evidence?.performance
551
583
  ? calculateAccountPerformance(evidence.performance)
552
584
  : null;
@@ -565,12 +597,19 @@ export function buildPortfolioRisk(
565
597
  : null;
566
598
  warnings.push(...(greeks?.warnings ?? []));
567
599
  const rows: Record<RiskView, RiskDisplayRow[]> = {
568
- risk: metrics.map((row) => ({
569
- ...row,
570
- percentile: row.rank.percentile,
571
- // The method (price returns at fixed current weights) is in docs; the footer keeps room for coverage.
572
- detail: `${row.samples} sessions`,
573
- })),
600
+ risk: metrics.map((row) => {
601
+ // VaR and expected shortfall are a one-day loss on the covered basket's current value, in the portfolio currency.
602
+ const tail = TAIL_ROW_IDS.has(row.id) && row.value != null && coverage.coveredValue > 0;
603
+ return {
604
+ ...row,
605
+ percentile: row.rank.percentile,
606
+ // The method (price returns at fixed current weights) is in docs; the footer keeps room for coverage.
607
+ detail: filed && row.value == null && TAIL_ROW_IDS.has(row.id) ? `${row.samples} sessions; needs 60` : `${row.samples} sessions`,
608
+ ...(tail
609
+ ? { amount: (row.value! / 100) * coverage.coveredValue, amountCurrency: coverage.currency, amountBase: coverage.coveredValue }
610
+ : {}),
611
+ };
612
+ }),
574
613
  factors: factors.map((row) => ({
575
614
  ...row,
576
615
  percentile: row.rank.percentile,
@@ -762,6 +801,10 @@ export function buildPortfolioRisk(
762
801
  warnings: [...new Set(warnings)],
763
802
  notes,
764
803
  fetchedAt: market.fetchedAt,
804
+ benchmark: RISK_BENCHMARK,
805
+ window: filed
806
+ ? { kind: "since-filed" as const, filed, start: metrics[0]?.startDate ?? null, sessions: metrics[0]?.samples ?? 0 }
807
+ : { kind: "trailing" as const, sessions: 60 },
765
808
  };
766
809
  }
767
810
  export type PortfolioRiskModel = ReturnType<typeof buildPortfolioRisk>;
@@ -770,6 +813,22 @@ export const riskValue = (row: RiskDisplayRow) =>
770
813
  ? "left out"
771
814
  : row.value == null
772
815
  ? "--"
773
- : `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}`;
816
+ : `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}${riskAmount(row)}`;
817
+ /** "220,476 USD basket": the value a tail loss in money is taken on, or null for a row without one. */
818
+ export function riskAmountBase(row: Pick<RiskDisplayRow, "amountBase" | "amountCurrency">): string | null {
819
+ return row.amountBase != null && Number.isFinite(row.amountBase) && row.amountCurrency
820
+ ? `${formatNumber(row.amountBase, 0)} ${row.amountCurrency} basket`
821
+ : null;
822
+ }
823
+ /** A row's evidence with the basket a tail loss in money is taken on. */
824
+ export function riskEvidence(row: RiskDisplayRow): string {
825
+ const base = riskAmountBase(row);
826
+ return base ? `${row.detail}; of ${base}` : row.detail;
827
+ }
828
+ /** " ($5,735)": a tail loss in money beside its percent. */
829
+ function riskAmount(row: RiskDisplayRow): string {
830
+ if (row.amount == null || !Number.isFinite(row.amount) || !row.amountCurrency) return "";
831
+ return ` (${formatCurrency(row.amount, row.amountCurrency, 0)})`;
832
+ }
774
833
  export const riskPercentile = (row: RiskDisplayRow) =>
775
834
  row.percentile == null ? "--" : String(Math.round(row.percentile));