gloomberb 0.17.6 → 0.18.0
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 +2 -0
- package/README.zh-CN.md +2 -0
- package/package.json +6 -1
- package/patches/electrobun@1.18.1.patch +74 -0
- package/src/account/auth-model.ts +3 -2
- package/src/account/device-signin-dialog.tsx +38 -13
- package/src/account/device-signin.ts +2 -1
- package/src/account/upgrade-dialog.tsx +6 -2
- package/src/api-client/askg.ts +5 -3
- package/src/api-client/bank-figures.ts +73 -0
- package/src/api-client/credit-boards.ts +21 -1
- package/src/api-client/crypto-markets.ts +88 -1
- package/src/api-client/data.ts +104 -4
- package/src/api-client/debt-maturities.ts +18 -0
- package/src/api-client/equity-screener.ts +3 -0
- package/src/api-client/errors.ts +13 -0
- package/src/api-client/fund-facts.ts +72 -0
- package/src/api-client/futures-curve.ts +26 -3
- package/src/api-client/geo.ts +11 -1
- package/src/api-client/index.ts +25 -2
- package/src/api-client/insider-signals.ts +95 -11
- package/src/api-client/normalizers.ts +1 -0
- package/src/api-client/paths.ts +20 -1
- package/src/api-client/request.ts +11 -3
- package/src/api-client/research-activity.ts +15 -8
- package/src/api-client/socket.ts +6 -3
- package/src/api-client/supply-chain-graph.ts +2 -2
- package/src/api-client/supply-chain.ts +8 -0
- package/src/api-client/tape.ts +12 -0
- package/src/api-client/types.ts +66 -2
- package/src/api-client/upgrade-experiment.ts +4 -3
- package/src/api-client/wall-experiments.ts +5 -3
- package/src/api-client/wall-summary.ts +3 -1
- package/src/api-client/web-experiments.ts +5 -2
- package/src/api-client/yield-curves.ts +17 -0
- package/src/app/command-bar-intro.ts +38 -0
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
- package/src/app/pane-runtime/plugin-bindings.ts +4 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
- package/src/app/pane-runtime/ticker-open-target.ts +31 -0
- package/src/app/runtime/desktop-deeplink.ts +3 -4
- package/src/app/runtime/plugin-bindings.ts +3 -2
- package/src/app/runtime/startup.ts +3 -4
- package/src/app/runtime/ticker-refresh.ts +13 -12
- package/src/app/runtime/update.ts +3 -2
- package/src/architecture/core-builtin-allowlist.json +0 -3
- package/src/architecture/silent-catch-allowlist.json +3 -0
- package/src/architecture/ui-literals-allowlist.json +186 -0
- package/src/architecture/ui-tokens-allowlist.json +40 -0
- package/src/ask-gloom/pane-context.ts +3 -1
- package/src/brokers/signed-in/catalog.ts +2 -1
- package/src/brokers/signed-in/client.ts +7 -2
- package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
- package/src/brokers/signed-in/sign-in.ts +22 -20
- package/src/brokers/sync-broker-instance.ts +2 -1
- package/src/capabilities/chart-series.ts +2 -0
- package/src/capabilities/registry.ts +1 -3
- package/src/cli/bank-section.ts +147 -0
- package/src/cli/base-converter.ts +5 -2
- package/src/cli/board-coins.ts +70 -0
- package/src/cli/commands/fred-series.ts +90 -0
- package/src/cli/commands/market.ts +340 -69
- package/src/cli/commands/news-search.ts +35 -2
- package/src/cli/commands/options-chain.ts +7 -5
- package/src/cli/commands/options-leaps.ts +3 -3
- package/src/cli/commands/overview.ts +78 -29
- package/src/cli/commands/plugins.ts +1 -0
- package/src/cli/commands/search.ts +87 -24
- package/src/cli/commands/system.ts +5 -2
- package/src/cli/commands/ticker.ts +337 -60
- package/src/cli/context.ts +2 -1
- package/src/cli/desktop-pane-shot.ts +11 -3
- package/src/cli/earnings-calendar.ts +2 -1
- package/src/cli/errors.ts +10 -0
- package/src/cli/export-source.ts +18 -3
- package/src/cli/glossary.ts +196 -14
- package/src/cli/history-rows.ts +60 -9
- package/src/cli/index-roots.ts +26 -0
- package/src/cli/index.ts +34 -9
- package/src/cli/known-gaps.ts +156 -22
- package/src/cli/listing-arg.ts +156 -12
- package/src/cli/listing-suggestion.ts +4 -2
- package/src/cli/name-entries.ts +76 -0
- package/src/cli/not-a-ticker.ts +15 -6
- package/src/cli/pane-functions/access-gate.ts +22 -0
- package/src/cli/pane-functions/capabilities.ts +62 -4
- package/src/cli/pane-functions/catalog.ts +94 -39
- package/src/cli/pane-functions/data.ts +6 -5
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +3 -3
- package/src/cli/pane-functions/freshness.ts +49 -8
- package/src/cli/pane-functions/function-help.ts +13 -10
- package/src/cli/pane-functions/headless.ts +177 -42
- package/src/cli/pane-functions/index.ts +64 -8
- package/src/cli/pane-functions/options.ts +17 -3
- package/src/cli/pane-functions/report-notices.ts +17 -3
- package/src/cli/pane-functions/resolver.ts +48 -13
- package/src/cli/pane-functions/screenshot.ts +124 -23
- package/src/cli/pane-functions/shot-options.ts +68 -0
- package/src/cli/perpetual-contract.ts +3 -1
- package/src/cli/report-tables.ts +10 -2
- package/src/cli/staged-tickers.ts +5 -0
- package/src/cli/statement-filings.ts +261 -0
- package/src/cli/symbol-args.ts +47 -8
- package/src/cli/symbol-list.ts +9 -2
- package/src/cli/symbol-rows.ts +269 -29
- package/src/cli/ticker-resolution.ts +148 -34
- package/src/cli/treasury-yields.ts +86 -0
- package/src/cli/types.ts +3 -0
- package/src/cli/uncovered-instrument.ts +20 -0
- package/src/components/chart/composite/axis-overlays.tsx +16 -9
- package/src/components/chart/composite/composite-chart.tsx +85 -6
- package/src/components/chart/composite/downsample.ts +19 -3
- package/src/components/chart/composite/format.ts +3 -0
- package/src/components/chart/composite/legend.tsx +155 -76
- package/src/components/chart/composite/panel-bitmap.ts +8 -2
- package/src/components/chart/composite/panel-surface.tsx +3 -3
- package/src/components/chart/composite/toolbar.tsx +12 -7
- package/src/components/chart/composite/types.ts +6 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
- package/src/components/chart/curve/curve-surface.tsx +1 -1
- package/src/components/chart/static/series.ts +39 -0
- package/src/components/chart/static/trail-chart-surface.tsx +2 -1
- package/src/components/command-bar/commands/collection-list.ts +45 -15
- package/src/components/command-bar/commands/collection.ts +10 -3
- package/src/components/command-bar/commands/registry.ts +2 -2
- package/src/components/command-bar/list/badge.ts +4 -3
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/panel/index.tsx +19 -8
- package/src/components/command-bar/panel/native-surface.ts +6 -4
- package/src/components/command-bar/panel/prompt-example.ts +22 -0
- package/src/components/command-bar/routes/root/provider-search.ts +3 -9
- package/src/components/command-bar/routes/root/results.ts +13 -0
- package/src/components/command-bar/routes/root/start-here.ts +90 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
- package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
- package/src/components/command-bar/theme-picker.tsx +3 -1
- package/src/components/command-bar/workflow/builtin.ts +5 -1
- package/src/components/command-bar/workflow/collection-actions.ts +21 -12
- package/src/components/command-bar/workflow/ops.ts +21 -1
- package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
- package/src/components/command-bar/workflow/tickers.ts +6 -4
- package/src/components/feedback-dialog.tsx +1 -1
- package/src/components/form-modal/broker-step.tsx +7 -63
- package/src/components/form-modal/content.tsx +7 -2
- package/src/components/form-modal/field-row.tsx +6 -8
- package/src/components/form-modal/host.tsx +3 -3
- package/src/components/form-modal/model.ts +3 -0
- package/src/components/form-modal/routes.ts +17 -2
- package/src/components/index.ts +6 -6
- package/src/components/input-search-bar.tsx +43 -6
- package/src/components/layout/detached-pane-shell.tsx +0 -1
- package/src/components/layout/floating-pane.tsx +0 -1
- package/src/components/layout/header.tsx +8 -7
- package/src/components/layout/pane/footer/index.tsx +7 -4
- package/src/components/layout/pane/footer/model.ts +28 -2
- package/src/components/layout/pane/header.tsx +9 -19
- package/src/components/layout/pane/index.tsx +0 -1
- package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
- package/src/components/layout/pane/pane-tabs.tsx +4 -3
- package/src/components/layout/pane/sizing.ts +9 -0
- package/src/components/layout/pane/ticker-fate-gate.tsx +8 -2
- package/src/components/layout/shell/pane/capture.ts +44 -20
- package/src/components/layout/status-bar.tsx +3 -6
- package/src/components/markdown-text.tsx +17 -2
- package/src/components/market-board/index.tsx +19 -8
- package/src/components/metric-treemap/heat-surface.tsx +2 -7
- package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
- package/src/components/onboarding/onboarding-frame.tsx +24 -21
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
- package/src/components/onboarding/wizard-positions.ts +40 -11
- package/src/components/pane-settings-dialog/desktop.tsx +12 -50
- package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
- package/src/components/price-performance.tsx +18 -2
- package/src/components/reader/article-reader.tsx +11 -10
- package/src/components/reader/detail-reader.tsx +9 -5
- package/src/components/reader/reader-text.tsx +51 -24
- package/src/components/sign-in-code-panel.tsx +129 -75
- package/src/components/ticker/badge/index.tsx +2 -1
- package/src/components/ui/action-row.tsx +5 -2
- package/src/components/ui/audio-player.tsx +70 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/data-table/index.tsx +4 -2
- package/src/components/ui/data-table/types.ts +11 -0
- package/src/components/ui/detail-scroll-body.tsx +1 -1
- package/src/components/ui/dialog-actions.tsx +1 -21
- package/src/components/ui/display.tsx +13 -5
- package/src/components/ui/external-link.tsx +4 -2
- package/src/components/ui/fields.tsx +12 -0
- package/src/components/ui/figure.tsx +5 -3
- package/src/components/ui/frame.tsx +40 -6
- package/src/components/ui/icon.tsx +4 -0
- package/src/components/ui/index.ts +4 -1
- package/src/components/ui/list-view.tsx +8 -0
- package/src/components/ui/prose.tsx +97 -25
- package/src/components/ui/query-bar-keys.tsx +3 -1
- package/src/components/ui/query-bar.tsx +6 -0
- package/src/components/ui/quote.ts +42 -0
- package/src/components/ui/range-track.tsx +15 -2
- package/src/components/ui/reveal-in-scroll-box.ts +21 -3
- package/src/components/ui/select-button.tsx +38 -3
- package/src/components/ui/status.tsx +73 -4
- package/src/components/ui/table-layout.ts +20 -0
- package/src/components/use-pinned-moment.ts +19 -0
- package/src/core/app-runtime.ts +2 -2
- package/src/core/state/app/instrument.ts +18 -1
- package/src/core/state/app/layout.ts +6 -0
- package/src/core/state/app/state.ts +14 -2
- package/src/data/cached-query.ts +1 -1
- package/src/data/config/chart-settings.ts +3 -1
- package/src/data/config/home.ts +4 -1
- package/src/data/config/store/node.ts +9 -4
- package/src/data/config/store/normalize.ts +9 -0
- package/src/data/json-storage.ts +6 -3
- package/src/data/json-ticker-repository.ts +3 -1
- package/src/data/plugin-cache.ts +5 -1
- package/src/data/sqlite/json.ts +3 -1
- package/src/data/ticker-repository.ts +5 -2
- package/src/feedback/diagnostics.ts +2 -6
- package/src/i18n/es.ts +86 -6
- package/src/i18n/index.ts +3 -9
- package/src/i18n/ja.ts +86 -6
- package/src/i18n/ko.ts +86 -6
- package/src/i18n/zh-cn.ts +86 -6
- package/src/i18n/zh-tw.ts +86 -6
- package/src/layout-marketplace/gallery-desktop.tsx +8 -4
- package/src/market-data/bars-per-year.ts +43 -0
- package/src/market-data/bond-funds.ts +85 -0
- package/src/market-data/coordinator/auxiliary.ts +5 -2
- package/src/market-data/coordinator/index.ts +6 -5
- package/src/market-data/futures-contract.ts +102 -5
- package/src/market-data/hooks.tsx +20 -11
- package/src/market-data/market/bar-period.ts +36 -0
- package/src/market-data/market/format.ts +5 -13
- package/src/market-data/market/freshness.ts +1 -3
- package/src/market-data/market/index-level.ts +51 -0
- package/src/market-data/model-dividend-yield.ts +57 -16
- package/src/market-data/quotes/live-valuation.ts +48 -2
- package/src/market-data/realized-volatility.ts +16 -7
- package/src/market-data/tax-equivalent.ts +344 -0
- package/src/news/aggregator.ts +4 -2
- package/src/notifications/notification-log.ts +5 -3
- package/src/plugins/auto-update-node.ts +1 -0
- package/src/plugins/builtin/account-management/footer.ts +1 -1
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +71 -19
- package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
- package/src/plugins/builtin/alerts/cli.ts +7 -18
- package/src/plugins/builtin/alerts/constants.ts +8 -0
- package/src/plugins/builtin/alerts/event-rows.ts +16 -0
- package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
- package/src/plugins/builtin/alerts/headless.ts +182 -0
- package/src/plugins/builtin/alerts/index.tsx +3 -0
- package/src/plugins/builtin/alerts/pane.tsx +1 -7
- package/src/plugins/builtin/alerts/storage.ts +17 -1
- package/src/plugins/builtin/analytics/index.tsx +6 -1
- package/src/plugins/builtin/analytics/metrics.ts +47 -9
- package/src/plugins/builtin/analytics/risk-headless.ts +14 -2
- package/src/plugins/builtin/analytics/risk-math.ts +83 -0
- package/src/plugins/builtin/analytics/risk-model.ts +97 -4
- package/src/plugins/builtin/analytics/risk-pane.tsx +11 -6
- package/src/plugins/builtin/analytics/sector-model.ts +14 -3
- package/src/plugins/builtin/awards/headless.ts +6 -5
- package/src/plugins/builtin/awards/index.tsx +1 -1
- package/src/plugins/builtin/backtest/client.ts +38 -8
- package/src/plugins/builtin/backtest/engine.ts +25 -13
- package/src/plugins/builtin/backtest/export.ts +27 -0
- package/src/plugins/builtin/backtest/format.ts +19 -3
- package/src/plugins/builtin/backtest/headless.ts +42 -28
- package/src/plugins/builtin/backtest/index.tsx +3 -0
- package/src/plugins/builtin/backtest/pane.tsx +39 -10
- package/src/plugins/builtin/backtest/report.ts +160 -0
- package/src/plugins/builtin/backtest/rules.ts +2 -0
- package/src/plugins/builtin/backtest/window.ts +112 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
- package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
- package/src/plugins/builtin/catalysts/headless.ts +24 -13
- package/src/plugins/builtin/catalysts/index.tsx +4 -2
- package/src/plugins/builtin/catalysts/model.ts +18 -1
- package/src/plugins/builtin/catalysts/pane.tsx +2 -2
- package/src/plugins/builtin/cds/client.ts +28 -5
- package/src/plugins/builtin/cds/headless.ts +183 -31
- package/src/plugins/builtin/cds/index.tsx +1 -1
- package/src/plugins/builtin/cds/model.ts +229 -53
- package/src/plugins/builtin/cds/pane.tsx +82 -26
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
- package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
- package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
- package/src/plugins/builtin/chart-composer/headless.ts +99 -21
- package/src/plugins/builtin/chart-composer/index.tsx +70 -13
- package/src/plugins/builtin/chart-composer/pane.tsx +65 -15
- package/src/plugins/builtin/chart-composer/presets.ts +79 -11
- package/src/plugins/builtin/chart-composer/series-catalog.ts +50 -14
- package/src/plugins/builtin/chart-composer/series-expression.ts +9 -7
- package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
- package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
- package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
- package/src/plugins/builtin/chat/content/composer.tsx +22 -1
- package/src/plugins/builtin/chat/content/index.tsx +35 -5
- package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
- package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
- package/src/plugins/builtin/chat/content/snapshot.ts +29 -6
- package/src/plugins/builtin/chat/ghost-user.ts +11 -3
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +13 -5
- package/src/plugins/builtin/chat/message/header.tsx +26 -4
- package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
- package/src/plugins/builtin/chat/message/render-state.ts +28 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
- package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
- package/src/plugins/builtin/chat/share/flow.tsx +9 -73
- package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
- package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
- package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
- package/src/plugins/builtin/cloud/plugin.tsx +2 -0
- package/src/plugins/builtin/cloud/team/module.tsx +5 -1
- package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
- package/src/plugins/builtin/cloud/team/views.ts +11 -4
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
- package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
- package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
- package/src/plugins/builtin/commodities-energy/index.tsx +8 -5
- package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
- package/src/plugins/builtin/company-attention/headless.ts +15 -7
- package/src/plugins/builtin/company-attention/index.tsx +1 -1
- package/src/plugins/builtin/company-attention/model.ts +49 -4
- package/src/plugins/builtin/company-attention/pane.tsx +11 -9
- package/src/plugins/builtin/company-kpis/headless.ts +4 -3
- package/src/plugins/builtin/company-kpis/index.tsx +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
- package/src/plugins/builtin/congress-trades/headless.ts +23 -2
- package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
- package/src/plugins/builtin/cot/headless.ts +5 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
- package/src/plugins/builtin/credit-boards/client.ts +9 -2
- package/src/plugins/builtin/credit-boards/headless.ts +93 -27
- package/src/plugins/builtin/credit-boards/index.tsx +15 -4
- package/src/plugins/builtin/credit-boards/model.ts +105 -6
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
- package/src/plugins/builtin/credit-documents/index.tsx +3 -0
- package/src/plugins/builtin/credit-documents/model.ts +3 -10
- package/src/plugins/builtin/crypto-board/client.ts +152 -2
- package/src/plugins/builtin/crypto-board/headless.ts +138 -19
- package/src/plugins/builtin/crypto-board/index.tsx +5 -3
- package/src/plugins/builtin/crypto-board/model.ts +210 -12
- package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
- package/src/plugins/builtin/crypto-board/series.ts +52 -1
- package/src/plugins/builtin/crypto-board/supply.ts +123 -0
- package/src/plugins/builtin/debt-maturities/client.ts +54 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/model.ts +58 -13
- package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
- package/src/plugins/builtin/dividend-yield/client.ts +42 -36
- package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
- package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
- package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
- package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
- package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
- package/src/plugins/builtin/dividend-yield/types.ts +6 -1
- package/src/plugins/builtin/dividend-yield/view.ts +1 -1
- package/src/plugins/builtin/docs/blocks.tsx +54 -8
- package/src/plugins/builtin/docs/pane.tsx +8 -13
- package/src/plugins/builtin/earnings/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/data.ts +51 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
- package/src/plugins/builtin/earnings-calls/model.ts +97 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
- package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
- package/src/plugins/builtin/econ/calendar-model.ts +22 -0
- package/src/plugins/builtin/econ/calendar-source.ts +35 -0
- package/src/plugins/builtin/econ/index.tsx +40 -8
- package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +8 -1
- package/src/plugins/builtin/econ-statistics/headless.ts +26 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +4 -2
- package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -0
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +46 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
- package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
- package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/editor.tsx +3 -3
- package/src/plugins/builtin/fear-greed/index.tsx +9 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures/index.tsx +2 -2
- package/src/plugins/builtin/futures/model.ts +34 -21
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
- package/src/plugins/builtin/futures-curve/headless.ts +4 -2
- package/src/plugins/builtin/futures-curve/model.ts +5 -7
- package/src/plugins/builtin/help/index.tsx +55 -8
- package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
- package/src/plugins/builtin/holders/headless.ts +12 -0
- package/src/plugins/builtin/insider/headless.ts +311 -41
- package/src/plugins/builtin/insider/index.tsx +280 -106
- package/src/plugins/builtin/insider/insiders.tsx +224 -0
- package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
- package/src/plugins/builtin/insider/signals-client.ts +135 -11
- package/src/plugins/builtin/insider/signals-model.ts +628 -56
- package/src/plugins/builtin/insider/signals.tsx +283 -83
- package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
- package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
- package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
- package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
- package/src/plugins/builtin/iv-history/headless.ts +2 -0
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jodi/headless.ts +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
- package/src/plugins/builtin/market-valuation/pane.tsx +1 -1
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
- package/src/plugins/builtin/mna/distress/headless.ts +2 -1
- package/src/plugins/builtin/mna/headless.ts +14 -2
- package/src/plugins/builtin/mna/index.tsx +1 -0
- package/src/plugins/builtin/news/headless.ts +4 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
- package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
- package/src/plugins/builtin/notes/cli.ts +8 -4
- package/src/plugins/builtin/notes/files.ts +66 -20
- package/src/plugins/builtin/notes/migration.ts +18 -6
- package/src/plugins/builtin/notes/owner.tsx +3 -2
- package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
- package/src/plugins/builtin/options-scenario/client.ts +7 -4
- package/src/plugins/builtin/options-scenario/headless.ts +5 -3
- package/src/plugins/builtin/pe-band/index.tsx +1 -1
- package/src/plugins/builtin/pe-band/model.ts +1 -15
- package/src/plugins/builtin/perps/headless.ts +30 -13
- package/src/plugins/builtin/perps/model.ts +45 -3
- package/src/plugins/builtin/perps/pane.tsx +7 -7
- package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +108 -46
- package/src/plugins/builtin/portfolio-list/cli/render.ts +368 -45
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +8 -2
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +24 -34
- package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +151 -29
- package/src/plugins/builtin/portfolio-list/income.ts +296 -0
- package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
- package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +27 -10
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +3 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +10 -3
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +31 -3
- package/src/plugins/builtin/portfolio-list/table.tsx +25 -5
- package/src/plugins/builtin/power/prices-headless.ts +2 -1
- package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
- package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
- package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +6 -4
- package/src/plugins/builtin/realized-vol/model.ts +5 -1
- package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
- package/src/plugins/builtin/realized-vol/settings.ts +1 -1
- package/src/plugins/builtin/research/analyst-headless.ts +4 -0
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -0
- package/src/plugins/builtin/research/event-model.ts +22 -2
- package/src/plugins/builtin/research/headless-schema.ts +1 -0
- package/src/plugins/builtin/research/headless.ts +3 -0
- package/src/plugins/builtin/research/index.tsx +3 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
- package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +9 -6
- package/src/plugins/builtin/reverse-dcf/index.tsx +2 -2
- package/src/plugins/builtin/reverse-dcf/model.ts +51 -4
- package/src/plugins/builtin/reverse-dcf/pane.tsx +23 -10
- package/src/plugins/builtin/risk-factors/headless.ts +7 -0
- package/src/plugins/builtin/risk-factors/index.tsx +1 -0
- package/src/plugins/builtin/scanner/feed.ts +5 -3
- package/src/plugins/builtin/scanner/headless.ts +9 -57
- package/src/plugins/builtin/scanner/index.ts +1 -2
- package/src/plugins/builtin/sec/forms.ts +2 -6
- package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
- package/src/plugins/builtin/sec/fund-facts.ts +328 -0
- package/src/plugins/builtin/sec/headless.ts +140 -44
- package/src/plugins/builtin/sec/index.tsx +95 -30
- package/src/plugins/builtin/sec/model.ts +2 -44
- package/src/plugins/builtin/shared/headless-options.ts +10 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
- package/src/plugins/builtin/shared/move-rank.ts +108 -0
- package/src/plugins/builtin/shared/report-freshness.ts +25 -9
- package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
- package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +1 -0
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
- package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
- package/src/plugins/builtin/short-interest/headless.ts +3 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
- package/src/plugins/builtin/social-mentions/client.ts +8 -1
- package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
- package/src/plugins/builtin/supply-chain/client.ts +12 -3
- package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
- package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
- package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
- package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
- package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
- package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
- package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
- package/src/plugins/builtin/supply-chain/headless.ts +69 -27
- package/src/plugins/builtin/supply-chain/index.tsx +1 -1
- package/src/plugins/builtin/supply-chain/model.ts +76 -15
- package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
- package/src/plugins/builtin/themes/model.ts +2 -5
- package/src/plugins/builtin/thirteenf/api.ts +50 -2
- package/src/plugins/builtin/thirteenf/data.ts +250 -11
- package/src/plugins/builtin/thirteenf/headless.ts +311 -28
- package/src/plugins/builtin/thirteenf/index.tsx +4 -1
- package/src/plugins/builtin/thirteenf/model.ts +244 -19
- package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
- package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
- package/src/plugins/builtin/thirteenf/types.ts +49 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -8
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +17 -1
- package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/headless.ts +23 -10
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
- package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +36 -3
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
- package/src/plugins/builtin/time-sales/client.ts +7 -4
- package/src/plugins/builtin/time-sales/headless.ts +71 -22
- package/src/plugins/builtin/time-sales/model.ts +12 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -7
- package/src/plugins/builtin/time-sales/window.ts +128 -0
- package/src/plugins/builtin/trace-bonds/client.ts +351 -33
- package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
- package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
- package/src/plugins/builtin/trace-bonds/model.ts +27 -25
- package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
- package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
- package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
- package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
- package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
- package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
- package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
- package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
- package/src/plugins/builtin/vol-surface/headless.ts +3 -2
- package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
- package/src/plugins/builtin/vol-surface/stored.ts +4 -7
- package/src/plugins/builtin/volatility/chart-model.ts +16 -15
- package/src/plugins/builtin/volatility/charts.tsx +5 -5
- package/src/plugins/builtin/volatility/client.ts +73 -2
- package/src/plugins/builtin/volatility/evidence.ts +13 -14
- package/src/plugins/builtin/volatility/headless.ts +13 -7
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/volatility/model.ts +104 -38
- package/src/plugins/builtin/volatility/pane.tsx +42 -24
- package/src/plugins/builtin/volatility/series.ts +22 -13
- package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +8 -5
- package/src/plugins/builtin/world-venue-map/index.ts +16 -2
- package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
- package/src/plugins/builtin/yield-curve/curves.ts +29 -5
- package/src/plugins/builtin/yield-curve/headless.ts +41 -8
- package/src/plugins/builtin/yield-curve/history.ts +5 -5
- package/src/plugins/builtin/yield-curve/index.tsx +30 -13
- package/src/plugins/compat.ts +3 -1
- package/src/plugins/dependencies.ts +8 -2
- package/src/plugins/host-link.ts +12 -5
- package/src/plugins/installer.ts +16 -7
- package/src/plugins/loader.ts +9 -2
- package/src/plugins/marketplace/activation.ts +10 -4
- package/src/plugins/registry/host-actions.ts +3 -0
- package/src/plugins/registry/index.ts +3 -1
- package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +74 -12
- package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +140 -53
- package/src/portfolio/futures-positions.ts +213 -0
- package/src/portfolio/futures-terms.ts +75 -0
- package/src/portfolio/manual-lots.ts +78 -0
- package/src/portfolio/mutations.ts +54 -10
- package/src/portfolio/position-metrics.ts +44 -10
- package/src/portfolio/valuation-basis.ts +31 -4
- package/src/public/__snapshots__/public-api.test.ts.snap +4 -0
- package/src/public/time-series.ts +2 -1
- package/src/remote/confirm-change.tsx +2 -1
- package/src/remote/server.ts +1 -1
- package/src/remote/watchlist.ts +9 -1
- package/src/renderers/dom/data-table/row.tsx +1 -1
- package/src/renderers/dom/desktop/audio-player.tsx +312 -0
- package/src/renderers/dom/desktop/control-styles.ts +17 -82
- package/src/renderers/dom/desktop/controls.tsx +39 -63
- package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
- package/src/renderers/dom/desktop/icons.tsx +8 -0
- package/src/renderers/dom/desktop/list-view.tsx +6 -6
- package/src/renderers/dom/desktop/popover.tsx +0 -3
- package/src/renderers/dom/desktop/query-bar.tsx +6 -4
- package/src/renderers/dom/desktop/select-field.tsx +9 -8
- package/src/renderers/dom/desktop/stack-header.ts +3 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -2
- package/src/renderers/dom/host/chart-surface.tsx +3 -3
- package/src/renderers/dom/host/size-observer.ts +33 -4
- package/src/renderers/dom/host/surface-3d.tsx +3 -2
- package/src/renderers/dom/host/surface-fit.ts +4 -1
- package/src/renderers/dom/host/tabs.tsx +22 -132
- package/src/renderers/dom/styles.css +358 -160
- package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
- package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
- package/src/series/capability.ts +1 -0
- package/src/series/files.ts +9 -3
- package/src/series/registry.ts +40 -14
- package/src/series/resolve.ts +121 -18
- package/src/series/standalone.ts +3 -2
- package/src/series/types.ts +55 -1
- package/src/series/validate.ts +39 -0
- package/src/shares/api.ts +26 -7
- package/src/shares/bug-report-dialog.tsx +2 -2
- package/src/shares/bug-report-flow.tsx +4 -7
- package/src/shares/capture-flow.ts +5 -4
- package/src/shares/capture-preview.tsx +2 -2
- package/src/shares/chat.ts +7 -27
- package/src/shares/flow.tsx +86 -40
- package/src/shares/location.ts +1 -3
- package/src/shares/pane-image.ts +11 -9
- package/src/shares/pane.ts +5 -2
- package/src/shares/payload.ts +1 -1
- package/src/shares/personal-pane.ts +3 -3
- package/src/shares/portable-layout.ts +9 -2
- package/src/shares/ready.ts +42 -0
- package/src/shares/test-harness.ts +62 -0
- package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
- package/src/sources/gloomberb-cloud/index.ts +64 -12
- package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
- package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
- package/src/sources/history-omitted.ts +34 -0
- package/src/sources/history-result.ts +3 -0
- package/src/sources/history-retention.ts +1 -1
- package/src/sources/provider-errors.ts +43 -1
- package/src/sources/provider-router/batches.ts +3 -2
- package/src/sources/provider-router/cache.ts +2 -1
- package/src/sources/provider-router/cached-routes.ts +9 -3
- package/src/sources/provider-router/history.ts +9 -8
- package/src/sources/provider-router/index.ts +18 -3
- package/src/sources/provider-router/primary.ts +5 -4
- package/src/sources/provider-router/quote-route.ts +3 -1
- package/src/sources/provider-router/routing.ts +2 -1
- package/src/sources/provider-router/search.ts +47 -13
- package/src/sources/provider-router/streaming.ts +7 -4
- package/src/sources/sec-edgar.ts +1 -3
- package/src/state/app/context/index.tsx +9 -13
- package/src/state/app/tab-cursor.ts +149 -12
- package/src/state/hooks/quote-streaming.ts +3 -2
- package/src/state/hooks/session-snapshot.ts +3 -2
- package/src/state/persist-scheduler.ts +12 -4
- package/src/sync/controller.ts +22 -1
- package/src/sync/core-contributors.ts +58 -15
- package/src/team/collections-sync.ts +14 -4
- package/src/team/collections.ts +40 -11
- package/src/team/store.ts +5 -4
- package/src/telemetry/attention-counts.ts +8 -2
- package/src/telemetry/crash-reports-dom.ts +3 -0
- package/src/telemetry/crash-reports-node.ts +7 -4
- package/src/telemetry/crash-reports.ts +11 -11
- package/src/telemetry/usage-counts.ts +16 -12
- package/src/theme/colors.ts +2 -0
- package/src/theme/font-scale.ts +2 -0
- package/src/theme/ui-tokens.ts +71 -0
- package/src/tickers/batched-lookups.ts +186 -0
- package/src/tickers/company-name-listing.ts +97 -0
- package/src/tickers/company-name.ts +13 -0
- package/src/tickers/instrument-coverage.ts +112 -0
- package/src/tickers/listing-fate.ts +49 -9
- package/src/tickers/listing-venues.ts +24 -5
- package/src/tickers/open-target.ts +13 -5
- package/src/tickers/search/index.ts +112 -35
- package/src/tickers/search/ranking.ts +49 -1
- package/src/tickers/terminal-codes.ts +79 -0
- package/src/tickers/ticker-changes.ts +74 -3
- package/src/tickers/us-listing.ts +2 -1
- package/src/time-series/chart-data.ts +79 -8
- package/src/time-series/fundamentals.ts +55 -7
- package/src/time-series/ice-credit.ts +17 -2
- package/src/time-series/live-bars.ts +21 -8
- package/src/time-series/live-quotes.ts +2 -3
- package/src/time-series/price-comparison.ts +6 -1
- package/src/time-series/resolve.ts +65 -10
- package/src/time-series/spec.ts +2 -1
- package/src/time-series/studies.ts +3 -3
- package/src/time-series/types.ts +22 -0
- package/src/time-series/use-chart-resolution.ts +2 -1
- package/src/types/config.ts +7 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/headless.ts +142 -1
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +32 -9
- package/src/types/price-history.ts +5 -0
- package/src/types/ticker-changes.ts +19 -0
- package/src/types/ticker.ts +10 -2
- package/src/ui/context-menu.tsx +2 -0
- package/src/ui/host.tsx +40 -4
- package/src/ui/measured-cells.ts +13 -7
- package/src/ui/qr.ts +7 -5
- package/src/updater/index.ts +5 -5
- package/src/utils/calendar-date.ts +86 -27
- package/src/utils/currency-units.ts +17 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/dividend-cash.ts +48 -0
- package/src/utils/dom-screenshot-rasters.ts +3 -1
- package/src/utils/dom-screenshot.ts +14 -10
- package/src/utils/exchange-rate-snapshot.ts +9 -4
- package/src/utils/external-url.ts +1 -0
- package/src/utils/fiscal-period.ts +47 -0
- package/src/utils/format.ts +5 -2
- package/src/utils/forward-dividend.ts +160 -11
- package/src/utils/futures-generic.ts +34 -8
- package/src/utils/http-proxy-response.ts +2 -1
- package/src/utils/local-utc-offset.ts +2 -0
- package/src/utils/log-failure.ts +31 -0
- package/src/utils/option-expiry.ts +12 -12
- package/src/utils/price-history-integrity.ts +56 -0
- package/src/utils/price-history.ts +13 -1
- package/src/utils/sec-filings.ts +245 -0
- package/src/utils/selection-clipboard.ts +5 -2
- package/src/utils/throttled-fetch.ts +1 -0
- package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
- package/src/utils/url.ts +1 -0
- package/src/utils/utc-time.ts +11 -0
- package/src/plugins/builtin/chat/share/targets.ts +0 -27
- package/src/renderers/dom/host/top-surface.ts +0 -119
- package/src/shares/dialog.tsx +0 -221
- package/src/shares/live.ts +0 -19
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FINANCIAL_VINTAGE_NOTICE, SEC_EPS_BASIS_NOTICE } from "../../../utils/financial-statements";
|
|
2
2
|
import { usePaneSharePreparation } from "../../../shares/prepare";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { useTabCursorLink } from "../../../state/app/tab-cursor";
|
|
4
5
|
import { Box, useUiCapabilities } from "../../../ui";
|
|
5
6
|
import {
|
|
6
7
|
ChoiceDialog,
|
|
@@ -30,6 +31,8 @@ import {
|
|
|
30
31
|
type ManualChartResolution,
|
|
31
32
|
} from "../../../time-series/resolution";
|
|
32
33
|
import { useResolvedChartSpec } from "../../../time-series/hooks";
|
|
34
|
+
import { shortCompanyName } from "../../../tickers/company-name";
|
|
35
|
+
import { useSeriesListings } from "./series-listings";
|
|
33
36
|
import { LIVE_CHART_TERMINAL_FRAME_MS } from "../../../time-series/live-quotes";
|
|
34
37
|
import { FORWARD_VALUATION_BASIS_NOTICES } from "../../../time-series/forward-valuation";
|
|
35
38
|
import { chartSeriesSourceKey } from "../../../capabilities";
|
|
@@ -56,8 +59,10 @@ import { chartComposerSemanticMetadata } from "./semantic";
|
|
|
56
59
|
import {
|
|
57
60
|
canToggleChartSeries,
|
|
58
61
|
CHART_INTERACTION_VIEWPORT_SETTING_KEY,
|
|
62
|
+
CHART_PINNED_MOMENT_SETTING_KEY,
|
|
59
63
|
CHART_SPEC_SETTING_KEY,
|
|
60
64
|
parseChartInteractionViewport,
|
|
65
|
+
parseSharedPinnedMoment,
|
|
61
66
|
parseChartSpecOr,
|
|
62
67
|
projectVisibleChartSeries,
|
|
63
68
|
toggleChartSeries,
|
|
@@ -67,6 +72,7 @@ import {
|
|
|
67
72
|
futuresGenericRollFromValue,
|
|
68
73
|
futuresGenericRollLabel,
|
|
69
74
|
futuresGenericRollValue,
|
|
75
|
+
standardFuturesGenericRoll,
|
|
70
76
|
type FuturesGenericAdjust,
|
|
71
77
|
} from "../../../utils/futures-generic";
|
|
72
78
|
import { chartSeriesLabel } from "./series-expression";
|
|
@@ -190,11 +196,14 @@ interface ChartComposerSurfaceProps {
|
|
|
190
196
|
height: number;
|
|
191
197
|
footerId: string;
|
|
192
198
|
onCapture?: (capturing: boolean) => void;
|
|
199
|
+
/** The legend names each series' company; a ticker's own research tab already does. */
|
|
200
|
+
nameSeries?: boolean;
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
const QUICK_ADD_CAPTURE = "quick-add";
|
|
196
204
|
|
|
197
205
|
const GENERIC_ROLL_OPTIONS = [
|
|
206
|
+
{ value: "standard", label: "Standard" },
|
|
198
207
|
{ value: "oi", label: "OI switch" },
|
|
199
208
|
{ value: "f5", label: "5d before notice" },
|
|
200
209
|
{ value: "d15", label: "Day 15" },
|
|
@@ -277,6 +286,7 @@ function ChartComposerSurface({
|
|
|
277
286
|
height,
|
|
278
287
|
footerId,
|
|
279
288
|
onCapture,
|
|
289
|
+
nameSeries = true,
|
|
280
290
|
}: ChartComposerSurfaceProps) {
|
|
281
291
|
const dialog = useDialog();
|
|
282
292
|
const dispatch = useAppDispatch();
|
|
@@ -310,6 +320,19 @@ function ChartComposerSurface({
|
|
|
310
320
|
CHART_INTERACTION_VIEWPORT_SETTING_KEY,
|
|
311
321
|
null,
|
|
312
322
|
);
|
|
323
|
+
// A link shared while its sender's crosshair was pinned opens on that
|
|
324
|
+
// moment: the chart pins its tab there once, then forgets it, so a restart
|
|
325
|
+
// does not pin it again. The value came from a link: anything but a
|
|
326
|
+
// plausible time is dropped without pinning. This handle only sets the
|
|
327
|
+
// pin; the chart it opens on is what shows and keeps it.
|
|
328
|
+
const [pinnedMoment, setPinnedMoment] = usePaneSettingValue<unknown>(CHART_PINNED_MOMENT_SETTING_KEY, null);
|
|
329
|
+
const momentLink = useTabCursorLink(paneId ? `${paneId}:moment` : null, { viewer: false });
|
|
330
|
+
useEffect(() => {
|
|
331
|
+
if (pinnedMoment == null || !momentLink?.pin) return;
|
|
332
|
+
const moment = parseSharedPinnedMoment(pinnedMoment);
|
|
333
|
+
if (moment !== null) momentLink.pin(moment);
|
|
334
|
+
setPinnedMoment(undefined);
|
|
335
|
+
}, [momentLink, pinnedMoment, setPinnedMoment]);
|
|
313
336
|
const persistedInteractionViewport = useMemo(
|
|
314
337
|
() => parseChartInteractionViewport(storedInteractionViewport),
|
|
315
338
|
[storedInteractionViewport],
|
|
@@ -332,7 +355,9 @@ function ChartComposerSurface({
|
|
|
332
355
|
// small zoom keeps the bars it already has. Read from the previous render:
|
|
333
356
|
// the resolver only consults it when the viewport moves.
|
|
334
357
|
const currentResolutionRef = useRef<ManualChartResolution | null>(null);
|
|
335
|
-
|
|
358
|
+
// Bare series are read as `quote` reads them before anything is loaded for them.
|
|
359
|
+
const listings = useSeriesListings(spec);
|
|
360
|
+
const resolution = useResolvedChartSpec(listings.spec, {
|
|
336
361
|
autoViewport: spec.viewport.resolution === "auto"
|
|
337
362
|
? activeRuntimeViewport?.adaptiveViewport
|
|
338
363
|
: null,
|
|
@@ -391,10 +416,18 @@ function ChartComposerSurface({
|
|
|
391
416
|
// them. Without a placeholder they vanish from the legend entirely and the
|
|
392
417
|
// only way back is the series dialog.
|
|
393
418
|
const legendSeries = useMemo(() => {
|
|
394
|
-
|
|
419
|
+
// Each security series names its company once, beside its label: "AAPL Price · Apple".
|
|
420
|
+
const named = new Set<string>();
|
|
421
|
+
const resolved = (resolution.legendSeries ?? []).map((entry) => {
|
|
422
|
+
const name = nameSeries ? listings.names.get(entry.id) : undefined;
|
|
423
|
+
const company = name ? shortCompanyName(name) : "";
|
|
424
|
+
if (!company || named.has(company)) return entry;
|
|
425
|
+
named.add(company);
|
|
426
|
+
return { ...entry, label: `${entry.label} · ${company}` };
|
|
427
|
+
});
|
|
395
428
|
const resolvedIds = new Set(resolved.map((entry) => entry.id));
|
|
396
429
|
const missing = spec.series.filter((entry) => !resolvedIds.has(entry.id));
|
|
397
|
-
if (missing.length === 0) return resolution.legendSeries;
|
|
430
|
+
if (missing.length === 0) return named.size > 0 ? resolved : resolution.legendSeries;
|
|
398
431
|
const bySpecOrder = new Map(spec.series.map((entry, index) => [entry.id, index] as const));
|
|
399
432
|
return [
|
|
400
433
|
...resolved,
|
|
@@ -415,7 +448,7 @@ function ChartComposerSurface({
|
|
|
415
448
|
points: [],
|
|
416
449
|
})),
|
|
417
450
|
].sort((a, b) => (bySpecOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER) - (bySpecOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER));
|
|
418
|
-
}, [resolution.legendSeries, spec.series]);
|
|
451
|
+
}, [listings.names, nameSeries, resolution.legendSeries, spec.series]);
|
|
419
452
|
const plottedSeries = useMemo(
|
|
420
453
|
() => projectVisibleChartSeries(
|
|
421
454
|
spec,
|
|
@@ -896,7 +929,9 @@ function ChartComposerSurface({
|
|
|
896
929
|
const comparisonUnavailable = comparisonHasNoWindow && !resolution.loading
|
|
897
930
|
? "Comparison unavailable: need two shared dates and a nonzero baseline."
|
|
898
931
|
: null;
|
|
899
|
-
const
|
|
932
|
+
const loading = resolution.loading || listings.pending;
|
|
933
|
+
// A bare code several companies list asks which, as `quote` does, before anything else is said.
|
|
934
|
+
const statusError = listings.errors[0] ?? resolution.errors[0];
|
|
900
935
|
// A spread or formula error names its legs and their units; the study's id adds nothing to it.
|
|
901
936
|
const formulaStudy = spec.studies.find((study) => (study.kind === "spread" || study.kind === "formula")
|
|
902
937
|
&& statusError?.startsWith(`${study.id}: `));
|
|
@@ -904,7 +939,9 @@ function ChartComposerSurface({
|
|
|
904
939
|
// Failed series use their authored id in errors and their display label in warnings.
|
|
905
940
|
const errorSeries = spec.series.find((entry) => statusError?.startsWith(`${entry.label ?? entry.id}: `));
|
|
906
941
|
const errorMessage = errorSeries ? statusError?.slice(`${errorSeries.label ?? errorSeries.id}: `.length) : undefined;
|
|
907
|
-
|
|
942
|
+
// The label the resolver wrote its warnings with, before the legend named the company.
|
|
943
|
+
const errorSeriesLabel = (resolution.legendSeries?.find((entry) => entry.id === errorSeries?.id)
|
|
944
|
+
?? legendSeries?.find((entry) => entry.id === errorSeries?.id))?.label;
|
|
908
945
|
const duplicateErrorNotices = new Set([statusError, errorMessage,
|
|
909
946
|
errorSeriesLabel && errorMessage ? `${errorSeriesLabel}: ${errorMessage}` : undefined]);
|
|
910
947
|
// A failed shared window empties every compared leg; one comparison message explains it.
|
|
@@ -923,7 +960,8 @@ function ChartComposerSurface({
|
|
|
923
960
|
&& warning.endsWith("; only matching observation times contribute."))
|
|
924
961
|
))
|
|
925
962
|
));
|
|
926
|
-
const statusNotices = [...new Set([...(statusErrorNotice ? [statusErrorNotice] : []), ...
|
|
963
|
+
const statusNotices = [...new Set([...(statusErrorNotice ? [statusErrorNotice] : []), ...listings.errors, ...listings.notices,
|
|
964
|
+
...(comparisonUnavailable ? [comparisonUnavailable] : []), ...statusWarnings])];
|
|
927
965
|
usePaneNoticeFooter({
|
|
928
966
|
registrationId: `${footerId}:notices`,
|
|
929
967
|
notices: statusNotices,
|
|
@@ -964,7 +1002,7 @@ function ChartComposerSurface({
|
|
|
964
1002
|
return newest > end ? formatCompositeDatasetDate(new Date(newest), end) : null;
|
|
965
1003
|
}, [activeRuntimeViewport, plottedSeries, spec, viewport]);
|
|
966
1004
|
usePaneFooter(footerId, () => ({
|
|
967
|
-
info:
|
|
1005
|
+
info: loading
|
|
968
1006
|
? [{ id: "loading", parts: [{ text: "loading", tone: "muted" as const }] }]
|
|
969
1007
|
: pickingAnchor
|
|
970
1008
|
? [{ id: "anchor", parts: [{ text: "pick a bar to anchor VWAP", tone: "muted" as const }] }]
|
|
@@ -978,7 +1016,7 @@ function ChartComposerSurface({
|
|
|
978
1016
|
{ id: "resolution", key: "t", label: "imeframe", onPress: footerResolution },
|
|
979
1017
|
...(anchorable ? [{ id: "vwap-anchor", key: "v", label: "wap anchor", title: "Anchor VWAP", onPress: footerAnchor }] : []),
|
|
980
1018
|
],
|
|
981
|
-
}), [
|
|
1019
|
+
}), [loading, pickingAnchor, newestBeyondView, footerSeries, openIndicators, indicatorsDisabled, openFormulas, formulasDisabled, footerResolution, anchorable, footerAnchor]);
|
|
982
1020
|
|
|
983
1021
|
// A fixed window (a GIP session) highlights no range, so the bar names it.
|
|
984
1022
|
const dateWindowLabel = useMemo(() => {
|
|
@@ -996,9 +1034,12 @@ function ChartComposerSurface({
|
|
|
996
1034
|
const genericFilters = useMemo(() => {
|
|
997
1035
|
if (!generic) return [];
|
|
998
1036
|
const roll = futuresGenericRollValue(generic.roll);
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1037
|
+
const notice = futuresGenericNotice(generic.root) === "first notice" ? "notice" : "last trade";
|
|
1038
|
+
const standard = standardFuturesGenericRoll(generic.root);
|
|
1039
|
+
const rollOptions = GENERIC_ROLL_OPTIONS.map((option) => option.value === "f5" ? { ...option, label: `5d before ${notice}` }
|
|
1040
|
+
: option.value === "standard" && standard.rule === "first-notice"
|
|
1041
|
+
? { ...option, label: standard.days === 0 ? `Standard, after ${notice}` : `Standard, ${standard.days}d before ${notice}` }
|
|
1042
|
+
: option);
|
|
1002
1043
|
if (!rollOptions.some((option) => option.value === roll)) rollOptions.push({ value: roll, label: futuresGenericRollLabel(generic) });
|
|
1003
1044
|
const update = (change: Parameters<typeof setChartFuturesGeneric>[1]) => {
|
|
1004
1045
|
const next = setChartFuturesGeneric(specRef.current, change);
|
|
@@ -1008,7 +1049,7 @@ function ChartComposerSurface({
|
|
|
1008
1049
|
return [
|
|
1009
1050
|
{ id: "roll", label: "Roll", value: roll, options: rollOptions, title: "Roll rule",
|
|
1010
1051
|
onChange: (value: string) => {
|
|
1011
|
-
const next = futuresGenericRollFromValue(value);
|
|
1052
|
+
const next = futuresGenericRollFromValue(value, generic.root);
|
|
1012
1053
|
if (next) update({ roll: next });
|
|
1013
1054
|
} },
|
|
1014
1055
|
{ id: "adjust", label: "Adjust", value: generic.adjust, options: GENERIC_ADJUST_OPTIONS, title: "Adjustment",
|
|
@@ -1041,11 +1082,18 @@ function ChartComposerSurface({
|
|
|
1041
1082
|
}]
|
|
1042
1083
|
: [];
|
|
1043
1084
|
|
|
1085
|
+
// A company that reports no quarterly figures says so, and where its annual ones are.
|
|
1086
|
+
const unreported = resolution.legendSeries?.find((entry) => entry.unreportedPeriod && entry.points.length === 0);
|
|
1044
1087
|
const emptyMessage = spec.series.length === 0
|
|
1045
1088
|
? "Add a series to start the chart"
|
|
1046
|
-
:
|
|
1089
|
+
: loading
|
|
1047
1090
|
? "Loading chart data"
|
|
1048
|
-
: statusErrorNotice ?? comparisonUnavailable
|
|
1091
|
+
: statusErrorNotice ?? comparisonUnavailable
|
|
1092
|
+
?? (unreported ? `${unreported.label} has no ${unreported.unreportedPeriod} figures. Set Period to Annual in Series.` : "No observations in this range");
|
|
1093
|
+
// Under "Choose an exchange for BDI.", the listings it asks between.
|
|
1094
|
+
const emptyDetail = !loading && spec.series.length > 0 && emptyMessage === statusErrorNotice && statusError
|
|
1095
|
+
? listings.choices.get(statusError)
|
|
1096
|
+
: undefined;
|
|
1049
1097
|
|
|
1050
1098
|
return (
|
|
1051
1099
|
<Box flexDirection="column" width={width} height={height}>
|
|
@@ -1127,6 +1175,7 @@ function ChartComposerSurface({
|
|
|
1127
1175
|
timePick={timePick}
|
|
1128
1176
|
levels={chartLevels}
|
|
1129
1177
|
emptyMessage={emptyMessage}
|
|
1178
|
+
emptyDetail={emptyDetail}
|
|
1130
1179
|
legendAccessory={(
|
|
1131
1180
|
<ChartSeriesQuickAdd
|
|
1132
1181
|
spec={spec}
|
|
@@ -1258,6 +1307,7 @@ export function ChartComposerResearchTab({ focused, width, height, onCapture }:
|
|
|
1258
1307
|
height={height}
|
|
1259
1308
|
footerId="chart-composer:research"
|
|
1260
1309
|
onCapture={onCapture}
|
|
1310
|
+
nameSeries={false}
|
|
1261
1311
|
/>
|
|
1262
1312
|
);
|
|
1263
1313
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../../../time-series/types";
|
|
7
7
|
import type { ChartResolution, TimeRange } from "../../../components/chart/core/types";
|
|
8
8
|
import { MAX_CHART_COMPOSER_SERIES } from "./chart-spec";
|
|
9
|
-
import { appendChartSeries, buildCustomSeries, buildSeriesSpec, panelsForSeries } from "./chart-spec-edit";
|
|
9
|
+
import { appendChartSeries, appendPlacedSeries, buildCustomSeries, buildSeriesSpec, panelsForSeries } from "./chart-spec-edit";
|
|
10
10
|
import { currencyPairSpelling } from "../../../utils/currency-pair";
|
|
11
11
|
import { dashedCoinPair } from "../../../utils/crypto-pair";
|
|
12
12
|
import {
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
import { setBuiltinStudies, setPairStudies, type PairStudySelection } from "./studies";
|
|
22
22
|
import { looksLikeFormula, parseFormulaExpression, type ParsedFormula } from "./formula";
|
|
23
23
|
import type { SeriesCatalogSuggestion } from "./series-catalog";
|
|
24
|
+
import { getSharedRegistry } from "../../registry";
|
|
25
|
+
import { seriesCatalogEntry } from "../../../series/registry";
|
|
24
26
|
|
|
25
27
|
function chartSpec(
|
|
26
28
|
series: ChartSeriesSpec[],
|
|
@@ -43,7 +45,8 @@ export function buildEmptyChartPreset(): ChartSpec {
|
|
|
43
45
|
/**
|
|
44
46
|
* `GAA/VOO`, `GAA / VOO`, and `CL=F - ES=F` are a ratio or a spread of two series.
|
|
45
47
|
* A slash that is the symbol stays one series (`EUR/USD`, `BTC/USD`), and so does
|
|
46
|
-
* a field written with a slash (`AAPL:EV/EBITDA`)
|
|
48
|
+
* a field written with a slash (`AAPL:EV/EBITDA`) and the symbol a catalog series
|
|
49
|
+
* takes after one (`CAP:short-volume:ratio/AAPL`). A comma-separated list stays a list.
|
|
47
50
|
*/
|
|
48
51
|
function derivedPair(expression: string): { series: ParsedSeriesExpression[]; formula: PairStudySelection } | null {
|
|
49
52
|
const trimmed = expression.trim();
|
|
@@ -58,6 +61,7 @@ function derivedPair(expression: string): { series: ParsedSeriesExpression[]; fo
|
|
|
58
61
|
const tight = /^([^/\s]+)\/([^/\s]+)$/.exec(trimmed);
|
|
59
62
|
if (!tight) return null;
|
|
60
63
|
const [leftToken, rightToken] = [tight[1]!, tight[2]!];
|
|
64
|
+
if (/^CAP:/i.test(leftToken) && !/^CAP:/i.test(rightToken)) return null;
|
|
61
65
|
const quote = rightToken.split(":")[0]!;
|
|
62
66
|
if (currencyPairSpelling(`${leftToken}/${quote}`) || dashedCoinPair(`${leftToken}/${quote}`)) return null;
|
|
63
67
|
const left = parseSeriesExpression(leftToken);
|
|
@@ -129,14 +133,54 @@ function appendChartFormula(spec: ChartSpec, expression: string): { spec: ChartS
|
|
|
129
133
|
};
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* The chart with a catalog suggestion added: one series, a registered
|
|
138
|
+
* series' lines where it asks for them, or a formula's legs and its study.
|
|
139
|
+
*/
|
|
133
140
|
export function appendCatalogSuggestion(
|
|
134
141
|
spec: ChartSpec,
|
|
135
142
|
suggestion: SeriesCatalogSuggestion,
|
|
136
143
|
): { spec: ChartSpec; series: ChartSeriesSpec } {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
if (suggestion.formula !== undefined) return appendChartFormula(spec, suggestion.formula);
|
|
145
|
+
if (suggestion.lines || suggestion.placement) {
|
|
146
|
+
return appendPlacedSeries(spec, suggestion.lines ?? [suggestion.expression!], {
|
|
147
|
+
name: suggestion.seriesName ?? suggestion.label,
|
|
148
|
+
...(suggestion.placement ? { placement: suggestion.placement } : {}),
|
|
149
|
+
...(suggestion.symbol ? { symbol: suggestion.symbol } : {}),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return appendChartSeries(spec, suggestion.expression);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The chart CAT opens for a registered series that asks where it is drawn or
|
|
157
|
+
* draws several lines: the ticker's price with the series placed as it asks,
|
|
158
|
+
* or the lines on their own.
|
|
159
|
+
*/
|
|
160
|
+
export function buildRegisteredSeriesChart(
|
|
161
|
+
series: { name: string; template: string; placement?: SeriesCatalogSuggestion["placement"]; lines?: ReadonlyArray<{ name: string; expression: string; style?: ChartSeriesSpec["style"] }> },
|
|
162
|
+
symbol?: string,
|
|
163
|
+
): ChartSpec {
|
|
164
|
+
const fill = (template: string) => symbol
|
|
165
|
+
? template.replaceAll("{ticker}", template.startsWith("CAP:") ? encodeURIComponent(symbol) : symbol)
|
|
166
|
+
: template;
|
|
167
|
+
const prefix = symbol ? `${symbol} · ` : "";
|
|
168
|
+
const lines = series.lines?.length
|
|
169
|
+
? series.lines.map((line) => {
|
|
170
|
+
const parsed = parseSeriesExpression(fill(line.expression));
|
|
171
|
+
if (!parsed) throw new Error(`"${line.expression}" is not a chart series.`);
|
|
172
|
+
return { ...parsed, label: `${prefix}${series.name} · ${line.name}`, ...(line.style ? { style: line.style } : {}) };
|
|
173
|
+
})
|
|
174
|
+
: [(() => {
|
|
175
|
+
const parsed = parseSeriesExpression(fill(series.template));
|
|
176
|
+
if (!parsed) throw new Error(`"${series.template}" is not a chart series.`);
|
|
177
|
+
return { ...parsed, label: `${prefix}${series.name}` };
|
|
178
|
+
})()];
|
|
179
|
+
const base = series.placement && symbol ? buildPriceChartPreset(symbol) : buildEmptyChartPreset();
|
|
180
|
+
return appendPlacedSeries(base, lines, {
|
|
181
|
+
name: series.name,
|
|
182
|
+
...(series.placement && symbol ? { placement: series.placement, symbol } : {}),
|
|
183
|
+
}).spec;
|
|
140
184
|
}
|
|
141
185
|
|
|
142
186
|
/**
|
|
@@ -157,9 +201,27 @@ export function buildCustomChartPreset(expression: string, fallbackSymbol?: stri
|
|
|
157
201
|
return formulaChartPreset(formula);
|
|
158
202
|
}
|
|
159
203
|
if (parsed.length === 0) return fallbackSymbol ? buildPriceChartPreset(fallbackSymbol) : buildEmptyChartPreset();
|
|
204
|
+
const registered = parsed.length === 1 ? placedRegisteredSeries(parsed[0]!) : null;
|
|
205
|
+
if (registered) return buildRegisteredSeriesChart(registered.series, registered.ticker);
|
|
160
206
|
return chartSpec(buildCustomSeries(parsed));
|
|
161
207
|
}
|
|
162
208
|
|
|
209
|
+
/**
|
|
210
|
+
* A registered series typed alone (`CAP:studies:rsi/AAPL`) that says where it is
|
|
211
|
+
* drawn or draws several lines charts as CAT opens it. Naming one line
|
|
212
|
+
* (`rsi~signal/AAPL`) charts that line alone.
|
|
213
|
+
*/
|
|
214
|
+
function placedRegisteredSeries(expression: ParsedSeriesExpression) {
|
|
215
|
+
if (expression.kind !== "capability" || expression.seriesId.split("/")[0]!.includes("~")) return null;
|
|
216
|
+
const found = getSharedRegistry()?.series?.findLoaded(expression.capabilityId, expression.seriesId);
|
|
217
|
+
if (!found || (!found.series.definition.placement && !found.series.definition.lines?.length)) return null;
|
|
218
|
+
const entry = seriesCatalogEntry(found.series);
|
|
219
|
+
return {
|
|
220
|
+
series: { name: entry.name, template: entry.expression, placement: entry.placement, lines: entry.lines },
|
|
221
|
+
...(found.ticker ? { ticker: found.ticker } : {}),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
163
225
|
export function buildPriceChartPreset(symbol: string): ChartSpec {
|
|
164
226
|
const normalized = normalizeInstrument(symbol, true);
|
|
165
227
|
if (!normalized) return buildEmptyChartPreset();
|
|
@@ -209,9 +271,15 @@ export function buildValuationChartPreset(
|
|
|
209
271
|
): ChartSpec {
|
|
210
272
|
const resolvedField = resolveChartFieldAlias(fieldId);
|
|
211
273
|
const normalized = symbols.map((symbol) => normalizeInstrument(symbol, true)).filter((entry): entry is NonNullable<typeof entry> => entry !== null).slice(0, MAX_CHART_COMPOSER_SERIES);
|
|
212
|
-
return chartSpec(normalized.map((instrument, index) =>
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
274
|
+
return chartSpec(normalized.map((instrument, index) => {
|
|
275
|
+
const series = buildSeriesSpec(
|
|
276
|
+
{ kind: "security", ...instrument, fieldId: resolvedField },
|
|
277
|
+
index,
|
|
278
|
+
{ style: normalized.length === 1 ? "line" : "columns", axis: "left" },
|
|
279
|
+
);
|
|
280
|
+
// Fiscal years: most US filers report no Q4 EPS, which charts do not
|
|
281
|
+
// reconstruct, so a quarterly trailing multiple has only its latest few
|
|
282
|
+
// quarters. Quarterly is the series' Period control away.
|
|
283
|
+
return series.source.kind === "security" ? { ...series, source: { ...series.source, period: "annual" } } : series;
|
|
284
|
+
}));
|
|
217
285
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type ChartSeriesCatalogItem,
|
|
8
8
|
} from "../../../capabilities";
|
|
9
9
|
import type { TimeSeriesFieldDefinition } from "../../../time-series/types";
|
|
10
|
-
import type { SeriesCatalogEntry } from "../../../series/types";
|
|
10
|
+
import type { SeriesCatalogEntry, SeriesPlacement } from "../../../series/types";
|
|
11
11
|
import {
|
|
12
12
|
canonicalExchange,
|
|
13
13
|
parsePublicTickerKey,
|
|
@@ -31,13 +31,20 @@ interface SeriesCatalogSuggestionText {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* One series to add,
|
|
35
|
-
* the chart with the study
|
|
34
|
+
* One series to add, the lines of a registered series that draws several, or
|
|
35
|
+
* a catalog formula (`42*HO=F - CL=F`): its legs join the chart with the study
|
|
36
|
+
* that weighs them.
|
|
36
37
|
*/
|
|
37
38
|
export type SeriesCatalogSuggestion = SeriesCatalogSuggestionText & (
|
|
38
|
-
| { expression: ParsedSeriesExpression; formula?: never }
|
|
39
|
-
| {
|
|
40
|
-
|
|
39
|
+
| { expression: ParsedSeriesExpression; formula?: never; lines?: never }
|
|
40
|
+
| { lines: ParsedSeriesExpression[]; expression?: never; formula?: never }
|
|
41
|
+
| { formula: string; expression?: never; lines?: never }
|
|
42
|
+
) & {
|
|
43
|
+
/** A registered series' own name, and where it asks to be drawn for the ticker it was filled in for. */
|
|
44
|
+
seriesName?: string;
|
|
45
|
+
placement?: SeriesPlacement;
|
|
46
|
+
symbol?: string;
|
|
47
|
+
};
|
|
41
48
|
|
|
42
49
|
export interface SeriesSearchAnalysis {
|
|
43
50
|
directInstrument: SeriesCatalogInstrument | null;
|
|
@@ -306,31 +313,44 @@ function registeredSeriesSuggestions(
|
|
|
306
313
|
if (!query.trim() || registered.length === 0) return [];
|
|
307
314
|
const instrument = analysis.directInstrument ?? defaultInstrument;
|
|
308
315
|
const tickerQuery = analysis.directInstrument ? analysis.metricQuery : query;
|
|
309
|
-
const hits: Array<{ entry: SeriesCatalogEntry; rank: number } & (
|
|
310
|
-
| { expression: ParsedSeriesExpression; formula?: never }
|
|
311
|
-
| {
|
|
316
|
+
const hits: Array<{ entry: SeriesCatalogEntry; rank: number; symbol?: string } & (
|
|
317
|
+
| { expression: ParsedSeriesExpression; formula?: never; lines?: never }
|
|
318
|
+
| { lines: ParsedSeriesExpression[]; expression?: never; formula?: never }
|
|
319
|
+
| { formula: string; expression?: never; lines?: never }
|
|
312
320
|
)> = [];
|
|
313
321
|
for (const entry of registered) {
|
|
314
322
|
let template = entry.expression;
|
|
315
323
|
let text = query;
|
|
324
|
+
let symbol: string | undefined;
|
|
325
|
+
const fill = (value: string) => symbol
|
|
326
|
+
? value.replaceAll("{ticker}", value.startsWith("CAP:") ? encodeURIComponent(symbol) : symbol)
|
|
327
|
+
: value;
|
|
316
328
|
if (entry.input) {
|
|
317
329
|
// Ticker fields are ranked against the security below; options and pairs need their own symbol.
|
|
318
330
|
if (entry.input !== "ticker" || /^\{ticker\}:[A-Za-z]/.test(template) || !tickerQuery.trim()) continue;
|
|
319
|
-
|
|
320
|
-
template =
|
|
331
|
+
symbol = publicTickerKey(instrument.symbol, instrument.exchange);
|
|
332
|
+
template = fill(template);
|
|
321
333
|
text = tickerQuery;
|
|
322
334
|
}
|
|
323
335
|
if (!matchesAliasQuery(text, entry.name, entry.expression, entry.id, entry.group ?? "", ...(entry.tags ?? []))) continue;
|
|
336
|
+
const prefix = symbol ? `${symbol} · ` : "";
|
|
337
|
+
if (entry.lines?.length) {
|
|
338
|
+
const lines = entry.lines.flatMap((line) => {
|
|
339
|
+
const parsed = parseSeriesExpression(fill(line.expression));
|
|
340
|
+
return parsed ? [{ ...parsed, label: `${prefix}${entry.name} · ${line.name}`, ...(line.style ? { style: line.style } : {}) }] : [];
|
|
341
|
+
});
|
|
342
|
+
if (lines.length === entry.lines.length) hits.push({ entry, rank: registeredMatchRank(entry, text), lines, ...(symbol ? { symbol } : {}) });
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
324
345
|
const parsed = parseSeriesExpression(template);
|
|
325
346
|
if (!parsed) {
|
|
326
347
|
if (!entry.input && catalogFormula(template)) hits.push({ entry, rank: registeredMatchRank(entry, text), formula: template });
|
|
327
348
|
continue;
|
|
328
349
|
}
|
|
329
|
-
|
|
330
|
-
hits.push({ entry, rank: registeredMatchRank(entry, text), expression: { ...parsed, label } });
|
|
350
|
+
hits.push({ entry, rank: registeredMatchRank(entry, text), expression: { ...parsed, label: `${prefix}${entry.name}` }, ...(symbol ? { symbol } : {}) });
|
|
331
351
|
}
|
|
332
352
|
hits.sort((left, right) => left.rank - right.rank || left.entry.name.length - right.entry.name.length);
|
|
333
|
-
return hits.map(({ entry, expression, formula }): SeriesCatalogSuggestion => {
|
|
353
|
+
return hits.map(({ entry, expression, lines, formula, symbol }): SeriesCatalogSuggestion => {
|
|
334
354
|
const description = [entry.group, entry.unit, entry.frequency].filter(Boolean).join(" · ");
|
|
335
355
|
const detail = entry.group ?? "Series";
|
|
336
356
|
if (formula !== undefined) {
|
|
@@ -338,12 +358,28 @@ function registeredSeriesSuggestions(
|
|
|
338
358
|
const formulaDescription = [formula, entry.unit, entry.frequency].filter(Boolean).join(" · ");
|
|
339
359
|
return { id: `formula:${formula}`, label: entry.name, description: formulaDescription, detail, formula };
|
|
340
360
|
}
|
|
361
|
+
const placed = {
|
|
362
|
+
seriesName: entry.name,
|
|
363
|
+
...(entry.placement ? { placement: entry.placement } : {}),
|
|
364
|
+
...(symbol ? { symbol } : {}),
|
|
365
|
+
};
|
|
366
|
+
if (lines) {
|
|
367
|
+
return {
|
|
368
|
+
id: `lines:${suggestionId(lines[0]!)}`,
|
|
369
|
+
label: `${symbol ? `${symbol} · ` : ""}${entry.name}`,
|
|
370
|
+
description: [entry.lines!.map((line) => line.name).join(", "), entry.group].filter(Boolean).join(" · "),
|
|
371
|
+
detail,
|
|
372
|
+
lines,
|
|
373
|
+
...placed,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
341
376
|
return {
|
|
342
377
|
id: suggestionId(expression),
|
|
343
378
|
label: expression.kind === "capability" ? expression.label ?? entry.name : `${entry.expression} · ${entry.name}`,
|
|
344
379
|
description,
|
|
345
380
|
detail,
|
|
346
381
|
expression,
|
|
382
|
+
...placed,
|
|
347
383
|
};
|
|
348
384
|
});
|
|
349
385
|
}
|
|
@@ -162,10 +162,14 @@ export function parseSeriesExpression(value: string): ParsedSeriesExpression | n
|
|
|
162
162
|
return { kind: "security", ...instrument, fieldId };
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
const SERIES_FORMS = "Use SYMBOL, SYMBOL:field, FUT:code, UST:maturity, FRED:series, GEO:series, or CAP:capability-id:series-id.";
|
|
166
|
+
|
|
165
167
|
export function parseChartExpression(value: string): ParsedSeriesExpression[] {
|
|
166
168
|
if (!value.trim()) return [];
|
|
167
|
-
|
|
168
|
-
const legs = value.split(/[;,\n]/);
|
|
169
|
+
// A list pasted with a stray separator (`BRK.B,SPY,`, `,SPY`, `A,,B`) has no series between them.
|
|
170
|
+
const legs = value.split(/[;,\n]/).filter((leg) => leg.trim());
|
|
171
|
+
// Separators alone name no series at all.
|
|
172
|
+
if (legs.length === 0) throw new Error(`Invalid chart series "${value.trim()}": no series between its separators. ${SERIES_FORMS}`);
|
|
169
173
|
if (legs.length > MAX_CHART_COMPOSER_SERIES) {
|
|
170
174
|
throw new Error(`Charts support up to ${MAX_CHART_COMPOSER_SERIES} base series.`);
|
|
171
175
|
}
|
|
@@ -173,10 +177,7 @@ export function parseChartExpression(value: string): ParsedSeriesExpression[] {
|
|
|
173
177
|
return legs.map((leg) => {
|
|
174
178
|
const parsed = parseSeriesExpression(leg);
|
|
175
179
|
if (parsed) return parsed;
|
|
176
|
-
|
|
177
|
-
throw new Error(
|
|
178
|
-
`Invalid chart series "${display}". Use SYMBOL, SYMBOL:field, FUT:code, UST:maturity, FRED:series, GEO:series, or CAP:capability-id:series-id.`,
|
|
179
|
-
);
|
|
180
|
+
throw new Error(`Invalid chart series "${leg.trim()}". ${SERIES_FORMS}`);
|
|
180
181
|
});
|
|
181
182
|
}
|
|
182
183
|
|
|
@@ -194,7 +195,8 @@ export function formatSeriesExpression(series: ChartSeriesSpec): string {
|
|
|
194
195
|
export function registeredSeriesName(source: { capabilityId: string; seriesId: string }): string | null {
|
|
195
196
|
const found = getSharedRegistry()?.series?.findLoaded(source.capabilityId, source.seriesId);
|
|
196
197
|
if (!found) return null;
|
|
197
|
-
|
|
198
|
+
const name = found.line ? `${found.series.definition.name} · ${found.line.name}` : found.series.definition.name;
|
|
199
|
+
return found.ticker ? `${found.ticker} ${name}` : name;
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
export function chartSeriesLabel(series: ChartSeriesSpec): string {
|