gloomberb 0.16.4 → 0.16.6
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 +5 -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 +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/central-bank-rates.ts +6 -1
- package/src/api-client/chat.ts +26 -0
- package/src/api-client/credit-boards.ts +2 -0
- package/src/api-client/data.ts +73 -3
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/europe-energy.ts +106 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +13 -1
- package/src/api-client/market-discovery.ts +13 -1
- package/src/api-client/normalizers.ts +32 -0
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/perps.ts +8 -0
- package/src/api-client/request.ts +9 -2
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/socket.ts +29 -0
- package/src/api-client/themes.ts +22 -1
- package/src/api-client/types.ts +78 -2
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +50 -2
- package/src/app/keybindings/actions.ts +12 -1
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
- package/src/app/runtime/desktop-deeplink.ts +10 -5
- package/src/app/runtime/startup.ts +1 -1
- package/src/app.tsx +6 -0
- package/src/architecture/core-builtin-allowlist.json +8 -26
- package/src/ask-gloom/pane-context.ts +114 -0
- package/src/ask-gloom/pane-request.ts +70 -0
- package/src/ask-gloom/pane-text.ts +201 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +19 -2
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/central-bank-events.ts +23 -0
- package/src/cli/command-options.ts +17 -5
- package/src/cli/commands/crypto-hints.ts +35 -2
- package/src/cli/commands/fred-series.ts +146 -0
- package/src/cli/commands/market.ts +501 -115
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +132 -26
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +317 -13
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +155 -18
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +76 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +7 -5
- package/src/cli/exit-codes.ts +8 -0
- package/src/cli/export-source.ts +58 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +483 -0
- package/src/cli/help.ts +10 -0
- package/src/cli/helpers.ts +2 -5
- package/src/cli/history-rows.ts +118 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +29 -9
- package/src/cli/known-gaps.ts +84 -0
- package/src/cli/listing-arg.ts +551 -97
- package/src/cli/not-a-ticker.ts +24 -9
- package/src/cli/pane-functions/access-gate.ts +13 -2
- package/src/cli/pane-functions/capabilities.ts +4 -3
- package/src/cli/pane-functions/catalog.ts +214 -40
- package/src/cli/pane-functions/data.ts +42 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +37 -8
- package/src/cli/pane-functions/freshness.ts +393 -49
- package/src/cli/pane-functions/function-help.ts +31 -15
- package/src/cli/pane-functions/headless.ts +98 -30
- package/src/cli/pane-functions/index.ts +101 -19
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +71 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +74 -19
- package/src/cli/pane-functions/screenshot.ts +250 -27
- package/src/cli/perpetual-contract.ts +60 -0
- package/src/cli/registry.ts +3 -1
- package/src/cli/report-tables.ts +26 -7
- package/src/cli/result.ts +45 -11
- package/src/cli/series-search.ts +111 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +27 -0
- package/src/cli/symbol-list.ts +154 -0
- package/src/cli/symbol-rows.ts +154 -0
- package/src/cli/ticker-resolution.ts +311 -27
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +14 -3
- package/src/components/chart/composite/composite-chart.tsx +71 -11
- package/src/components/chart/composite/crosshair-readout.tsx +150 -0
- package/src/components/chart/composite/downsample.ts +1 -1
- package/src/components/chart/composite/format.ts +29 -0
- package/src/components/chart/composite/interactions.ts +9 -2
- package/src/components/chart/composite/legend.tsx +100 -33
- package/src/components/chart/composite/panel-bitmap.ts +70 -35
- package/src/components/chart/composite/panel-labels.ts +18 -17
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +46 -21
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +50 -8
- package/src/components/chart/composite/scene.ts +2 -1
- package/src/components/chart/composite/time-scale.ts +26 -9
- package/src/components/chart/composite/types.ts +18 -0
- package/src/components/chart/composite/use-composite-viewport.ts +30 -2
- package/src/components/chart/native/raster/crosshair.ts +8 -3
- package/src/components/chart/native/raster/primitives.ts +85 -21
- package/src/components/chart/native/surface/manager.ts +33 -8
- package/src/components/chart/surface3d/chart.tsx +1 -1
- package/src/components/command-bar/action-runtime.ts +1 -1
- package/src/components/command-bar/commands/collection-list.ts +210 -0
- package/src/components/command-bar/commands/collection.ts +40 -1
- package/src/components/command-bar/commands/direct/index.ts +4 -0
- package/src/components/command-bar/commands/registry.ts +8 -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/plugin-install.ts +4 -4
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- 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/routing/actions.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +42 -17
- package/src/components/layout/detached-pane-shell.tsx +68 -39
- package/src/components/layout/floating-pane.tsx +10 -1
- package/src/components/layout/header.tsx +25 -5
- package/src/components/layout/missing-pane.tsx +3 -3
- package/src/components/layout/pane/capture-stamp.ts +41 -0
- package/src/components/layout/pane/capture-status.ts +12 -0
- package/src/components/layout/pane/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/keyboard.ts +3 -0
- package/src/components/layout/pane/footer/model.ts +41 -1
- package/src/components/layout/pane/header.tsx +50 -1
- package/src/components/layout/pane/index.tsx +21 -3
- package/src/components/layout/pane/sidebar.tsx +88 -21
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/cursor-occlusion.ts +2 -1
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +84 -65
- package/src/components/layout/shell/menu.ts +14 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +32 -10
- package/src/components/layout/shell/pane/ask.ts +131 -0
- package/src/components/layout/shell/pane/capture.ts +162 -0
- package/src/components/layout/shell/pane/layers.tsx +218 -50
- package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
- package/src/components/layout/shell/shortcuts.ts +21 -4
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +8 -1
- 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-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- 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/reader/article-reader.tsx +642 -0
- package/src/components/reader/article-text.ts +527 -0
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +43 -2
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -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 +18 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -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 +6 -1
- package/src/components/ui/query-bar.tsx +10 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/config/store/portfolio-as-of-column.ts +57 -0
- 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 +7555 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +65 -5
- package/src/i18n/ja.ts +65 -5
- package/src/i18n/ko.ts +65 -5
- package/src/i18n/zh-cn.ts +65 -5
- package/src/i18n/zh-tw.ts +65 -5
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/layout-marketplace/gallery.tsx +1 -1
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- 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 +84 -20
- package/src/market-data/market/session-close-note.ts +3 -2
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +5 -0
- package/src/market-data/quotes/metadata.ts +19 -24
- package/src/market-data/quotes/resolution.ts +5 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -0
- package/src/notifications/app-notifier.ts +17 -1
- package/src/notifications/notification-log.ts +180 -0
- package/src/plugins/auto-update-node.ts +2 -2
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/catalysts.ts +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/focus.ts +27 -0
- 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 +47 -11
- package/src/plugins/builtin/alerts/pane.tsx +27 -1
- 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 +8 -3
- package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/headless.ts +1 -1
- 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/headless.ts +88 -18
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/model.ts +41 -1
- package/src/plugins/builtin/awards/pane.tsx +22 -13
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/headless.ts +2 -2
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +1 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +49 -12
- package/src/plugins/builtin/cds/headless.ts +119 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +214 -32
- package/src/plugins/builtin/cds/pane.tsx +58 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
- package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
- package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
- package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -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-schema.ts +1 -1
- package/src/plugins/builtin/chart-composer/headless.ts +70 -5
- package/src/plugins/builtin/chart-composer/index.tsx +15 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
- 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/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +5 -1
- package/src/plugins/builtin/chat/content/footer.tsx +12 -0
- package/src/plugins/builtin/chat/content/index.tsx +89 -5
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
- package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
- package/src/plugins/builtin/chat/content/scroll.ts +127 -27
- package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
- package/src/plugins/builtin/chat/content/types.ts +1 -0
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/index.ts +123 -1
- package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
- package/src/plugins/builtin/chat/controller/messages.ts +7 -2
- package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
- package/src/plugins/builtin/chat/controller/send.ts +61 -1
- package/src/plugins/builtin/chat/controller/state.ts +8 -0
- package/src/plugins/builtin/chat/ghost-user.ts +20 -0
- package/src/plugins/builtin/chat/index.tsx +23 -5
- package/src/plugins/builtin/chat/layout.ts +78 -5
- package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
- package/src/plugins/builtin/chat/message/header.tsx +16 -4
- package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
- package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
- package/src/plugins/builtin/chat/message/render-state.ts +18 -2
- package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
- package/src/plugins/builtin/chat/message/types.ts +12 -0
- package/src/plugins/builtin/chat/reactions.ts +197 -0
- package/src/plugins/builtin/chat/share/flow.tsx +87 -0
- package/src/plugins/builtin/chat/share/targets.ts +27 -0
- package/src/plugins/builtin/chat/status-widget.tsx +6 -3
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
- package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
- package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
- package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
- package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -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 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
- package/src/plugins/builtin/cloud/plugin.tsx +19 -2
- package/src/plugins/builtin/cloud/team/model.ts +5 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/team/store.ts +8 -3
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +21 -7
- 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/headless.ts +97 -10
- package/src/plugins/builtin/company-kpis/model.ts +24 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +1 -1
- 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/cpi/headless.ts +3 -3
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
- package/src/plugins/builtin/credit-boards/client.ts +6 -2
- package/src/plugins/builtin/credit-boards/headless.ts +108 -31
- package/src/plugins/builtin/credit-boards/index.tsx +2 -0
- package/src/plugins/builtin/credit-boards/model.ts +11 -1
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-conditions/client.ts +12 -9
- package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
- package/src/plugins/builtin/credit-conditions/model.ts +19 -11
- package/src/plugins/builtin/credit-conditions/series.ts +16 -0
- package/src/plugins/builtin/credit-documents/headless.ts +33 -3
- 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/headless.ts +17 -11
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/client.ts +3 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/dividend-yield/types.ts +2 -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/headless.ts +12 -8
- 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/index.tsx +9 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/headless.ts +3 -3
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
- package/src/plugins/builtin/exposure/drivers.ts +13 -0
- package/src/plugins/builtin/exposure/headless.ts +205 -13
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/index.tsx +1 -0
- package/src/plugins/builtin/exposure/model.ts +23 -3
- package/src/plugins/builtin/exposure/pane.tsx +14 -12
- package/src/plugins/builtin/fear-greed/index.tsx +18 -10
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- 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 +71 -10
- 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/client.ts +63 -0
- package/src/plugins/builtin/fx-matrix/export.ts +2 -1
- package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
- 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 +58 -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 +101 -16
- 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/function-index.ts +2 -0
- package/src/plugins/builtin/help/index.tsx +31 -9
- 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 +55 -11
- 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 +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -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 +26 -9
- 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/ipo-calendar/headless.ts +1 -1
- package/src/plugins/builtin/iv-history/client.ts +20 -6
- package/src/plugins/builtin/iv-history/format.ts +9 -0
- package/src/plugins/builtin/iv-history/headless.ts +56 -21
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +143 -8
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +26 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
- package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- 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 +8 -3
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +6 -8
- package/src/plugins/builtin/mna/distress/headless.ts +4 -4
- package/src/plugins/builtin/mna/headless.ts +18 -6
- package/src/plugins/builtin/money-markets/headless.ts +5 -4
- 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/index.tsx +0 -2
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
- package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +3 -0
- package/src/plugins/builtin/options/view.tsx +1 -1
- 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 +4 -3
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +90 -16
- package/src/plugins/builtin/perps/equity-row.tsx +52 -17
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +47 -32
- package/src/plugins/builtin/perps/index.tsx +23 -4
- package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/open-market.ts +15 -0
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
- package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
- package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
- package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
- package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
- package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +63 -10
- package/src/plugins/builtin/power/headless.ts +77 -9
- package/src/plugins/builtin/power/index.tsx +28 -3
- package/src/plugins/builtin/power/model.ts +73 -2
- package/src/plugins/builtin/power/pane.tsx +37 -9
- package/src/plugins/builtin/power/prices-client.ts +139 -0
- package/src/plugins/builtin/power/prices-headless.ts +137 -0
- package/src/plugins/builtin/power/prices-model.ts +103 -0
- package/src/plugins/builtin/power/prices.tsx +179 -0
- package/src/plugins/builtin/rate-path/headless.ts +46 -18
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- 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/research/index.tsx +2 -0
- package/src/plugins/builtin/research-search/article.ts +65 -0
- package/src/plugins/builtin/research-search/document-view.tsx +33 -215
- package/src/plugins/builtin/research-search/model.ts +0 -9
- package/src/plugins/builtin/research-search/pane.tsx +41 -30
- package/src/plugins/builtin/research-search/snippet.ts +0 -29
- package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
- 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/headless.ts +25 -3
- package/src/plugins/builtin/sec/index.tsx +2 -1
- package/src/plugins/builtin/series-inventory.ts +93 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- 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/free-preview.ts +47 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +12 -1
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/volatility/options.ts +4 -1
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +2 -1
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- 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/headless.ts +43 -11
- package/src/plugins/builtin/supply-chain/model.ts +13 -0
- package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
- package/src/plugins/builtin/themes/headless.ts +74 -10
- package/src/plugins/builtin/themes/model.ts +71 -4
- package/src/plugins/builtin/themes/pane.tsx +22 -5
- 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/data-panes/returns-history.ts +114 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
- 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 +49 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +2 -1
- package/src/plugins/builtin/time-sales/index.tsx +2 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
- package/src/plugins/builtin/vol-surface/headless.ts +51 -17
- package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
- package/src/plugins/builtin/vol-surface/model.ts +39 -6
- package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
- package/src/plugins/builtin/vol-surface/stored.ts +63 -3
- package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
- package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
- package/src/plugins/builtin/world-venue-map/model.ts +56 -19
- package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
- 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/catalog-browser.ts +2 -1
- package/src/plugins/installer.ts +2 -2
- package/src/plugins/loader.ts +15 -0
- package/src/plugins/manager-node.ts +1 -1
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
- package/src/plugins/registry/host-actions.ts +11 -0
- package/src/plugins/registry/index.ts +89 -4
- package/src/portfolio/collection-name.ts +31 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/portfolio/valuation-basis.ts +79 -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 +33 -1
- package/src/react/key-repeat.ts +86 -0
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +144 -7
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +65 -2
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +4 -3
- package/src/renderers/browser/research-entry.ts +4 -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 +30 -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 +16 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
- package/src/renderers/dom/host/box.tsx +8 -0
- package/src/renderers/dom/host/chart-surface.tsx +33 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/scroll-box.tsx +32 -0
- package/src/renderers/dom/host/size-observer.ts +41 -0
- package/src/renderers/dom/host/sticky-scroll.ts +128 -0
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/surface-3d.tsx +19 -7
- package/src/renderers/dom/host/surface-fit.ts +406 -0
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +1 -0
- package/src/renderers/dom/styles.css +102 -5
- package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
- package/src/renderers/electrobun/bun/index.ts +3 -2
- package/src/renderers/electrobun/shared/protocol.ts +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +5 -3
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
- package/src/renderers/opentui/chart-surface.tsx +1 -0
- package/src/renderers/opentui/frame-capture.ts +33 -0
- package/src/renderers/opentui/host.tsx +10 -13
- package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
- package/src/renderers/opentui/pane-image/glyphs.json +1 -0
- package/src/renderers/opentui/pane-image/index.ts +107 -0
- package/src/renderers/opentui/pane-image/raster.ts +428 -0
- package/src/renderers/opentui/start.tsx +3 -3
- package/src/renderers/opentui/test-utils.tsx +3 -0
- package/src/renderers/opentui/ui-host.tsx +29 -1
- 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 +108 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +153 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/chat.ts +34 -0
- package/src/shares/dialog.tsx +295 -0
- package/src/shares/flow.tsx +56 -0
- package/src/shares/live.ts +14 -22
- package/src/shares/pane-image.ts +152 -0
- package/src/shares/personal-pane.ts +64 -0
- package/src/shares/portable-layout.ts +4 -2
- package/src/shares/prepare.ts +20 -0
- package/src/sources/gloomberb-cloud/index.ts +109 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
- package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/history-retention.ts +11 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/listing-target.ts +4 -0
- 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 +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/index.ts +14 -0
- package/src/sources/provider-router/search.ts +1 -0
- package/src/state/hooks/inline-tickers.ts +49 -11
- package/src/sync/core-contributors.ts +1 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/theme-context.tsx +15 -1
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +34 -1
- package/src/tickers/listing-name.ts +34 -0
- package/src/tickers/listing-venues.ts +132 -0
- package/src/tickers/open-target.ts +13 -4
- package/src/tickers/perpetual-listing.ts +151 -0
- package/src/tickers/prediction-listing.ts +26 -0
- package/src/tickers/search/index.ts +72 -11
- package/src/tickers/search/ranking.ts +98 -20
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/ticker-changes.ts +213 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/economic.ts +2 -6
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/ice-credit.ts +39 -0
- package/src/time-series/resolve.ts +211 -29
- package/src/time-series/studies.ts +1 -0
- package/src/time-series/types.ts +12 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +10 -2
- package/src/types/data-provider.ts +11 -0
- package/src/types/financials.ts +62 -1
- package/src/types/headless.ts +113 -0
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +52 -2
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker-changes.ts +26 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/context-menu.tsx +13 -1
- package/src/ui/host.tsx +57 -3
- package/src/ui/live-resize.ts +91 -0
- package/src/ui/live-stretch.ts +153 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/sticky-scroll.ts +7 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/central-banks.ts +76 -0
- package/src/utils/cli-output.ts +131 -15
- 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/currency-units.ts +11 -0
- package/src/utils/datetime-format.ts +27 -6
- 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 +439 -52
- package/src/utils/double-escape-close.ts +15 -1
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +143 -1
- package/src/utils/format.ts +35 -5
- package/src/utils/forward-dividend.ts +14 -0
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/fx-status.ts +6 -1
- package/src/utils/inline-content-tokenizer.ts +22 -3
- package/src/utils/market-capitalization.ts +8 -0
- package/src/utils/one-shot.ts +73 -0
- package/src/utils/options.ts +37 -8
- package/src/utils/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +63 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
} from "../../../components";
|
|
21
21
|
import { TickerBadgeList } from "../../../components/ticker/badge/list";
|
|
22
22
|
import { useShortcut } from "../../../react/input";
|
|
23
|
-
import { useInlineTickerOpener } from "../../../state/hooks/inline-tickers";
|
|
24
23
|
import { colors } from "../../../theme/colors";
|
|
25
24
|
import { Box, type InputRenderable, type ScrollBoxRenderable } from "../../../ui";
|
|
26
25
|
import { useDialog } from "../../../ui/dialog";
|
|
@@ -51,6 +50,8 @@ import {
|
|
|
51
50
|
} from "./data";
|
|
52
51
|
import { useDocumentFocusRequest } from "./focus-handoff";
|
|
53
52
|
import { SearchDocumentView } from "./document-view";
|
|
53
|
+
import { searchArticle } from "./article";
|
|
54
|
+
import { useOpenTickerChoice } from "../shared/ticker-choice";
|
|
54
55
|
import { SavedSearchesView } from "./saved-view";
|
|
55
56
|
import {
|
|
56
57
|
buildResultColumns,
|
|
@@ -97,7 +98,6 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
97
98
|
const openPlan = useCloudPlanAction();
|
|
98
99
|
const openUpgrade = useCloudUpgradeAction("srch-wall");
|
|
99
100
|
const dialog = useDialog();
|
|
100
|
-
const openTicker = useInlineTickerOpener();
|
|
101
101
|
|
|
102
102
|
const [seedQuery] = usePaneSettingValue("query", "");
|
|
103
103
|
const [mode, setMode] = usePluginPaneState<PaneMode>("mode", "results");
|
|
@@ -142,10 +142,11 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
142
142
|
const failure = useMemo<RequestFailure | null>(() => (
|
|
143
143
|
failedWith ? { message: errorMessage(failedWith), status: statusOf(failedWith) } : null
|
|
144
144
|
), [failedWith]);
|
|
145
|
-
const
|
|
146
|
-
() => (openHitId ? hits.
|
|
145
|
+
const openHitIndex = useMemo(
|
|
146
|
+
() => (openHitId ? hits.findIndex((hit) => hit.id === openHitId) : -1),
|
|
147
147
|
[hits, openHitId],
|
|
148
148
|
);
|
|
149
|
+
const openHit = openHitIndex >= 0 ? hits[openHitIndex]! : null;
|
|
149
150
|
|
|
150
151
|
const focusField = useCallback((field: Exclude<ActiveField, null>) => {
|
|
151
152
|
setActiveField(field);
|
|
@@ -326,6 +327,22 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
326
327
|
}, []);
|
|
327
328
|
|
|
328
329
|
const closeDetail = useCallback(() => setOpenHitId(null), [setOpenHitId]);
|
|
330
|
+
// n and p read on through the results without going back to the list.
|
|
331
|
+
const openAdjacent = useCallback((step: 1 | -1) => {
|
|
332
|
+
const next = hits[openHitIndex + step];
|
|
333
|
+
if (!next) return;
|
|
334
|
+
setSelectedHitId(next.id);
|
|
335
|
+
setOpenHitId(next.id);
|
|
336
|
+
}, [hits, openHitIndex, setOpenHitId, setSelectedHitId]);
|
|
337
|
+
const openNext = useMemo(
|
|
338
|
+
() => (openHitIndex >= 0 && openHitIndex < hits.length - 1 ? () => openAdjacent(1) : null),
|
|
339
|
+
[hits.length, openAdjacent, openHitIndex],
|
|
340
|
+
);
|
|
341
|
+
const openPrevious = useMemo(
|
|
342
|
+
() => (openHitIndex > 0 ? () => openAdjacent(-1) : null),
|
|
343
|
+
[openAdjacent, openHitIndex],
|
|
344
|
+
);
|
|
345
|
+
const openTickerChoice = useOpenTickerChoice();
|
|
329
346
|
|
|
330
347
|
// Opened straight onto a hit from the command bar, ahead of its own results.
|
|
331
348
|
const focusRequestedHit = useCallback((hit: CloudSearchHit) => {
|
|
@@ -402,11 +419,18 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
402
419
|
status,
|
|
403
420
|
]);
|
|
404
421
|
|
|
405
|
-
// The
|
|
422
|
+
// The tickers [t] offers: those the open document names, else the cursor
|
|
406
423
|
// row's (the table's cursor rests on the first row until one is chosen).
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
424
|
+
const documentTickers = useMemo(
|
|
425
|
+
() => (openHit && document ? searchArticle(document, openHit).tickers : null),
|
|
426
|
+
[document, openHit],
|
|
427
|
+
);
|
|
428
|
+
const hintTickers = useMemo(() => {
|
|
429
|
+
if (mode !== "results") return [];
|
|
430
|
+
if (documentTickers && documentTickers.length > 0) return documentTickers;
|
|
431
|
+
const ticker = (openHit ?? hits.find((hit) => hit.id === selectedHitId) ?? hits[0])?.ticker;
|
|
432
|
+
return ticker ? [ticker] : [];
|
|
433
|
+
}, [documentTickers, hits, mode, openHit, selectedHitId]);
|
|
410
434
|
const footerHints = useMemo<PaneHint[]>(() => {
|
|
411
435
|
// A wall or upsell replaces the results, so nothing there can be saved or opened.
|
|
412
436
|
if (signInRequired || verificationRequired || proRequired) return [];
|
|
@@ -419,14 +443,14 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
419
443
|
];
|
|
420
444
|
}
|
|
421
445
|
return [
|
|
422
|
-
...(
|
|
446
|
+
...(hintTickers.length > 0 ? [{ id: "ticker", key: "t", label: "icker", onPress: () => openTickerChoice(hintTickers) }] : []),
|
|
423
447
|
...(!openHit && trimmedQuery ? [{ id: "save", key: "Ctrl+S", label: "save search", onPress: saveCurrentSearch }] : []),
|
|
424
448
|
];
|
|
425
449
|
}, [
|
|
426
|
-
|
|
450
|
+
hintTickers,
|
|
427
451
|
mode,
|
|
428
452
|
openHit,
|
|
429
|
-
|
|
453
|
+
openTickerChoice,
|
|
430
454
|
proRequired,
|
|
431
455
|
removeSaved,
|
|
432
456
|
saved,
|
|
@@ -438,28 +462,12 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
438
462
|
verificationRequired,
|
|
439
463
|
]);
|
|
440
464
|
|
|
441
|
-
// The
|
|
442
|
-
// the
|
|
443
|
-
// section count is the kind of number the reader scrolls past anyway.
|
|
444
|
-
const documentIdentity = useMemo(() => {
|
|
445
|
-
if (!openHit) return null;
|
|
446
|
-
return [
|
|
447
|
-
formatHitDate(openHit.publishedAt),
|
|
448
|
-
// The type leads the footer when the document has no ticker, so repeating
|
|
449
|
-
// it here would say the same thing twice on one row.
|
|
450
|
-
openHit.ticker ? hitTypeLabel(openHit) : null,
|
|
451
|
-
].filter((part): part is string => !!part).join(" · ");
|
|
452
|
-
}, [openHit]);
|
|
453
|
-
|
|
465
|
+
// The reader's header names the open document, its source, date and
|
|
466
|
+
// tickers, so the footer keeps to what changes and what can be done.
|
|
454
467
|
useExternalLinkFooter({
|
|
455
468
|
registrationId: RESEARCH_SEARCH_PANE_ID,
|
|
456
469
|
focused,
|
|
457
470
|
url: openHit?.url ?? null,
|
|
458
|
-
source: documentIdentity,
|
|
459
|
-
// Never a fixed word: the row is led by whichever of these the document
|
|
460
|
-
// actually has, because a footer is for what changes as you move between
|
|
461
|
-
// documents, not for saying "document".
|
|
462
|
-
label: openHit ? (openHit.ticker || hitTypeLabel(openHit)) : "",
|
|
463
471
|
info: footerInfo,
|
|
464
472
|
hints: footerHints,
|
|
465
473
|
showHint: !!openHit?.url,
|
|
@@ -609,7 +617,7 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
609
617
|
focused={focused && activeField === null && !typePickerOpen}
|
|
610
618
|
detailOpen={!!openHit}
|
|
611
619
|
onBack={closeDetail}
|
|
612
|
-
|
|
620
|
+
// No title in the stack bar: the reader sets the headline at the top of the text.
|
|
613
621
|
detailContent={openHit ? (
|
|
614
622
|
<SearchDocumentView
|
|
615
623
|
hit={openHit}
|
|
@@ -619,7 +627,10 @@ export function ResearchSearchPane({ focused, paneId, width, height }: PaneProps
|
|
|
619
627
|
? "This document is part of Gloom Cloud Pro."
|
|
620
628
|
: documentFailure?.message ?? null}
|
|
621
629
|
width={width}
|
|
630
|
+
height={Math.max(1, height - tabRows - 1)}
|
|
622
631
|
focused={focused && activeField === null && !typePickerOpen}
|
|
632
|
+
onNext={openNext}
|
|
633
|
+
onPrevious={openPrevious}
|
|
623
634
|
/>
|
|
624
635
|
) : (
|
|
625
636
|
<Box flexGrow={1} />
|
|
@@ -103,32 +103,3 @@ export function snippetMatchTerms(snippet: string): string[] {
|
|
|
103
103
|
export function truncateSegments(segments: SnippetSegment[], width: number): SnippetSegment[] {
|
|
104
104
|
return truncateTextSegments(segments, width, (ellipsis) => ({ text: ellipsis, marked: false }));
|
|
105
105
|
}
|
|
106
|
-
|
|
107
|
-
/** Splits plain text on the matched terms so a full chunk can show the same highlights. */
|
|
108
|
-
export function highlightTerms(text: string, terms: readonly string[]): SnippetSegment[] {
|
|
109
|
-
const usable = terms.filter((term) => term.length > 0);
|
|
110
|
-
if (usable.length === 0) return [{ text, marked: false }];
|
|
111
|
-
|
|
112
|
-
const pattern = new RegExp(
|
|
113
|
-
`(${usable.map(escapeRegExp).sort((a, b) => b.length - a.length).join("|")})`,
|
|
114
|
-
"gi",
|
|
115
|
-
);
|
|
116
|
-
const segments: SnippetSegment[] = [];
|
|
117
|
-
let cursor = 0;
|
|
118
|
-
for (let match = pattern.exec(text); match; match = pattern.exec(text)) {
|
|
119
|
-
// A zero-width match would loop forever on the same index.
|
|
120
|
-
if (match[0].length === 0) {
|
|
121
|
-
pattern.lastIndex += 1;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
pushSegment(segments, text.slice(cursor, match.index), false);
|
|
125
|
-
pushSegment(segments, match[0], true);
|
|
126
|
-
cursor = match.index + match[0].length;
|
|
127
|
-
}
|
|
128
|
-
pushSegment(segments, text.slice(cursor), false);
|
|
129
|
-
return segments.filter((segment) => segment.text.length > 0);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function escapeRegExp(value: string): string {
|
|
133
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
134
|
-
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { RevenueBreakdownView } from "../../../api-client/revenue-breakdown";
|
|
2
|
-
import type { HeadlessPaneDefinition } from "../../../types/plugin";
|
|
2
|
+
import type { HeadlessPaneColumn, HeadlessPaneDefinition } from "../../../types/plugin";
|
|
3
3
|
import { fetchRevenueBreakdown } from "./client";
|
|
4
|
-
import { quarterLabel, reportedSpan } from "./model";
|
|
4
|
+
import { growthPercent, quarterLabel, reportedSpan, revenueAmount, sharePercent } from "./model";
|
|
5
5
|
import { SEC_FILINGS } from "../shared/report-freshness";
|
|
6
6
|
import { resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
7
7
|
|
|
8
|
+
/** Amounts compact and shares and growth in percent, as the pane prints them (15.97B, 83.7%, +10.8%); exports keep the whole number. */
|
|
9
|
+
const number = (format: (value: number | null) => string) => (value: unknown) => format(typeof value === "number" ? value : null);
|
|
10
|
+
const amountColumn = (key: string, header: string): HeadlessPaneColumn => ({ key, header, align: "right", textFormat: number(revenueAmount) });
|
|
11
|
+
|
|
8
12
|
export const revenueBreakdownHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
9
13
|
shape: "bundle",
|
|
10
14
|
freshness: { ...SEC_FILINGS, basis: "10-Q and 10-K filings" },
|
|
@@ -17,10 +21,10 @@ export const revenueBreakdownHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
17
21
|
aliases: ["SEG"],
|
|
18
22
|
dataRequirements: ["Gloom Cloud revenue breakdowns from 10-Q and 10-K XBRL"],
|
|
19
23
|
limitations: [
|
|
20
|
-
"US filers only; 20-F filers report no quarterly breakdown",
|
|
21
|
-
"Rows are the members that add up to reported revenue; subtotals are dropped",
|
|
22
|
-
"Fiscal quarters; Q4 is the fiscal year less nine months",
|
|
23
|
-
"Free accounts get the two largest rows",
|
|
24
|
+
"US filers only; 20-F filers report no quarterly breakdown.",
|
|
25
|
+
"Rows are the members that add up to reported revenue; subtotals are dropped.",
|
|
26
|
+
"Fiscal quarters; Q4 is the fiscal year less nine months.",
|
|
27
|
+
"Free accounts get the two largest rows.",
|
|
24
28
|
],
|
|
25
29
|
},
|
|
26
30
|
options: [
|
|
@@ -48,6 +52,13 @@ export const revenueBreakdownHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
48
52
|
sections: [
|
|
49
53
|
{
|
|
50
54
|
title: `Quarterly revenue by ${data.view}`,
|
|
55
|
+
columns: [
|
|
56
|
+
{ key: data.view, header: data.view[0]!.toUpperCase() + data.view.slice(1) },
|
|
57
|
+
...data.periods.map((period) => amountColumn(quarterLabel(period), quarterLabel(period))),
|
|
58
|
+
amountColumn("ttm", "TTM"),
|
|
59
|
+
{ key: "share", header: "Share", align: "right", textFormat: number(sharePercent) },
|
|
60
|
+
{ key: "yoy", header: "YoY", align: "right", textFormat: number(growthPercent) },
|
|
61
|
+
],
|
|
51
62
|
rows: data.rows.map((row) => ({
|
|
52
63
|
[data.view]: row.label,
|
|
53
64
|
...Object.fromEntries(data.periods.map((period, index) => [quarterLabel(period), row.values[index]])),
|
|
@@ -58,6 +69,7 @@ export const revenueBreakdownHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
58
69
|
},
|
|
59
70
|
{
|
|
60
71
|
title: "Total revenue",
|
|
72
|
+
columns: [{ key: "quarter", header: "Quarter" }, { key: "end", header: "End" }, amountColumn("revenue", "Revenue")],
|
|
61
73
|
rows: data.periods.map((period, index) => ({
|
|
62
74
|
quarter: quarterLabel(period),
|
|
63
75
|
end: period.end,
|
|
@@ -13,30 +13,38 @@ export interface SeasonalityHistory {
|
|
|
13
13
|
fetchedAt: number;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/** Monthly closes for the Returns and Overlay tabs, daily closes for Weekdays. */
|
|
17
|
+
export type SeasonalityCadence = "monthly" | "daily";
|
|
18
|
+
|
|
16
19
|
const CANCELLED = "Seasonality history load was cancelled";
|
|
17
|
-
/** The cadence
|
|
18
|
-
export const SEASONALITY_HISTORY_RESOLUTION: ManualChartResolution = "1mo";
|
|
20
|
+
/** The cadence each tab reads, and so the cadence a screenshot of it captures. */
|
|
21
|
+
export const SEASONALITY_HISTORY_RESOLUTION: Record<SeasonalityCadence, ManualChartResolution> = { monthly: "1mo", daily: "1d" };
|
|
22
|
+
/** Daily history is served to five years; a longer request can come back as weekly bars. */
|
|
23
|
+
const BUFFER_RANGE = { monthly: "ALL", daily: "5Y" } as const;
|
|
19
24
|
|
|
20
25
|
/**
|
|
21
26
|
* Every month on record: the lookback is cut in the model, so changing it never
|
|
22
27
|
* refetches. Monthly bars, because daily history is only served to 5Y where
|
|
23
28
|
* provider support is not known yet, and a longer daily request comes back as
|
|
24
|
-
* Monday-stamped weeks that file a week's close under the wrong month.
|
|
29
|
+
* Monday-stamped weeks that file a week's close under the wrong month. The
|
|
30
|
+
* Weekdays tab needs sessions, so it reads those five years of daily bars.
|
|
25
31
|
*/
|
|
26
32
|
export async function loadSeasonalityHistory(
|
|
27
|
-
request: { instrument: InstrumentRef; signal?: AbortSignal; forceRefresh?: boolean },
|
|
33
|
+
request: { instrument: InstrumentRef; cadence?: SeasonalityCadence; signal?: AbortSignal; forceRefresh?: boolean },
|
|
28
34
|
marketData?: DataProvider,
|
|
29
35
|
): Promise<SeasonalityHistory> {
|
|
30
36
|
if (request.signal?.aborted) throw abortError(CANCELLED);
|
|
37
|
+
const cadence = request.cadence ?? "monthly";
|
|
31
38
|
const now = Date.now();
|
|
32
39
|
const coordinator = marketData ? new MarketDataCoordinator(marketData) : getSharedMarketDataCoordinator();
|
|
33
40
|
try {
|
|
34
41
|
if (!coordinator) throw new Error("Market data coordinator unavailable");
|
|
35
|
-
const entry = await abortable(coordinator.loadChart({ instrument: request.instrument, bufferRange:
|
|
36
|
-
granularity: "resolution", resolution: SEASONALITY_HISTORY_RESOLUTION }, { forceRefresh: request.forceRefresh }), request.signal, CANCELLED);
|
|
42
|
+
const entry = await abortable(coordinator.loadChart({ instrument: request.instrument, bufferRange: BUFFER_RANGE[cadence],
|
|
43
|
+
granularity: "resolution", resolution: SEASONALITY_HISTORY_RESOLUTION[cadence] }, { forceRefresh: request.forceRefresh }), request.signal, CANCELLED);
|
|
37
44
|
const history = resolveEntryValue(entry) ?? [];
|
|
38
45
|
return { history, stale: !!entry.error || (entry.staleAt != null && entry.staleAt <= now),
|
|
39
|
-
error: entry.error?.message ?? (history.length ? null : "Monthly price history unavailable
|
|
46
|
+
error: entry.error?.message ?? (history.length ? null : `${cadence === "daily" ? "Daily" : "Monthly"} price history unavailable`),
|
|
47
|
+
fetchedAt: entry.fetchedAt ?? now };
|
|
40
48
|
} catch (error) {
|
|
41
49
|
if (request.signal?.aborted || (error instanceof Error && error.name === "AbortError")) throw abortError(CANCELLED);
|
|
42
50
|
return { history: [], stale: false, error: errorMessage(error), fetchedAt: now };
|
|
@@ -1,38 +1,62 @@
|
|
|
1
1
|
import type { HeadlessPaneDefinition } from "../../../types/plugin";
|
|
2
2
|
import { resolveHeadlessInstrument } from "../shared/headless-market-data";
|
|
3
3
|
import { loadSeasonalityHistory } from "./client";
|
|
4
|
-
import { MONTH_LABELS, projectSeasonality } from "./model";
|
|
4
|
+
import { MONTH_LABELS, projectSeasonality, projectWeekdays, TURN_OF_MONTH_LABELS } from "./model";
|
|
5
5
|
|
|
6
|
-
const percent = (value: unknown) => typeof value === "number" ? `${(value * 100).toFixed(
|
|
6
|
+
const percent = (digits: number) => (value: unknown) => typeof value === "number" ? `${(value * 100).toFixed(digits)}%` : "--";
|
|
7
|
+
const statColumns = (digits: number, countHeader: string) => [{ key: "mean", header: "Avg", format: percent(digits) },
|
|
8
|
+
{ key: "median", header: "Median", format: percent(digits) }, { key: "hitRate", header: "Up", format: percent(1) }, { key: "count", header: countHeader }];
|
|
7
9
|
|
|
8
10
|
export const seasonalityHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
9
11
|
shape: "bundle", argument: { kind: "ticker", description: "Ticker" },
|
|
10
12
|
// Dated by the month of its last monthly close.
|
|
11
13
|
freshness: { status: "not-a-feed", basis: "monthly closes", maxAgeMinutes: 45 * 24 * 60 },
|
|
12
14
|
describe: (args) => `SEAS ${args.symbols[0] ?? ""}`,
|
|
13
|
-
discovery: { screenshotReadiness: "live-dom", limitations: ["Local-price closes; dividends and FX are excluded."
|
|
15
|
+
discovery: { screenshotReadiness: "live-dom", limitations: ["Local-price closes; dividends and FX are excluded.",
|
|
16
|
+
"Weekdays reads daily closes, which are served for the last five years only."] },
|
|
14
17
|
options: [
|
|
15
|
-
{ key: "tab", type: "enum", values: [{ value: "returns" }, { value: "overlay" }], defaultValue: "returns",
|
|
18
|
+
{ key: "tab", type: "enum", values: [{ value: "returns" }, { value: "overlay" }, { value: "weekdays" }], defaultValue: "returns",
|
|
16
19
|
description: "Initial view", pluginState: { pluginId: "ticker-research", key: "activeTabId" } },
|
|
17
|
-
{ key: "lookbackYears", type: "integer", minimum: 1, maximum: 30, defaultValue: 10, description: "Calendar years, the current one included" },
|
|
20
|
+
{ key: "lookbackYears", type: "integer", minimum: 1, maximum: 30, defaultValue: 10, description: "Calendar years, the current one included; Weekdays covers every daily close served" },
|
|
18
21
|
],
|
|
19
22
|
async load(args, ctx) {
|
|
20
23
|
const instrument = await resolveHeadlessInstrument(ctx, args.symbols[0]!);
|
|
21
|
-
const
|
|
24
|
+
const weekdays = args.options.tab === "weekdays";
|
|
25
|
+
const history = await loadSeasonalityHistory({ instrument, cadence: weekdays ? "daily" : "monthly", signal: ctx.signal }, ctx.marketData);
|
|
22
26
|
ctx.signal.throwIfAborted();
|
|
27
|
+
const common = { errors: history.error ? [history.error] : [] };
|
|
28
|
+
if (weekdays) {
|
|
29
|
+
const model = projectWeekdays(history.history, { symbol: instrument.symbol, exchange: instrument.exchange, fetchedAt: history.fetchedAt });
|
|
30
|
+
const present = model.start != null;
|
|
31
|
+
return {
|
|
32
|
+
sections: [
|
|
33
|
+
{ title: "By weekday", columns: [{ key: "day", header: "Day" }, ...statColumns(3, "Sessions")],
|
|
34
|
+
rows: model.weekdays },
|
|
35
|
+
{ title: "Turn of month", columns: [{ key: "day", header: "Session" }, ...statColumns(3, "Sessions")],
|
|
36
|
+
rows: [...model.turnOfMonth.map((stat, index) => ({ day: TURN_OF_MONTH_LABELS[index], ...stat })),
|
|
37
|
+
{ day: "Turn of month", ...model.turnWindow }, { day: "Other days", ...model.otherDays }] },
|
|
38
|
+
],
|
|
39
|
+
complete: !history.stale && !history.error && present,
|
|
40
|
+
unavailableSymbols: present ? [] : [instrument.symbol],
|
|
41
|
+
...common,
|
|
42
|
+
// Dated by its last session's close.
|
|
43
|
+
freshness: { basis: "daily closes", maxAgeMinutes: 14 * 24 * 60 },
|
|
44
|
+
metadata: { unit: "decimal return, local-price session close to close", start: model.start, asOf: model.asOf, stale: history.stale,
|
|
45
|
+
fetchedAt: history.fetchedAt, methodology: "docs/research-data.md#seasonality" },
|
|
46
|
+
};
|
|
47
|
+
}
|
|
23
48
|
const model = projectSeasonality(history.history, { symbol: instrument.symbol, lookbackYears: Number(args.options.lookbackYears) || 10 });
|
|
24
|
-
const monthColumns = MONTH_LABELS.map((label, month) => ({ key: `m${month}`, header: label, format: percent }));
|
|
49
|
+
const monthColumns = MONTH_LABELS.map((label, month) => ({ key: `m${month}`, header: label, format: percent(1) }));
|
|
25
50
|
return {
|
|
26
51
|
sections: [
|
|
27
|
-
{ title: "By month", columns: [{ key: "month", header: "Month" },
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{ title: "Monthly returns", columns: [{ key: "year", header: "Year" }, ...monthColumns, { key: "total", header: "Year", format: percent }],
|
|
52
|
+
{ title: "By month", columns: [{ key: "month", header: "Month" }, ...statColumns(1, "Years")],
|
|
53
|
+
rows: model.months.map((stat) => ({ ...stat, month: MONTH_LABELS[stat.month] })) },
|
|
54
|
+
{ title: "Monthly returns", columns: [{ key: "year", header: "Year" }, ...monthColumns, { key: "total", header: "Year", format: percent(1) }],
|
|
31
55
|
rows: model.years.map((year) => ({ year: year.year, total: year.total, ...Object.fromEntries(year.months.map((value, month) => [`m${month}`, value])) })) },
|
|
32
56
|
],
|
|
33
57
|
complete: !history.stale && !history.error && model.years.length > 0,
|
|
34
58
|
unavailableSymbols: model.years.length ? [] : [instrument.symbol],
|
|
35
|
-
|
|
59
|
+
...common,
|
|
36
60
|
metadata: { unit: "decimal return, local-price close to close", asOf: model.asOf?.toISOString() ?? null, stale: history.stale,
|
|
37
61
|
fetchedAt: history.fetchedAt, averagePath: model.averagePath, methodology: "docs/research-data.md#seasonality" },
|
|
38
62
|
};
|
|
@@ -14,7 +14,7 @@ export const seasonalityModule: PluginModule = {
|
|
|
14
14
|
}],
|
|
15
15
|
paneTemplates: [{ ...createTickerSurfacePaneTemplate({
|
|
16
16
|
id: "seasonality-pane", paneId: "seasonality", label: "Seasonality",
|
|
17
|
-
description: "Monthly returns by year, each month's average and hit rate,
|
|
18
|
-
keywords: ["seas", "seasonality", "seasonal", "monthly returns", "calendar"], shortcut: "SEAS", publicShare: true,
|
|
17
|
+
description: "Monthly returns by year, each month's average and hit rate, every year's path on one calendar, and returns by weekday and turn of month.",
|
|
18
|
+
keywords: ["seas", "seasonality", "seasonal", "monthly returns", "calendar", "weekday", "day of week", "turn of month"], shortcut: "SEAS", publicShare: true,
|
|
19
19
|
}), headless: seasonalityHeadless }],
|
|
20
20
|
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { latestRegularSessionClose } from "../../../market-data/market/freshness";
|
|
2
|
+
import { listingSuffixExchange, tickerHasListingSuffix } from "../../../sources/listing-symbols";
|
|
3
|
+
import { calendarBarStart } from "../../../time-series/chart-data";
|
|
1
4
|
import type { PricePoint } from "../../../types/financials";
|
|
5
|
+
import { isRoundTheClockCoin } from "../../../utils/crypto-pair";
|
|
2
6
|
|
|
3
7
|
export const MONTH_LABELS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] as const;
|
|
4
8
|
/** Year overlays share one calendar; 2000 is a leap year, so Feb 29 has a place. */
|
|
@@ -122,3 +126,118 @@ export function projectSeasonality(history: readonly PricePoint[], options: { sy
|
|
|
122
126
|
|
|
123
127
|
return { symbol: options.symbol, years, months, paths, averagePath, asOf: last.date };
|
|
124
128
|
}
|
|
129
|
+
|
|
130
|
+
/** Monday first; a Saturday or Sunday row appears only for a venue that trades then. */
|
|
131
|
+
const WEEKDAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] as const;
|
|
132
|
+
/** The turn of the month: a month's last session, then the next month's first three. */
|
|
133
|
+
export const TURN_OF_MONTH_LABELS = ["Last day", "Day 1", "Day 2", "Day 3"] as const;
|
|
134
|
+
|
|
135
|
+
export interface DailyReturnStat {
|
|
136
|
+
mean: number | null;
|
|
137
|
+
median: number | null;
|
|
138
|
+
/** Share of sessions that closed up. */
|
|
139
|
+
hitRate: number | null;
|
|
140
|
+
count: number;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface WeekdayModel {
|
|
144
|
+
symbol: string;
|
|
145
|
+
/**
|
|
146
|
+
* Each day of the week that held a session, in the venue's week: Monday
|
|
147
|
+
* first, or Sunday first where Sunday sessions outnumber Friday ones.
|
|
148
|
+
*/
|
|
149
|
+
weekdays: (DailyReturnStat & { day: (typeof WEEKDAY_LABELS)[number] })[];
|
|
150
|
+
/** In TURN_OF_MONTH_LABELS order. */
|
|
151
|
+
turnOfMonth: DailyReturnStat[];
|
|
152
|
+
/** The four turn-of-month sessions pooled, against every other session whose place in its month is known. */
|
|
153
|
+
turnWindow: DailyReturnStat;
|
|
154
|
+
otherDays: DailyReturnStat;
|
|
155
|
+
/** Session dates of the first and last return counted, "YYYY-MM-DD". */
|
|
156
|
+
start: string | null;
|
|
157
|
+
asOf: string | null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function returnStat(values: number[]): DailyReturnStat {
|
|
161
|
+
return { count: values.length, mean: mean(values), median: median(values),
|
|
162
|
+
hitRate: values.length ? values.filter((value) => value > 0).length / values.length : null };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Closing auctions and late prints settle after the bell, as price history allows for. */
|
|
166
|
+
const SESSION_SETTLE_MS = 30 * 60_000;
|
|
167
|
+
|
|
168
|
+
/** The venue a listing's sessions follow: a bare symbol without a listing suffix is a US listing. */
|
|
169
|
+
function sessionVenue(symbol: string, exchange: string | undefined): string | undefined {
|
|
170
|
+
if (exchange || isRoundTheClockCoin(symbol)) return exchange;
|
|
171
|
+
return listingSuffixExchange(symbol) ?? (tickerHasListingSuffix(symbol) ? undefined : "NYSE");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* The latest session date whose close had settled by `time`, on the venue's
|
|
176
|
+
* calendar; for a coin, whose daily bar is a UTC day, the UTC day before.
|
|
177
|
+
* Null where the venue's sessions are unknown.
|
|
178
|
+
*/
|
|
179
|
+
function settledSessionDate(symbol: string, venue: string | undefined, time: number): string | null {
|
|
180
|
+
if (isRoundTheClockCoin(symbol, venue)) return new Date(time - SESSION_SETTLE_MS - DAY_MS).toISOString().slice(0, 10);
|
|
181
|
+
return venue ? latestRegularSessionClose(venue, time - SESSION_SETTLE_MS)?.date ?? null : null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Close-to-close returns of daily bars, each filed under its session date: the
|
|
186
|
+
* venue's date for a bar stamped at its open or local midnight, the label for a
|
|
187
|
+
* date-only bar at UTC midnight. Every session served counts; there is no
|
|
188
|
+
* lookback. A session still trading when the history was fetched is left out.
|
|
189
|
+
* A Monday after a holiday Friday runs from Thursday's close. A session's
|
|
190
|
+
* place in its month is only known once the session before the month started
|
|
191
|
+
* is in the history, and the latest session may still turn out to be its
|
|
192
|
+
* month's last, so those stay out of the turn-of-month split (but not out of
|
|
193
|
+
* the weekdays).
|
|
194
|
+
*/
|
|
195
|
+
export function projectWeekdays(history: readonly PricePoint[], options: { symbol: string; exchange?: string; fetchedAt: number }): WeekdayModel {
|
|
196
|
+
const venue = sessionVenue(options.symbol, options.exchange);
|
|
197
|
+
const settled = settledSessionDate(options.symbol, venue, options.fetchedAt);
|
|
198
|
+
const sessions = new Map<string, number>();
|
|
199
|
+
for (const point of history
|
|
200
|
+
.map((entry) => ({ time: new Date(entry.date).getTime(), close: entry.close }))
|
|
201
|
+
.filter((entry) => Number.isFinite(entry.close) && entry.close > 0 && Number.isFinite(entry.time))
|
|
202
|
+
.sort((left, right) => left.time - right.time)) {
|
|
203
|
+
const day = calendarBarStart(point.time, "1d", venue);
|
|
204
|
+
if (settled == null || day <= settled) sessions.set(day, point.close);
|
|
205
|
+
}
|
|
206
|
+
const days = [...sessions.entries()].sort(([left], [right]) => left.localeCompare(right));
|
|
207
|
+
const empty = returnStat([]);
|
|
208
|
+
// Weekly or monthly bars would file a week's move under one weekday.
|
|
209
|
+
if (days.length < 2 || medianGapDays(days.map(([day]) => ({ date: new Date(`${day}T00:00:00Z`) }))) > 4) {
|
|
210
|
+
return { symbol: options.symbol, weekdays: [], turnOfMonth: TURN_OF_MONTH_LABELS.map(() => empty),
|
|
211
|
+
turnWindow: empty, otherDays: empty, start: null, asOf: null };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const weekdays: number[][] = WEEKDAY_LABELS.map(() => []);
|
|
215
|
+
const turnOfMonth: number[][] = TURN_OF_MONTH_LABELS.map(() => []);
|
|
216
|
+
const other: number[] = [];
|
|
217
|
+
/** The session's place in its month, 1 for the first; null until a month's start is seen. */
|
|
218
|
+
let position: number | null = null;
|
|
219
|
+
for (let index = 1; index < days.length; index++) {
|
|
220
|
+
const [day, close] = days[index]!;
|
|
221
|
+
const month = day.slice(0, 7);
|
|
222
|
+
position = month !== days[index - 1]![0].slice(0, 7) ? 1 : position == null ? null : position + 1;
|
|
223
|
+
const value = close / days[index - 1]![1] - 1;
|
|
224
|
+
weekdays[(new Date(`${day}T00:00:00Z`).getUTCDay() + 6) % 7]!.push(value);
|
|
225
|
+
const next = days[index + 1]?.[0];
|
|
226
|
+
if (next != null && next.slice(0, 7) !== month) turnOfMonth[0]!.push(value);
|
|
227
|
+
else if (position != null && position <= 3) turnOfMonth[position]!.push(value);
|
|
228
|
+
else if (next != null && position != null) other.push(value);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const stats = weekdays.map((values, day) => ({ day: WEEKDAY_LABELS[day]!, ...returnStat(values) }));
|
|
232
|
+
// A Sunday-to-Thursday venue (Tadawul, Boursa Kuwait) starts its week on Sunday.
|
|
233
|
+
const ordered = stats[6]!.count > stats[4]!.count ? [stats[6]!, ...stats.slice(0, 6)] : stats;
|
|
234
|
+
return {
|
|
235
|
+
symbol: options.symbol,
|
|
236
|
+
weekdays: ordered.filter((stat) => stat.count > 0),
|
|
237
|
+
turnOfMonth: turnOfMonth.map(returnStat),
|
|
238
|
+
turnWindow: returnStat(turnOfMonth.flat()),
|
|
239
|
+
otherDays: returnStat(other),
|
|
240
|
+
start: days[1]![0],
|
|
241
|
+
asOf: days.at(-1)![0],
|
|
242
|
+
};
|
|
243
|
+
}
|