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.
- package/README.md +14 -91
- package/package.json +7 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
- package/src/account/upgrade-personalization.ts +57 -0
- package/src/account/upgrade-tickers.ts +124 -0
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +58 -18
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +16 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +95 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +46 -10
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +74 -2
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +26 -2
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +61 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +19 -4
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +744 -181
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +425 -0
- package/src/cli/commands/overview.ts +251 -40
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +109 -15
- package/src/cli/commands/system.ts +151 -24
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +149 -40
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +150 -17
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +22 -8
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/glossary.ts +429 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +58 -0
- package/src/cli/index.ts +29 -12
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +595 -26
- package/src/cli/not-a-ticker.ts +44 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +11 -4
- package/src/cli/pane-functions/catalog.ts +48 -7
- package/src/cli/pane-functions/data.ts +48 -13
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +41 -19
- package/src/cli/pane-functions/freshness.ts +531 -32
- package/src/cli/pane-functions/function-help.ts +77 -25
- package/src/cli/pane-functions/headless.ts +50 -21
- package/src/cli/pane-functions/index.ts +66 -10
- package/src/cli/pane-functions/market-session.ts +147 -0
- package/src/cli/pane-functions/options.ts +77 -25
- package/src/cli/pane-functions/report-notices.ts +81 -0
- package/src/cli/pane-functions/report.ts +19 -8
- package/src/cli/pane-functions/resolver.ts +53 -18
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +199 -30
- package/src/cli/registry.ts +2 -1
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +53 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +83 -10
- package/src/components/chart/composite/legend.tsx +88 -8
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +9 -2
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +40 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +26 -2
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +43 -9
- package/src/components/layout/shell/drag/live.ts +87 -6
- package/src/components/layout/shell/drag/runtime.ts +62 -20
- package/src/components/layout/shell/index.tsx +71 -12
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +33 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +216 -28
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +69 -23
- package/src/components/metric-treemap/heat-surface.tsx +37 -9
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +50 -41
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +17 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +49 -0
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +20 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +13 -2
- package/src/components/ui/index.ts +1 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +44 -5
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +75 -5
- package/src/i18n/ja.ts +75 -5
- package/src/i18n/ko.ts +75 -5
- package/src/i18n/zh-cn.ts +75 -5
- package/src/i18n/zh-tw.ts +75 -5
- package/src/layout/desks.ts +2 -3
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +193 -30
- package/src/market-data/market/status.ts +59 -23
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +22 -2
- package/src/market-data/quotes/metadata.ts +8 -9
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +61 -9
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +2 -56
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +37 -8
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +71 -12
- package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +50 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
- package/src/plugins/builtin/cloud/askg/model.ts +156 -78
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
- package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +116 -67
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +23 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +70 -22
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +64 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +114 -20
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +18 -8
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +42 -134
- package/src/plugins/builtin/holders/pane.tsx +14 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +27 -10
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +26 -6
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +27 -12
- package/src/plugins/builtin/iv-history/index.tsx +5 -3
- package/src/plugins/builtin/iv-history/model.ts +172 -20
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +68 -3
- package/src/plugins/builtin/macro-day/headless.ts +18 -12
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +66 -15
- package/src/plugins/builtin/macro-day/pane.tsx +34 -20
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +102 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +11 -3
- package/src/plugins/builtin/market-movers/model.ts +101 -17
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +162 -13
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +5 -2
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +75 -18
- package/src/plugins/builtin/options-scenario/headless.ts +72 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -8
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +32 -6
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +90 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
- package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +8 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +69 -0
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +59 -2
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +21 -4
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +3 -10
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
- package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +125 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +129 -64
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +173 -28
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +25 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +126 -59
- package/src/remote/matching.ts +69 -0
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +63 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +32 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +21 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +4 -1
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +14 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +74 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +6 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +26 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +14 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +9 -5
- package/src/sources/provider-router/financial-routes.ts +12 -5
- package/src/sources/provider-router/financials.ts +55 -15
- package/src/sources/provider-router/history.ts +68 -34
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +5 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +67 -9
- package/src/tickers/search/ranking.ts +78 -18
- package/src/tickers/search/types.ts +10 -2
- package/src/tickers/starter-symbols.ts +8 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +96 -30
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +67 -1
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +72 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +68 -3
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +26 -4
- package/src/ui/index.tsx +2 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +21 -2
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +120 -1
- package/src/utils/format.ts +17 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +44 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +130 -40
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +178 -36
- package/src/utils/sec.ts +98 -40
- package/src/utils/throttled-fetch.ts +51 -22
- package/src/utils/utc-time.ts +51 -4
|
@@ -3,7 +3,12 @@ import type { MarketHeatmapAsset, MarketHeatmapUniverseId } from "../../../api-c
|
|
|
3
3
|
import { useAppSelector, usePaneStateValue } from "../../../state/app/context";
|
|
4
4
|
import type { ColumnConfig } from "../../../types/config";
|
|
5
5
|
import type { TickerFinancials } from "../../../types/financials";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getRegularSessionMoveDisplay,
|
|
8
|
+
getTradedSessionMoveDisplay,
|
|
9
|
+
type ActiveQuoteDisplay,
|
|
10
|
+
type ExtendedSession,
|
|
11
|
+
} from "../../../market-data/market/status";
|
|
7
12
|
import type { TickerRecord } from "../../../types/ticker";
|
|
8
13
|
import { getSortValue, type ColumnContext } from "../portfolio-list/metrics";
|
|
9
14
|
|
|
@@ -195,6 +200,7 @@ export function buildPortfolioHeatmapAssets({
|
|
|
195
200
|
currency,
|
|
196
201
|
exchangeRates,
|
|
197
202
|
sizeBy = "sqrt-market-cap",
|
|
203
|
+
regularSession = false,
|
|
198
204
|
}: {
|
|
199
205
|
tickers: readonly TickerRecord[];
|
|
200
206
|
financials: ReadonlyMap<string, TickerFinancials>;
|
|
@@ -204,6 +210,8 @@ export function buildPortfolioHeatmapAssets({
|
|
|
204
210
|
currency: string;
|
|
205
211
|
exchangeRates: Map<string, number>;
|
|
206
212
|
sizeBy?: HeatmapSizeBy;
|
|
213
|
+
/** Color by the regular session alone, never an extended print (`getRegularSessionMoveDisplay`). */
|
|
214
|
+
regularSession?: boolean;
|
|
207
215
|
}): { assets: HeatmapBoardAsset[]; omitted: number } {
|
|
208
216
|
const context: ColumnContext = {
|
|
209
217
|
activeTab: kind === "portfolio" ? collectionId : undefined,
|
|
@@ -217,7 +225,9 @@ export function buildPortfolioHeatmapAssets({
|
|
|
217
225
|
const snapshot = financials.get(symbol);
|
|
218
226
|
const quote = snapshot?.quote;
|
|
219
227
|
// Colored like the market boards: an open extended session's move, else the regular session's.
|
|
220
|
-
const display =
|
|
228
|
+
const display: (ActiveQuoteDisplay & { session?: ExtendedSession }) | null = regularSession
|
|
229
|
+
? getRegularSessionMoveDisplay(quote)
|
|
230
|
+
: getTradedSessionMoveDisplay(quote);
|
|
221
231
|
const price = display != null && Number.isFinite(display.price) ? display.price : null;
|
|
222
232
|
const size = positiveNumber(getSortValue(sizeColumn, ticker, snapshot, context));
|
|
223
233
|
const hasChange = display?.changePercent != null && Number.isFinite(display.changePercent);
|
|
@@ -5,18 +5,19 @@ import type {
|
|
|
5
5
|
CloudSessionMoversSide,
|
|
6
6
|
} from "../../../api-client/market-movers";
|
|
7
7
|
import type { DataProvider } from "../../../types/data-provider";
|
|
8
|
-
import { CATEGORY_MAP, screenerQuoteFromQuote, type ScreenerTabId } from "./model";
|
|
8
|
+
import { CATEGORY_MAP, moverRegularSession, screenerQuoteFromQuote, type MoverQuote, type ScreenerTabId } from "./model";
|
|
9
9
|
import {
|
|
10
10
|
fetchPreferredMarketMovers,
|
|
11
11
|
fetchTrending,
|
|
12
12
|
type MarketMoversResult,
|
|
13
13
|
type PreferredMoversOptions,
|
|
14
|
-
type ScreenerQuote,
|
|
15
14
|
type TrendingSymbol,
|
|
16
15
|
} from "./screener";
|
|
17
16
|
|
|
18
17
|
export interface MarketMoverTabResult extends MarketMoversResult {
|
|
19
18
|
tab: ScreenerTabId;
|
|
19
|
+
/** In the list's order; Last and Chg% the regular session, as `ticker` reads them. */
|
|
20
|
+
quotes: MoverQuote[];
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface MarketMoverTabDependencies {
|
|
@@ -36,9 +37,9 @@ const defaultDependencies: MarketMoverTabDependencies = {
|
|
|
36
37
|
async function hydrateTrending(
|
|
37
38
|
trending: readonly TrendingSymbol[],
|
|
38
39
|
provider: DataProvider | null,
|
|
39
|
-
): Promise<
|
|
40
|
+
): Promise<MoverQuote[]> {
|
|
40
41
|
const symbols = trending.slice(0, 25).map(({ symbol }) => symbol);
|
|
41
|
-
const bySymbol = new Map<string,
|
|
42
|
+
const bySymbol = new Map<string, MoverQuote>();
|
|
42
43
|
if (!provider) return [];
|
|
43
44
|
if (provider.getQuotesBatch) {
|
|
44
45
|
const results = await provider.getQuotesBatch(
|
|
@@ -79,7 +80,8 @@ export async function loadMarketMoverTab(
|
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
const result = await dependencies.fetchPreferred(CATEGORY_MAP[tab], 25, options);
|
|
82
|
-
|
|
83
|
+
// Ranked by the live print first, so reading each row's regular session keeps its place.
|
|
84
|
+
return { ...result, quotes: result.quotes.map(moverRegularSession), tab };
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
/** The server refused the list for the account's plan. */
|
|
@@ -10,14 +10,18 @@ import type {
|
|
|
10
10
|
CloudSessionMoversSide,
|
|
11
11
|
} from "../../../api-client/market-movers";
|
|
12
12
|
import { loadMarketMoverTab, loadSessionMovers, type MarketMoverTabResult } from "./client";
|
|
13
|
-
import { createRows, fiftyTwoWeekPositionPercent, formatMoverPrice, moverReferencePrice, type MarketMoverRow, type ScreenerTabId, type TabId } from "./model";
|
|
13
|
+
import { createRows, fiftyTwoWeekPositionPercent, formatMoverPrice, moverExtendedSessions, moverReferencePrice, type MarketMoverRow, type ScreenerTabId, type TabId } from "./model";
|
|
14
|
+
import { EXTENDED_SESSION_LABELS, type ExtendedSession } from "../../../market-data/market/status";
|
|
15
|
+
import type { HeadlessPaneColumn } from "../../../types/headless";
|
|
14
16
|
import { isSessionTab, resolveSide } from "./session";
|
|
15
17
|
|
|
16
|
-
const
|
|
18
|
+
const rowPrice = (value: unknown, row: Record<string, unknown>) => formatMoverPrice(typeof value === "number" ? value : null, typeof row.currency === "string" ? row.currency : "", moverReferencePrice(row as unknown as MarketMoverRow));
|
|
19
|
+
|
|
20
|
+
const COLUMNS: HeadlessPaneColumn[] = [
|
|
17
21
|
{ key: "rank", header: "Rank", align: "right" as const },
|
|
18
22
|
{ key: "symbol", header: "Symbol" },
|
|
19
23
|
{ key: "name", header: "Name" },
|
|
20
|
-
{ key: "price", header: "Last", align: "right" as const, format:
|
|
24
|
+
{ key: "price", header: "Last", align: "right" as const, format: rowPrice },
|
|
21
25
|
{ key: "changePercent", header: "Change %", align: "right" as const, format: (value: unknown) => value == null ? "—" : formatPercentRaw(Number(value)) },
|
|
22
26
|
{ key: "volume", header: "Volume", align: "right" as const, format: (value: unknown) => value == null ? "—" : formatCompact(Number(value), { fixedDecimals: true }) },
|
|
23
27
|
{ key: "volumeRatio", header: "Vol / Avg", align: "right" as const, format: (value: unknown) => value == null ? "—" : formatNumber(Number(value), 1) },
|
|
@@ -30,6 +34,19 @@ const percent = (value: unknown) => value == null ? "—" : formatPercentRaw(Num
|
|
|
30
34
|
const ratio = (value: unknown) => value == null ? "—" : `${formatNumber(Number(value), 1)}x`;
|
|
31
35
|
const compact = (value: unknown) => value == null ? "—" : formatCompact(Number(value), { fixedDecimals: true });
|
|
32
36
|
const CATALYST_LABEL: Record<string, string> = { halt: "Halt", filing: "8-K", news: "News" };
|
|
37
|
+
|
|
38
|
+
/** The pre-market or after-hours print and its move from the regular close, for the rows that have one. */
|
|
39
|
+
function extendedColumn(session: ExtendedSession): HeadlessPaneColumn {
|
|
40
|
+
return {
|
|
41
|
+
key: "extendedPrice",
|
|
42
|
+
header: EXTENDED_SESSION_LABELS[session],
|
|
43
|
+
align: "right",
|
|
44
|
+
format: (value, row) => row.extendedSession === session && typeof value === "number"
|
|
45
|
+
? `${rowPrice(value, row)} ${percent(row.extendedChangePercent)}`
|
|
46
|
+
: "—",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
const SESSION_VOLUME: Record<CloudSessionMoversCategory, string> = {
|
|
34
51
|
premarket: "Pre-market volume",
|
|
35
52
|
afterhours: "After-hours volume",
|
|
@@ -131,8 +148,15 @@ export function createMarketMoversHeadless(
|
|
|
131
148
|
};
|
|
132
149
|
}
|
|
133
150
|
const result = await dependencies.load(args, tab, ctx.marketData);
|
|
134
|
-
const
|
|
151
|
+
const ranked = createRows(result.quotes);
|
|
152
|
+
// Last and Change % are the regular session; an extended print is a column of its own.
|
|
153
|
+
const extendedSessions = moverExtendedSessions(ranked);
|
|
154
|
+
const rows = ranked.map(({ extended, ...row }) => ({
|
|
135
155
|
...row,
|
|
156
|
+
extendedSession: extended?.session ?? null,
|
|
157
|
+
extendedPrice: extended?.price ?? null,
|
|
158
|
+
extendedChange: extended?.change ?? null,
|
|
159
|
+
extendedChangePercent: extended?.changePercent ?? null,
|
|
136
160
|
rangePositionPercent: fiftyTwoWeekPositionPercent(
|
|
137
161
|
row.price,
|
|
138
162
|
row.fiftyTwoWeekLow,
|
|
@@ -140,6 +164,9 @@ export function createMarketMoversHeadless(
|
|
|
140
164
|
),
|
|
141
165
|
}));
|
|
142
166
|
return {
|
|
167
|
+
...(extendedSessions.length > 0
|
|
168
|
+
? { columns: [...COLUMNS.slice(0, 5), ...extendedSessions.map(extendedColumn), ...COLUMNS.slice(5)] }
|
|
169
|
+
: {}),
|
|
143
170
|
rows,
|
|
144
171
|
metadata: { list: tab, source: result.source, stale: result.stale },
|
|
145
172
|
};
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
INDEX_SHORT,
|
|
26
26
|
TABS,
|
|
27
27
|
createRows,
|
|
28
|
+
moverExtendedSessions,
|
|
28
29
|
overlayMarketMoverQuotes,
|
|
29
30
|
resolveSummarySymbols,
|
|
30
31
|
resolveTabs,
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
type MarketMoverColumn,
|
|
34
35
|
type MarketMoverRow,
|
|
35
36
|
type MarketMoverSortPreference,
|
|
37
|
+
type MoverQuote,
|
|
36
38
|
type ScreenerTabId,
|
|
37
39
|
type TabId,
|
|
38
40
|
} from "./model";
|
|
@@ -42,6 +44,7 @@ import { isSessionTab, resolveActiveTab, usSessionAt, type UsSession } from "./s
|
|
|
42
44
|
import { SessionMoversBody } from "./session-body";
|
|
43
45
|
import { marketMoversHeadless } from "./headless";
|
|
44
46
|
import { buildMarketMoverColumns, renderMarketMoverCell } from "./table";
|
|
47
|
+
import type { ExtendedSession } from "../../../market-data/market/status";
|
|
45
48
|
import {
|
|
46
49
|
LIVE_STREAMING_QUICK_SETTING,
|
|
47
50
|
useLiveStreamingSetting,
|
|
@@ -56,7 +59,7 @@ import {
|
|
|
56
59
|
/** Stable identity: a fresh literal here would reload the board every render. */
|
|
57
60
|
const NO_SAVED_SELECTION: string[] = [];
|
|
58
61
|
const SESSION_CHECK_MS = 30_000;
|
|
59
|
-
const NO_QUOTES:
|
|
62
|
+
const NO_QUOTES: MoverQuote[] = [];
|
|
60
63
|
const moverKey = (row: Pick<ScreenerQuote, "symbol" | "exchange">) => publicTickerKey(row.symbol, row.exchange);
|
|
61
64
|
|
|
62
65
|
/** What is trading in New York, re-read every half minute so the pane follows 04:00, 09:30 and 16:00. */
|
|
@@ -152,7 +155,7 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
|
|
|
152
155
|
}) {
|
|
153
156
|
const dataProvider = useAssetData();
|
|
154
157
|
const { pinTicker } = usePluginTickerActions();
|
|
155
|
-
const [quotes, setQuotes] = useState<
|
|
158
|
+
const [quotes, setQuotes] = useState<MoverQuote[]>([]);
|
|
156
159
|
const [loadedTab, setLoadedTab] = useState<TabId | null>(null);
|
|
157
160
|
const visibleQuotes = loadedTab === activeTab ? quotes : NO_QUOTES;
|
|
158
161
|
// The first load starts before the effect runs; an empty board is not "no data".
|
|
@@ -188,8 +191,13 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
|
|
|
188
191
|
}),
|
|
189
192
|
[freshnessNow, liveQuoteEntries, quoteTargets, subscriptionStartedAt],
|
|
190
193
|
);
|
|
191
|
-
const columns = useMemo(() => buildMarketMoverColumns(width), [width]);
|
|
192
194
|
const rankedRows = useMemo(() => createRows(resolvedQuotes), [resolvedQuotes]);
|
|
195
|
+
// A pre-market or after-hours column only while a row has such a print.
|
|
196
|
+
const extendedSessionsKey = moverExtendedSessions(rankedRows).join(",");
|
|
197
|
+
const columns = useMemo(
|
|
198
|
+
() => buildMarketMoverColumns(width, extendedSessionsKey ? extendedSessionsKey.split(",") as ExtendedSession[] : []),
|
|
199
|
+
[extendedSessionsKey, width],
|
|
200
|
+
);
|
|
193
201
|
const rows = useMemo(() => sortRows(rankedRows, sortPreference), [rankedRows, sortPreference]);
|
|
194
202
|
const selectedIdx = selectedSymbol
|
|
195
203
|
? rows.findIndex((row) => moverKey(row) === selectedSymbol)
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { resolveCurrencyUnit } from "../../../utils/currency-units";
|
|
2
2
|
import { overlayScreenerQuoteEntries } from "../../../market-data/quotes/screener-live-quotes";
|
|
3
|
+
import {
|
|
4
|
+
getExtendedSessionDisplay,
|
|
5
|
+
getRegularSessionDisplay,
|
|
6
|
+
type ExtendedSession,
|
|
7
|
+
type ExtendedSessionDisplay,
|
|
8
|
+
} from "../../../market-data/market/status";
|
|
9
|
+
import { buildQuoteKey, resolveEntryData } from "../../../market-data/selectors";
|
|
10
|
+
import { isFiniteNumber } from "../../../utils/guards";
|
|
3
11
|
import type { Quote } from "../../../types/financials";
|
|
4
12
|
import type { CloudSessionMoversCategory } from "../../../api-client/market-movers";
|
|
5
13
|
import type { QueryEntry } from "../../../market-data/result-types";
|
|
@@ -37,12 +45,20 @@ type MarketMoverColumnId =
|
|
|
37
45
|
| "name"
|
|
38
46
|
| "price"
|
|
39
47
|
| "changePercent"
|
|
48
|
+
| "preMarket"
|
|
49
|
+
| "afterHours"
|
|
40
50
|
| "volume"
|
|
41
51
|
| "volumeRatio"
|
|
42
52
|
| "range"
|
|
43
53
|
| "marketCap";
|
|
44
54
|
export type MarketMoverColumn = DataTableColumn & { id: MarketMoverColumnId };
|
|
45
|
-
|
|
55
|
+
/**
|
|
56
|
+
* A list row. Price and change are the regular session's, as `ticker` reads
|
|
57
|
+
* them; a row whose quote has a pre-market or after-hours print carries it in
|
|
58
|
+
* `extended`, measured from that session's close.
|
|
59
|
+
*/
|
|
60
|
+
export type MoverQuote = ScreenerQuote & { extended?: ExtendedSessionDisplay | null };
|
|
61
|
+
export type MarketMoverRow = MoverQuote & { rank: number };
|
|
46
62
|
|
|
47
63
|
export interface MarketMoverSortPreference {
|
|
48
64
|
columnId: MarketMoverColumnId | null;
|
|
@@ -96,6 +112,9 @@ function getSortValue(
|
|
|
96
112
|
return row.price;
|
|
97
113
|
case "changePercent":
|
|
98
114
|
return row.changePercent;
|
|
115
|
+
case "preMarket":
|
|
116
|
+
case "afterHours":
|
|
117
|
+
return moverExtendedMove(row, columnId === "preMarket" ? "PRE" : "POST");
|
|
99
118
|
case "volume":
|
|
100
119
|
return row.volume;
|
|
101
120
|
case "volumeRatio":
|
|
@@ -123,7 +142,17 @@ export function sortRows(
|
|
|
123
142
|
/** A row is rebuilt only when its quote or rank moved, so unchanged rows skip the render. */
|
|
124
143
|
const moverRows = new WeakMap<ScreenerQuote, MarketMoverRow>();
|
|
125
144
|
|
|
126
|
-
|
|
145
|
+
/** The extended print's move from the close, when the row has one for `session`. */
|
|
146
|
+
export function moverExtendedMove(row: MoverQuote, session: ExtendedSession): number | null {
|
|
147
|
+
return row.extended?.session === session && isFiniteNumber(row.extended.changePercent) ? row.extended.changePercent : null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** The extended sessions some row has a print for, in the order their columns go. */
|
|
151
|
+
export function moverExtendedSessions(rows: readonly MoverQuote[]): ExtendedSession[] {
|
|
152
|
+
return (["PRE", "POST"] as const).filter((session) => rows.some((row) => row.extended?.session === session));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function createRows(quotes: readonly MoverQuote[]): MarketMoverRow[] {
|
|
127
156
|
return quotes.map((quote, index) => {
|
|
128
157
|
const cached = moverRows.get(quote);
|
|
129
158
|
if (cached?.rank === index + 1) return cached;
|
|
@@ -137,26 +166,66 @@ export function createRows(quotes: ScreenerQuote[]): MarketMoverRow[] {
|
|
|
137
166
|
});
|
|
138
167
|
}
|
|
139
168
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
): MarketSummaryQuote {
|
|
169
|
+
/** An index in the summary strip, at its regular session's level and move. */
|
|
170
|
+
export function summaryQuoteFromQuote(symbol: string, quote: Quote): MarketSummaryQuote {
|
|
171
|
+
const headline = getRegularSessionDisplay(quote)!;
|
|
144
172
|
return {
|
|
145
173
|
symbol,
|
|
146
174
|
name: quote.name ?? symbol,
|
|
147
|
-
price:
|
|
148
|
-
change:
|
|
149
|
-
changePercent:
|
|
175
|
+
price: headline.price,
|
|
176
|
+
change: headline.change ?? Number.NaN,
|
|
177
|
+
changePercent: headline.changePercent ?? Number.NaN,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** The extended print beside a quote's regular session, or null; a non-finite price is none. */
|
|
182
|
+
function moverExtended(quote: Quote): ExtendedSessionDisplay | null {
|
|
183
|
+
const extended = getExtendedSessionDisplay(quote);
|
|
184
|
+
return extended && isFiniteNumber(extended.price) ? extended : null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* A listed row as `ticker` reads its quote: Last and Chg% are the regular
|
|
189
|
+
* session's close and move, and a pre-market or after-hours print is its
|
|
190
|
+
* `extended`, measured from that close. The list ranked it by its live print
|
|
191
|
+
* first, so its place stays. A row without its quote's sessions (an older
|
|
192
|
+
* server) reads as it came.
|
|
193
|
+
*/
|
|
194
|
+
export function moverRegularSession({ sessions, ...row }: ScreenerQuote): MoverQuote {
|
|
195
|
+
if (!sessions || row.price == null) return row;
|
|
196
|
+
const quote: Quote = {
|
|
197
|
+
symbol: row.symbol,
|
|
198
|
+
price: row.price,
|
|
199
|
+
change: row.change ?? Number.NaN,
|
|
200
|
+
changePercent: row.changePercent ?? Number.NaN,
|
|
201
|
+
previousClose: row.previousClose,
|
|
202
|
+
currency: row.currency,
|
|
203
|
+
lastUpdated: row.lastUpdated ?? Number.NaN,
|
|
204
|
+
listingExchangeName: row.exchange || undefined,
|
|
205
|
+
...sessions,
|
|
206
|
+
};
|
|
207
|
+
const headline = getRegularSessionDisplay(quote)!;
|
|
208
|
+
return {
|
|
209
|
+
...row,
|
|
210
|
+
price: screenerNumber(headline.price),
|
|
211
|
+
change: screenerNumber(headline.change),
|
|
212
|
+
changePercent: screenerNumber(headline.changePercent),
|
|
213
|
+
extended: moverExtended(quote),
|
|
150
214
|
};
|
|
151
215
|
}
|
|
152
216
|
|
|
153
|
-
|
|
217
|
+
/**
|
|
218
|
+
* A trending row from its quote: Last and Chg% are the regular session, as
|
|
219
|
+
* `ticker` reads it, and a pre-market or after-hours print rides beside them.
|
|
220
|
+
*/
|
|
221
|
+
export function screenerQuoteFromQuote(symbol: string, quote: Quote): MoverQuote {
|
|
222
|
+
const headline = getRegularSessionDisplay(quote)!;
|
|
154
223
|
return {
|
|
155
224
|
symbol,
|
|
156
225
|
name: quote.name ?? symbol,
|
|
157
|
-
price: screenerNumber(
|
|
158
|
-
change: screenerNumber(
|
|
159
|
-
changePercent: screenerNumber(
|
|
226
|
+
price: screenerNumber(headline.price),
|
|
227
|
+
change: screenerNumber(headline.change),
|
|
228
|
+
changePercent: screenerNumber(headline.changePercent),
|
|
160
229
|
volume: screenerVolume(quote.volume),
|
|
161
230
|
avgVolume: null,
|
|
162
231
|
volumeRatio: null,
|
|
@@ -169,6 +238,7 @@ export function screenerQuoteFromQuote(symbol: string, quote: { name?: string; p
|
|
|
169
238
|
exchange: quote.listingExchangeName ?? quote.exchangeName ?? "",
|
|
170
239
|
lastUpdated: quote.lastUpdated,
|
|
171
240
|
previousClose: screenerNumber(quote.previousClose) ?? undefined,
|
|
241
|
+
extended: moverExtended(quote),
|
|
172
242
|
};
|
|
173
243
|
}
|
|
174
244
|
|
|
@@ -198,21 +268,35 @@ export function formatMoverPrice(price: number | null, currency: string, referen
|
|
|
198
268
|
}
|
|
199
269
|
|
|
200
270
|
/** Keyed by the overlaid row, which the shared overlay keeps while its quote holds. */
|
|
201
|
-
const convertedOverlays = new WeakMap<ScreenerQuote,
|
|
271
|
+
const convertedOverlays = new WeakMap<ScreenerQuote, MoverQuote>();
|
|
202
272
|
|
|
203
|
-
/**
|
|
273
|
+
/**
|
|
274
|
+
* Live quotes on the list's rows, which keep the list's order. Price and
|
|
275
|
+
* change are the regular session's, as `ticker` reads them, so after the
|
|
276
|
+
* close they hold at it and a pre-market or after-hours print is the row's
|
|
277
|
+
* `extended`. Range endpoints and the previous close belong to the original
|
|
278
|
+
* screener price denomination.
|
|
279
|
+
*/
|
|
204
280
|
export function overlayMarketMoverQuotes(
|
|
205
|
-
rows: readonly
|
|
281
|
+
rows: readonly MoverQuote[],
|
|
206
282
|
entries: ReadonlyMap<string, QueryEntry<Quote>>,
|
|
207
|
-
):
|
|
283
|
+
): MoverQuote[] {
|
|
208
284
|
return overlayScreenerQuoteEntries(rows, entries).map((row, index) => {
|
|
209
285
|
const original = rows[index]!;
|
|
210
286
|
if (row === original) return row;
|
|
211
287
|
const cached = convertedOverlays.get(row);
|
|
212
288
|
if (cached) return cached;
|
|
213
289
|
const convert = (value: number | undefined) => convertScreenerPriceUnit(value, original.currency, row.currency);
|
|
290
|
+
const quote = resolveEntryData(entries.get(buildQuoteKey({ symbol: row.symbol, exchange: row.exchange })));
|
|
291
|
+
const headline = quote ? getRegularSessionDisplay(quote) : null;
|
|
214
292
|
const converted = {
|
|
215
293
|
...row,
|
|
294
|
+
...(quote && headline ? {
|
|
295
|
+
price: headline.price,
|
|
296
|
+
change: isFiniteNumber(headline.change) ? headline.change : null,
|
|
297
|
+
changePercent: isFiniteNumber(headline.changePercent) ? headline.changePercent : null,
|
|
298
|
+
extended: moverExtended(quote),
|
|
299
|
+
} : {}),
|
|
216
300
|
fiftyTwoWeekLow: convert(original.fiftyTwoWeekLow),
|
|
217
301
|
fiftyTwoWeekHigh: convert(original.fiftyTwoWeekHigh),
|
|
218
302
|
dayLow: convert(original.dayLow),
|
|
@@ -8,7 +8,9 @@ import type {
|
|
|
8
8
|
CloudMarketScreenerCategory,
|
|
9
9
|
CloudMarketScreenerItem,
|
|
10
10
|
CloudMarketScreenerPayload,
|
|
11
|
+
CloudMoverSessionFields,
|
|
11
12
|
} from "../../../api-client/types";
|
|
13
|
+
import type { MarketState } from "../../../types/financials";
|
|
12
14
|
import { hasProAccess } from "../../../api-client/plan-access";
|
|
13
15
|
|
|
14
16
|
const CACHE_KIND = "market-screener";
|
|
@@ -184,6 +186,32 @@ export function convertScreenerPriceUnit(value: number | undefined, from: string
|
|
|
184
186
|
? value / source.divisor * target.divisor : undefined;
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
const MARKET_STATES = new Set<string>(["PRE", "REGULAR", "POST", "PREPRE", "POSTPOST", "CLOSED"] satisfies MarketState[]);
|
|
190
|
+
const SESSION_NUMBERS = [
|
|
191
|
+
"regularClose", "regularChange", "regularChangePercent",
|
|
192
|
+
"preMarketPrice", "preMarketChange", "preMarketChangePercent",
|
|
193
|
+
"postMarketPrice", "postMarketChange", "postMarketChangePercent",
|
|
194
|
+
] as const;
|
|
195
|
+
const isSessionDate = (value: unknown): value is string => typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A row's quote sessions as the server sends them beside its live print, or
|
|
199
|
+
* undefined when it sends none (an older server), so the row reads as it came.
|
|
200
|
+
*/
|
|
201
|
+
function parseScreenerSessions(row: Record<string, unknown>): CloudMoverSessionFields | undefined {
|
|
202
|
+
if (typeof row.marketState !== "string" || !MARKET_STATES.has(row.marketState)) return undefined;
|
|
203
|
+
const sessions: CloudMoverSessionFields = { marketState: row.marketState as MarketState };
|
|
204
|
+
if (isSessionDate(row.changeSessionDate)) sessions.changeSessionDate = row.changeSessionDate;
|
|
205
|
+
for (const key of SESSION_NUMBERS) {
|
|
206
|
+
const value = screenerNumber(row[key]);
|
|
207
|
+
if (value != null) sessions[key] = value;
|
|
208
|
+
}
|
|
209
|
+
if (sessions.regularClose != null && isSessionDate(row.regularCloseSessionDate)) {
|
|
210
|
+
sessions.regularCloseSessionDate = row.regularCloseSessionDate;
|
|
211
|
+
}
|
|
212
|
+
return sessions;
|
|
213
|
+
}
|
|
214
|
+
|
|
187
215
|
/** Validate numeric fields at the API boundary so absent values stay unavailable. */
|
|
188
216
|
export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
|
|
189
217
|
if (!data || typeof data !== "object" || !("quotes" in data) || !Array.isArray(data.quotes)) {
|
|
@@ -202,6 +230,7 @@ export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
|
|
|
202
230
|
dayHigh: screenerNumber(q.dayHigh) ?? undefined, dayLow: screenerNumber(q.dayLow) ?? undefined,
|
|
203
231
|
previousClose: screenerNumber(q.previousClose) ?? undefined, exchange: typeof q.exchange === "string" ? q.exchange : "",
|
|
204
232
|
lastUpdated: typeof q.lastUpdated === "number" && Number.isFinite(q.lastUpdated) && q.lastUpdated > 0 ? q.lastUpdated : undefined,
|
|
233
|
+
sessions: parseScreenerSessions(q),
|
|
205
234
|
}];
|
|
206
235
|
});
|
|
207
236
|
}
|
|
@@ -274,6 +303,8 @@ function mergeCloudScreenerItem(
|
|
|
274
303
|
dayLow: screenerNumber(item.dayLow) ?? metadataPrice(metadata?.dayLow),
|
|
275
304
|
exchange: item.exchange || metadata?.exchange || "",
|
|
276
305
|
lastUpdated: item.lastUpdated,
|
|
306
|
+
previousClose: screenerNumber(item.previousClose) ?? undefined,
|
|
307
|
+
sessions: parseScreenerSessions(item as unknown as Record<string, unknown>),
|
|
277
308
|
};
|
|
278
309
|
}
|
|
279
310
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { DataTableCell } from "../../../components";
|
|
2
|
+
import { getTableWidth } from "../../../components/ui/table-layout";
|
|
2
3
|
import { TextAttributes } from "../../../ui";
|
|
3
4
|
import { colors, priceColor } from "../../../theme/colors";
|
|
4
5
|
import { formatCompact, formatPercentRaw } from "../../../utils/format";
|
|
6
|
+
import { marketStateLabel, type ExtendedSession } from "../../../market-data/market/status";
|
|
5
7
|
import type { MarketMoverColumn, MarketMoverRow } from "./model";
|
|
6
|
-
import { fiftyTwoWeekPositionPercent, formatMoverPrice, moverReferencePrice } from "./model";
|
|
8
|
+
import { fiftyTwoWeekPositionPercent, formatMoverPrice, moverExtendedMove, moverReferencePrice } from "./model";
|
|
7
9
|
|
|
8
10
|
export function formatVolRatio(ratio: number | null): string {
|
|
9
11
|
if (ratio == null || !Number.isFinite(ratio) || ratio < 0) return "—";
|
|
@@ -22,30 +24,45 @@ function fiftyTwoWeekPosition(price: number | null, low: number | undefined, hig
|
|
|
22
24
|
return pct == null ? "—" : `${Math.round(pct)}%`;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const priceWidth = 11;
|
|
29
|
-
const chgWidth = 9;
|
|
30
|
-
const volWidth = 8;
|
|
31
|
-
const volRatioWidth = 6;
|
|
32
|
-
const rangeWidth = 6;
|
|
33
|
-
const mcapWidth = 8;
|
|
34
|
-
const columnCount = 9;
|
|
35
|
-
const fixedWidth = rankWidth + tickerWidth + priceWidth + chgWidth + volWidth + volRatioWidth + rangeWidth + mcapWidth;
|
|
36
|
-
const nameWidth = Math.max(6, width - 2 - columnCount - fixedWidth);
|
|
27
|
+
const EXTENDED_COLUMN_WIDTH = 9;
|
|
28
|
+
/** With an extended column, a narrow pane drops MCAP, then 52W%, before the name gets narrower than this. */
|
|
29
|
+
const EXTENDED_MIN_NAME_WIDTH = 12;
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{ id: "
|
|
46
|
-
{ id: "
|
|
47
|
-
{ id: "marketCap", label: "MCAP", width: mcapWidth, align: "right" },
|
|
31
|
+
/**
|
|
32
|
+
* The list's columns at `width`. A pre-market or after-hours column follows
|
|
33
|
+
* CHG% for each session in `extendedSessions`; to make room for it a narrow
|
|
34
|
+
* pane gives up MCAP, then 52W%, before it cuts the names short.
|
|
35
|
+
*/
|
|
36
|
+
export function buildMarketMoverColumns(width: number, extendedSessions: readonly ExtendedSession[] = []): MarketMoverColumn[] {
|
|
37
|
+
const lead: MarketMoverColumn[] = [
|
|
38
|
+
{ id: "rank", label: "#", width: 3, align: "left" },
|
|
39
|
+
{ id: "symbol", label: "TICKER", width: 8, align: "left" },
|
|
48
40
|
];
|
|
41
|
+
const quote: MarketMoverColumn[] = [
|
|
42
|
+
{ id: "price", label: "LAST", width: 11, align: "right" },
|
|
43
|
+
{ id: "changePercent", label: "CHG%", width: 9, align: "right" },
|
|
44
|
+
...extendedSessions.map((session): MarketMoverColumn => ({
|
|
45
|
+
id: session === "PRE" ? "preMarket" : "afterHours",
|
|
46
|
+
// Named for the session it trades in, as the header labels it.
|
|
47
|
+
label: marketStateLabel(session),
|
|
48
|
+
width: EXTENDED_COLUMN_WIDTH,
|
|
49
|
+
align: "right",
|
|
50
|
+
})),
|
|
51
|
+
];
|
|
52
|
+
const trailing: MarketMoverColumn[] = [
|
|
53
|
+
{ id: "volume", label: "VOL", width: 8, align: "right" },
|
|
54
|
+
{ id: "volumeRatio", label: "V/AVG", width: 6, align: "right" },
|
|
55
|
+
{ id: "range", label: "52W%", width: 6, align: "right" },
|
|
56
|
+
{ id: "marketCap", label: "MCAP", width: 8, align: "right" },
|
|
57
|
+
];
|
|
58
|
+
// Measured the way the table draws them (a header and its sort mark widen a
|
|
59
|
+
// column, gaps between them); the name adds its own width and a gap.
|
|
60
|
+
const nameRoom = () => width - getTableWidth([...lead, ...quote, ...trailing]) - 1;
|
|
61
|
+
for (const id of ["marketCap", "range"] as const) {
|
|
62
|
+
if (extendedSessions.length === 0 || nameRoom() >= EXTENDED_MIN_NAME_WIDTH) break;
|
|
63
|
+
trailing.splice(trailing.findIndex((column) => column.id === id), 1);
|
|
64
|
+
}
|
|
65
|
+
return [...lead, { id: "name", label: "NAME", width: Math.max(6, nameRoom()), align: "left" }, ...quote, ...trailing];
|
|
49
66
|
}
|
|
50
67
|
|
|
51
68
|
export function renderMarketMoverCell(
|
|
@@ -71,6 +88,16 @@ export function renderMarketMoverCell(
|
|
|
71
88
|
value: row.changePercent,
|
|
72
89
|
color: priceColor(row.changePercent ?? 0),
|
|
73
90
|
};
|
|
91
|
+
case "preMarket":
|
|
92
|
+
case "afterHours": {
|
|
93
|
+
// The extended print's move from the close in LAST.
|
|
94
|
+
const move = moverExtendedMove(row, column.id === "preMarket" ? "PRE" : "POST");
|
|
95
|
+
return {
|
|
96
|
+
text: formatPercentRaw(move ?? undefined),
|
|
97
|
+
value: move,
|
|
98
|
+
color: move == null ? colors.textDim : priceColor(move),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
74
101
|
case "volume":
|
|
75
102
|
return { text: formatCompact(row.volume ?? undefined, { fixedDecimals: true }), value: row.volume, color: colors.textDim };
|
|
76
103
|
case "volumeRatio":
|