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
|
@@ -1,17 +1,29 @@
|
|
|
1
|
+
import type { EarningsTiming } from "../../../api-client/earnings";
|
|
1
2
|
import type { PricePoint } from "../../../types/financials";
|
|
2
3
|
import { zonedDateTimeParts } from "../../../utils/zoned-date-time";
|
|
3
|
-
import { MACRO_EVENT_KINDS, type MacroEventKind, type MacroRelease } from "./releases";
|
|
4
|
+
import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, type MacroEventKind, type MacroRelease } from "./releases";
|
|
4
5
|
|
|
5
6
|
const DAY_MS = 86_400_000;
|
|
6
7
|
/** Longest calendar gap between two closes that is still one session apart: Thursday to Monday over a Friday holiday. */
|
|
7
8
|
const MAX_SESSION_GAP_DAYS = 4;
|
|
8
9
|
|
|
10
|
+
/** One of the ticker's own earnings reports, reduced to what dates its reaction. */
|
|
11
|
+
export interface MacroDayEarningsReport {
|
|
12
|
+
/** Report date, New York. */
|
|
13
|
+
date: string;
|
|
14
|
+
timing: EarningsTiming | null;
|
|
15
|
+
/** The session the earnings history measures the report's move on, once the report is priced. */
|
|
16
|
+
reactionSession?: string | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
export interface MacroDayEvent {
|
|
10
20
|
kind: MacroEventKind;
|
|
11
21
|
/** Release day, New York date. */
|
|
12
22
|
date: string;
|
|
13
23
|
/** The session whose close carries the reaction: the release day, or the next session when the market was shut. */
|
|
14
24
|
session: string;
|
|
25
|
+
/** The session is also the reaction session of the ticker's own earnings report: the move is the report's, not the release's. */
|
|
26
|
+
earnings: boolean;
|
|
15
27
|
/** Close before the release to the session's close. */
|
|
16
28
|
move: number;
|
|
17
29
|
/** |move| over the normal day's average |move|. */
|
|
@@ -32,15 +44,22 @@ export interface MacroDayModel {
|
|
|
32
44
|
symbol: string;
|
|
33
45
|
/** Newest first. */
|
|
34
46
|
events: MacroDayEvent[];
|
|
47
|
+
/** Without the earnings days. */
|
|
35
48
|
byKind: Record<MacroEventKind, MacroDayStats>;
|
|
36
|
-
/** Every release day of the three kinds together; a day with two releases counts once. */
|
|
49
|
+
/** Every release day of the three kinds together, without the earnings days; a day with two releases counts once. */
|
|
37
50
|
allEvents: MacroDayStats;
|
|
38
|
-
/**
|
|
51
|
+
/** Release days that are the ticker's earnings reaction, which no other figure counts; a day with two releases counts once. */
|
|
52
|
+
earnings: MacroDayStats;
|
|
53
|
+
/** Sessions with no release of the three kinds, and none of the earnings days among them. */
|
|
39
54
|
normal: MacroDayStats;
|
|
40
55
|
start: string | null;
|
|
41
56
|
asOf: string | null;
|
|
42
57
|
}
|
|
43
58
|
|
|
59
|
+
/** The release's name, with the earnings marker on a day that is the ticker's own report reaction. */
|
|
60
|
+
export const macroDayEventLabel = (event: Pick<MacroDayEvent, "kind" | "earnings">) =>
|
|
61
|
+
event.earnings ? `${MACRO_EVENT_LABELS[event.kind]} (earnings)` : MACRO_EVENT_LABELS[event.kind];
|
|
62
|
+
|
|
44
63
|
/** Daily labels at UTC midnight name that date; any other stamp reads in New York. */
|
|
45
64
|
function sessionDate(time: number): string {
|
|
46
65
|
if (time % DAY_MS === 0) return new Date(time).toISOString().slice(0, 10);
|
|
@@ -59,6 +78,27 @@ function stats(moves: number[], normalAbs: number | null): MacroDayStats {
|
|
|
59
78
|
multiple: normalAbs ? meanAbs / normalAbs : null };
|
|
60
79
|
}
|
|
61
80
|
|
|
81
|
+
/**
|
|
82
|
+
* The sessions whose close carries a report's reaction, on the history's own
|
|
83
|
+
* calendar. A priced report names its session in the earnings history. Any
|
|
84
|
+
* other reads as the earnings history reads it: before the open and during
|
|
85
|
+
* the session react the same day, after the close the next session. A report
|
|
86
|
+
* with no time on record may have reacted on either, so both count.
|
|
87
|
+
*/
|
|
88
|
+
function earningsReactionSessions(reports: readonly MacroDayEarningsReport[], sessions: readonly string[]): Set<string> {
|
|
89
|
+
const reacted = new Set<string>();
|
|
90
|
+
for (const report of reports) {
|
|
91
|
+
if (report.reactionSession) { reacted.add(report.reactionSession); continue; }
|
|
92
|
+
const sameDay = report.timing === "bmo" || report.timing === "dmh";
|
|
93
|
+
const afterClose = report.timing === "amc";
|
|
94
|
+
const same = sessions.find((date) => date >= report.date);
|
|
95
|
+
const next = sessions.find((date) => date > report.date);
|
|
96
|
+
if (!afterClose && same) reacted.add(same);
|
|
97
|
+
if (!sameDay && next) reacted.add(next);
|
|
98
|
+
}
|
|
99
|
+
return reacted;
|
|
100
|
+
}
|
|
101
|
+
|
|
62
102
|
/**
|
|
63
103
|
* Close to close on the release day: 8:30 ET releases land before the open
|
|
64
104
|
* and 14:00 FOMC statements before the close, so the release day's close
|
|
@@ -66,7 +106,9 @@ function stats(moves: number[], normalAbs: number | null): MacroDayStats {
|
|
|
66
106
|
* is read on the next session, from the close before the release. A release
|
|
67
107
|
* whose close-to-close would span a gap in the history is left out rather
|
|
68
108
|
* than read across it. A lone missing bar on the release day itself cannot
|
|
69
|
-
* be told from a holiday and is read on the next session.
|
|
109
|
+
* be told from a holiday and is read on the next session. A release whose
|
|
110
|
+
* session is also the reaction to the ticker's own earnings is kept, marked,
|
|
111
|
+
* and counted in neither the release figures nor the normal days.
|
|
70
112
|
*/
|
|
71
113
|
export function projectMacroDays(history: readonly PricePoint[], options: {
|
|
72
114
|
symbol: string;
|
|
@@ -74,6 +116,8 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
|
|
|
74
116
|
releases: readonly MacroRelease[];
|
|
75
117
|
/** The release list's last covered day. */
|
|
76
118
|
coveredThrough: string;
|
|
119
|
+
/** The ticker's own earnings reports; none when they could not be read. */
|
|
120
|
+
earnings?: readonly MacroDayEarningsReport[];
|
|
77
121
|
}): MacroDayModel {
|
|
78
122
|
const { coveredThrough } = options;
|
|
79
123
|
const byDate = new Map<string, number>();
|
|
@@ -86,7 +130,7 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
|
|
|
86
130
|
const last = sessions.at(-1) ?? null;
|
|
87
131
|
const empty = (): MacroDayStats => stats([], null);
|
|
88
132
|
if (!last) return { symbol: options.symbol, events: [], byKind: { cpi: empty(), jobs: empty(), fomc: empty() },
|
|
89
|
-
allEvents: empty(), normal: empty(), start: null, asOf: null };
|
|
133
|
+
allEvents: empty(), earnings: empty(), normal: empty(), start: null, asOf: null };
|
|
90
134
|
|
|
91
135
|
// Sessions after the published lists end may be unlisted release days, so they are left out of both sides.
|
|
92
136
|
const end = last < coveredThrough ? last : coveredThrough;
|
|
@@ -105,7 +149,7 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
|
|
|
105
149
|
}
|
|
106
150
|
|
|
107
151
|
const reactionSessions = new Set<string>();
|
|
108
|
-
const found: Omit<MacroDayEvent, "multiple">[] = [];
|
|
152
|
+
const found: Omit<MacroDayEvent, "multiple" | "earnings">[] = [];
|
|
109
153
|
for (const release of options.releases) {
|
|
110
154
|
if (release.date <= start || release.date > end || !isWeekday(release.date)) continue;
|
|
111
155
|
const at = sessions.findIndex((date) => date >= release.date);
|
|
@@ -120,12 +164,14 @@ export function projectMacroDays(history: readonly PricePoint[], options: {
|
|
|
120
164
|
const normalMoves = [...moves].filter(([date]) => !reactionSessions.has(date)).map(([, move]) => move);
|
|
121
165
|
const normal = stats(normalMoves, null);
|
|
122
166
|
const normalAbs = normal.meanAbs;
|
|
123
|
-
const
|
|
167
|
+
const reacted = earningsReactionSessions(options.earnings ?? [], sessions);
|
|
168
|
+
const events = found.map((event) => ({ ...event, earnings: reacted.has(event.session), multiple: normalAbs ? Math.abs(event.move) / normalAbs : null }))
|
|
124
169
|
.sort((left, right) => right.date.localeCompare(left.date) || left.kind.localeCompare(right.kind));
|
|
125
170
|
const byKind = Object.fromEntries(MACRO_EVENT_KINDS.map((kind) =>
|
|
126
|
-
[kind, stats(events.filter((event) => event.kind === kind).map((event) => event.move), normalAbs)])) as Record<MacroEventKind, MacroDayStats>;
|
|
127
|
-
const
|
|
128
|
-
return { symbol: options.symbol, events, byKind, allEvents
|
|
171
|
+
[kind, stats(events.filter((event) => event.kind === kind && !event.earnings).map((event) => event.move), normalAbs)])) as Record<MacroEventKind, MacroDayStats>;
|
|
172
|
+
const sessionMoves = (flagged: boolean) => [...reactionSessions].filter((session) => reacted.has(session) === flagged).map((session) => moves.get(session)!);
|
|
173
|
+
return { symbol: options.symbol, events, byKind, allEvents: stats(sessionMoves(false), normalAbs), earnings: stats(sessionMoves(true), normalAbs),
|
|
174
|
+
normal, start, asOf: end };
|
|
129
175
|
}
|
|
130
176
|
|
|
131
177
|
/**
|
|
@@ -9,8 +9,8 @@ import { useAutoRefresh } from "../../../react/auto-refresh";
|
|
|
9
9
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
10
10
|
import type { PaneProps } from "../../../types/plugin";
|
|
11
11
|
import { Box } from "../../../ui";
|
|
12
|
-
import { loadMacroDayHistory, loadMacroReleases } from "./client";
|
|
13
|
-
import { projectMacroDays, type MacroDayEvent, type MacroDayModel } from "./model";
|
|
12
|
+
import { loadMacroDayEarnings, loadMacroDayHistory, loadMacroReleases, macroDayEarningsNotice } from "./client";
|
|
13
|
+
import { macroDayEventLabel, projectMacroDays, type MacroDayEvent, type MacroDayModel } from "./model";
|
|
14
14
|
import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, staleMacroReleasesNotice, type MacroEventKind } from "./releases";
|
|
15
15
|
|
|
16
16
|
export const LOOKBACK_OPTIONS = [{ value: "1", label: "1Y" }, { value: "2", label: "2Y" }, { value: "3", label: "3Y" }, { value: "5", label: "5Y" }];
|
|
@@ -23,14 +23,22 @@ function pct(value: number | null | undefined, signed = true): string {
|
|
|
23
23
|
}
|
|
24
24
|
const times = (value: number | null | undefined) => value == null ? "--" : `${value.toFixed(1)}x`;
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const EARNINGS_MARK = "earnings";
|
|
27
|
+
const DATE: DataTableColumn = { id: "date", label: "Date", width: 19, align: "left" };
|
|
28
|
+
const MOVE: DataTableColumn[] = [
|
|
29
29
|
{ id: "move", label: "Move", width: 9, align: "right" },
|
|
30
30
|
{ id: "multiple", label: "vs Normal", width: 10, align: "right" },
|
|
31
31
|
];
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* With every release listed, the release's name, widened to take the earnings marker where a row has one. With one
|
|
35
|
+
* selected, a column only for the marker: every row would repeat the name.
|
|
36
|
+
*/
|
|
37
|
+
function columnsFor(release: string, rows: readonly MacroDayEvent[]): DataTableColumn[] {
|
|
38
|
+
const marked = rows.some((event) => event.earnings);
|
|
39
|
+
if (release === "all") return [DATE, { id: "release", label: "Release", width: marked ? 15 : 8, align: "left" }, ...MOVE];
|
|
40
|
+
return marked ? [DATE, { id: "release", label: "Note", width: EARNINGS_MARK.length, align: "left" }, ...MOVE] : [DATE, ...MOVE];
|
|
41
|
+
}
|
|
34
42
|
|
|
35
43
|
function figures(model: MacroDayModel, release: string): StatItem[] {
|
|
36
44
|
const normal: StatItem = { id: "normal", label: "Normal day", value: pct(model.normal.meanAbs, false), detail: "avg |move|" };
|
|
@@ -39,7 +47,8 @@ function figures(model: MacroDayModel, release: string): StatItem[] {
|
|
|
39
47
|
const stats = model.byKind[kind];
|
|
40
48
|
return { id: kind, label: `${MACRO_EVENT_LABELS[kind]} day`, value: pct(stats.meanAbs, false),
|
|
41
49
|
detail: stats.count ? `${times(stats.multiple)} normal` : undefined };
|
|
42
|
-
}),
|
|
50
|
+
}), ...(model.earnings.count ? [{ id: "earnings", label: "Earnings day", value: pct(model.earnings.meanAbs, false),
|
|
51
|
+
detail: `${times(model.earnings.multiple)} normal` }] : []), normal];
|
|
43
52
|
}
|
|
44
53
|
const stats = model.byKind[release as MacroEventKind];
|
|
45
54
|
const tone = (value: number | null) => value == null ? undefined : value >= 0 ? "positive" as const : "negative" as const;
|
|
@@ -64,12 +73,10 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
|
|
|
64
73
|
const loader = useCallback(async (force: boolean) => {
|
|
65
74
|
controller.current?.abort();
|
|
66
75
|
controller.current = new AbortController();
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
loadMacroReleases({ force }),
|
|
70
|
-
]);
|
|
76
|
+
const request = { instrument: instrument!, forceRefresh: force, signal: controller.current.signal };
|
|
77
|
+
const [snapshot, releases, earnings] = await Promise.all([loadMacroDayHistory(request), loadMacroReleases({ force }), loadMacroDayEarnings(request)]);
|
|
71
78
|
if (!snapshot.history.length && snapshot.error) throw new Error(snapshot.error);
|
|
72
|
-
return { ...snapshot, releases };
|
|
79
|
+
return { ...snapshot, releases, earnings };
|
|
73
80
|
}, [instrumentKey]);
|
|
74
81
|
const history = useAsyncResource(instrument ? loader : null);
|
|
75
82
|
useEffect(() => () => controller.current?.abort(), [loader]);
|
|
@@ -77,26 +84,29 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
|
|
|
77
84
|
usePaneRefreshKey(() => { void history.reload(); }, { focused });
|
|
78
85
|
|
|
79
86
|
const model = useMemo(() => history.data ? projectMacroDays(history.data.history, { symbol: symbol ?? "", lookbackYears: Number(lookback) || 5,
|
|
80
|
-
releases: history.data.releases.releases, coveredThrough: history.data.releases.coveredThrough }) : null,
|
|
87
|
+
releases: history.data.releases.releases, coveredThrough: history.data.releases.coveredThrough, earnings: history.data.earnings.reports }) : null,
|
|
88
|
+
[history.data, lookback, symbol]);
|
|
81
89
|
const releasesNotice = history.data ? staleMacroReleasesNotice(history.data.releases) : null;
|
|
90
|
+
const earningsNotice = history.data ? macroDayEarningsNotice(history.data.earnings) : null;
|
|
82
91
|
const rows = useMemo(() => model ? model.events.filter((event) => release === "all" || event.kind === release) : [], [model, release]);
|
|
83
92
|
const stats = useMemo(() => model?.events.length ? figures(model, release) : [], [model, release]);
|
|
93
|
+
const columns = useMemo(() => columnsFor(release, rows), [release, rows]);
|
|
84
94
|
|
|
85
95
|
usePaneNoticeFooter({ registrationId: "macro-day-notices", focused,
|
|
86
|
-
notices: [...new Set([identityError, history.error, history.data?.error, releasesNotice].filter((value): value is string => !!value))] });
|
|
96
|
+
notices: [...new Set([identityError, history.error, history.data?.error, releasesNotice, earningsNotice].filter((value): value is string => !!value))] });
|
|
87
97
|
usePaneFooter("macro-day", () => ({ info: [
|
|
88
98
|
...(history.loading ? [{ id: "loading", parts: [{ text: "loading history", tone: "muted" as const }] }] : []),
|
|
89
|
-
...(history.data?.stale ? [{ id: "stale", parts: [{ text: "stale history", tone: "warning" as const }] }] : []),
|
|
99
|
+
...(history.data?.stale || history.data?.earnings.stale ? [{ id: "stale", parts: [{ text: "stale history", tone: "warning" as const }] }] : []),
|
|
90
100
|
...(model?.asOf ? [{ id: "date", parts: [{ text: `daily closes ${model.start} to ${model.asOf}`, tone: "muted" as const }] }] : []),
|
|
91
|
-
] }), [history.loading, history.data?.stale, model?.start, model?.asOf]);
|
|
101
|
+
] }), [history.loading, history.data?.stale, history.data?.earnings.stale, model?.start, model?.asOf]);
|
|
92
102
|
|
|
93
103
|
const renderCell = useCallback((event: MacroDayEvent, column: DataTableColumn): DataTableCell => {
|
|
94
104
|
if (column.id === "date") return { text: event.session === event.date ? event.date : `${event.date} → ${event.session.slice(5)}`, value: event.date };
|
|
95
|
-
if (column.id === "release") return { text:
|
|
105
|
+
if (column.id === "release") return { text: release === "all" ? macroDayEventLabel(event) : event.earnings ? EARNINGS_MARK : "" };
|
|
96
106
|
if (column.id === "move") return { text: pct(event.move), value: event.move * 100,
|
|
97
107
|
color: event.move > 0 ? colors.positive : event.move < 0 ? colors.negative : undefined };
|
|
98
108
|
return { text: times(event.multiple), value: event.multiple };
|
|
99
|
-
}, [colors]);
|
|
109
|
+
}, [colors, release]);
|
|
100
110
|
|
|
101
111
|
const contentHeight = Math.max(4, height - 1 - statGridRows(stats, width));
|
|
102
112
|
const key = (event: MacroDayEvent) => `${event.kind}:${event.date}`;
|
|
@@ -110,7 +120,7 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
|
|
|
110
120
|
error={!model ? history.error ?? identityError ?? null : null} empty={!!model && !model.events.length}>
|
|
111
121
|
{model ? <>
|
|
112
122
|
<StatGrid items={stats} width={width} />
|
|
113
|
-
<DataTableView<MacroDayEvent> focused={focused} columns={
|
|
123
|
+
<DataTableView<MacroDayEvent> focused={focused} columns={columns} items={rows} rootWidth={width} rootHeight={contentHeight}
|
|
114
124
|
getItemKey={key} emptyStateTitle="No release days." sortColumnId={null} sortDirection="desc" selectedTextOverridesCellColor
|
|
115
125
|
selection={{ kind: "id", selectedId: selectedRow, getId: key, onChange: (id) => setSelectedRow(id) }}
|
|
116
126
|
getExportMetadata={() => [["symbol", model.symbol], ["from", model.start ?? ""], ["to", model.asOf ?? ""],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HeadlessPaneColumn, HeadlessPaneDefinition } from "../../../types/plugin";
|
|
2
2
|
import { formatCompact, formatPercentRaw } from "../../../utils/format";
|
|
3
|
-
import { MARKET_HEATMAP_REQUEST_COUNT, MARKET_HEATMAP_UNIVERSES, fetchMarketHeatmap, type MarketHeatmapUniverseId } from "./data";
|
|
3
|
+
import { MARKET_HEATMAP_REQUEST_COUNT, MARKET_HEATMAP_UNIVERSES, fetchMarketHeatmap, type MarketHeatmapBoard, type MarketHeatmapUniverseId } from "./data";
|
|
4
4
|
import { heatmapMove, summarizeHeatmapGroups, type HeatmapGroupBy, type HeatmapGroupSummary } from "./model";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -39,6 +39,20 @@ function noMoveNotice(symbols: readonly string[], names: number): string {
|
|
|
39
39
|
return `${symbols.length} of ${names} names have no move yet and count toward size only: ${shown}${rest}.`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* When the board's figures are from, and whose sessions they follow: outside
|
|
44
|
+
* the regular session the tiles are the completed session's, so the board is
|
|
45
|
+
* as of that session's close (its date, from a server that does not send the
|
|
46
|
+
* close), not when the snapshot was put together; while it trades, the
|
|
47
|
+
* snapshot time.
|
|
48
|
+
*/
|
|
49
|
+
function boardObservation(board: Pick<MarketHeatmapBoard, "fetchedAt" | "regularSessionDate" | "regularSessionClosedAt">) {
|
|
50
|
+
const closedAt = board.regularSessionDate ? board.regularSessionClosedAt : null;
|
|
51
|
+
const asOf = typeof closedAt === "number" && closedAt > 0 ? new Date(closedAt).toISOString()
|
|
52
|
+
: board.regularSessionDate || new Date(board.fetchedAt).toISOString();
|
|
53
|
+
return { asOf, sessionExchange: "NYSE" };
|
|
54
|
+
}
|
|
55
|
+
|
|
42
56
|
function projectRow(summary: HeatmapGroupSummary, groupBy: HeatmapGroupBy, whole = false) {
|
|
43
57
|
return {
|
|
44
58
|
group: whole ? "All" : summary.group ?? (summary.sector ? "No industry" : groupBy === "industry" ? "Unclassified" : "No sector"),
|
|
@@ -86,12 +100,13 @@ export const marketHeatmapHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
86
100
|
aliases: ["HM", "heatmap"],
|
|
87
101
|
dataRequirements: ["Gloom Cloud market heatmap snapshot"],
|
|
88
102
|
limitations: [
|
|
89
|
-
"The snapshot the pane starts from, refreshed about once a minute; the pane's live-streamed colors are not in the report",
|
|
90
|
-
"Moves are weighted by market cap (net assets for ETFs), not by the pane's square-root tile area",
|
|
103
|
+
"The snapshot the pane starts from, refreshed about once a minute; the pane's live-streamed colors are not in the report.",
|
|
104
|
+
"Moves are weighted by market cap (net assets for ETFs), not by the pane's square-root tile area.",
|
|
91
105
|
],
|
|
92
106
|
},
|
|
93
107
|
// A board snapshot refreshed on a schedule, not a feed; the pane streams on top of it, the report does not.
|
|
94
|
-
|
|
108
|
+
// A completed session it names only by its date is a US trading day.
|
|
109
|
+
freshness: { status: "delayed", tradingDayMarket: "US" },
|
|
95
110
|
describe: (args) => {
|
|
96
111
|
const universe = MARKET_HEATMAP_UNIVERSES.find((entry) => entry.id === args.options.universe)?.label ?? "US Stocks";
|
|
97
112
|
return args.options.universe === "us-etf" ? `Market Heatmap | ${universe}` : `Market Heatmap | ${universe} by ${String(args.options.group)}`;
|
|
@@ -117,7 +132,7 @@ export const marketHeatmapHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
117
132
|
metadata: {
|
|
118
133
|
universe,
|
|
119
134
|
groupBy: flat ? null : groupBy,
|
|
120
|
-
|
|
135
|
+
...boardObservation(result),
|
|
121
136
|
stale: result.stale === true,
|
|
122
137
|
session: result.session ?? null,
|
|
123
138
|
regularSessionDate: result.regularSessionDate ?? null,
|
|
@@ -743,6 +743,12 @@ export const marketHeatmapPlugin: GloomPlugin = {
|
|
|
743
743
|
name: "Market Heatmap",
|
|
744
744
|
icon: "H",
|
|
745
745
|
component: MarketHeatmapPane,
|
|
746
|
+
// Portfolio tiles disclose position values; watchlist and market tiles do not.
|
|
747
|
+
personalData: ({ settings, paneState }) => (
|
|
748
|
+
settings.universe === PORTFOLIO_HEATMAP_TAB
|
|
749
|
+
&& paneState[HEATMAP_COLLECTION_KIND_STATE_KEY] === "portfolio"
|
|
750
|
+
? "holdings" : null
|
|
751
|
+
),
|
|
746
752
|
headless: marketHeatmapHeadless,
|
|
747
753
|
defaultPosition: "right",
|
|
748
754
|
defaultMode: "floating",
|
|
@@ -77,18 +77,24 @@ const twoDigits = (value: number) => String(value).padStart(2, "0");
|
|
|
77
77
|
/** A New York calendar day ("2026-10-09") as the footer names it: "Oct 9". */
|
|
78
78
|
const dayLabel = (day: string) => formatShortDate(day, { year: false, utc: true, fallback: day });
|
|
79
79
|
|
|
80
|
+
const isTimestamp = (value: number | null | undefined): value is number =>
|
|
81
|
+
typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
82
|
+
|
|
80
83
|
/**
|
|
81
84
|
* What a market board covers and when it is from, for the footer: how many of
|
|
82
85
|
* the largest names it holds, the completed regular session it shows outside
|
|
83
|
-
* that session,
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
86
|
+
* that session, the time its figures are as of, in New York time, dated when
|
|
87
|
+
* that day is not the session's (or, while the session trades, today's), and
|
|
88
|
+
* when this client last checked, which is a separate figure. A board of a
|
|
89
|
+
* completed session is as of that session's close (`regularSessionClosedAt`);
|
|
90
|
+
* otherwise, or from a server that does not say, the time is when the server
|
|
91
|
+
* put the snapshot together. A footer narrower than `maxWidth` loses the check
|
|
92
|
+
* first, then that time, then the session; after a failed refresh (`failed`)
|
|
93
|
+
* the age of the last good check outlasts the time. Null when not even the
|
|
94
|
+
* count fits.
|
|
89
95
|
*/
|
|
90
96
|
export function heatmapBoardCaption(
|
|
91
|
-
board: { topCount: number; fetchedAt: number; regularSessionDate?: string | null },
|
|
97
|
+
board: { topCount: number; fetchedAt: number; regularSessionDate?: string | null; regularSessionClosedAt?: number | null },
|
|
92
98
|
{ now, checked = null, failed = false, maxWidth = Number.POSITIVE_INFINITY }:
|
|
93
99
|
{ now: number; checked?: string | null; failed?: boolean; maxWidth?: number },
|
|
94
100
|
): string | null {
|
|
@@ -96,11 +102,13 @@ export function heatmapBoardCaption(
|
|
|
96
102
|
// Display order; `rank` is the order they give way in, highest first.
|
|
97
103
|
const parts: Array<{ text: string; rank: number }> = [{ text: `top ${board.topCount}`, rank: 0 }];
|
|
98
104
|
if (sessionDate) parts.push({ text: `${dayLabel(sessionDate)} session`, rank: 1 });
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
const closedAt = sessionDate && isTimestamp(board.regularSessionClosedAt) ? board.regularSessionClosedAt : null;
|
|
106
|
+
const time = closedAt ?? (isTimestamp(board.fetchedAt) ? board.fetchedAt : null);
|
|
107
|
+
if (time != null) {
|
|
108
|
+
const { hour, minute } = zonedDateTimeParts(time, NEW_YORK);
|
|
101
109
|
const clock = `${twoDigits(hour)}:${twoDigits(minute)} ET`;
|
|
102
|
-
const day = zonedDateKey(
|
|
103
|
-
const text =
|
|
110
|
+
const day = zonedDateKey(time, NEW_YORK);
|
|
111
|
+
const text = `${closedAt != null ? "as of" : "snapshot"} ${day === (sessionDate ?? zonedDateKey(now, NEW_YORK)) ? clock : `${dayLabel(day)} ${clock}`}`;
|
|
104
112
|
parts.push({ text, rank: failed ? 3 : 2 });
|
|
105
113
|
}
|
|
106
114
|
if (checked) parts.push({ text: `checked ${checked}`, rank: failed ? 2 : 3 });
|
|
@@ -5,7 +5,7 @@ import type { ColumnConfig } from "../../../types/config";
|
|
|
5
5
|
import type { TickerFinancials } from "../../../types/financials";
|
|
6
6
|
import {
|
|
7
7
|
getRegularSessionMoveDisplay,
|
|
8
|
-
|
|
8
|
+
getTradedSessionMoveDisplay,
|
|
9
9
|
type ActiveQuoteDisplay,
|
|
10
10
|
type ExtendedSession,
|
|
11
11
|
} from "../../../market-data/market/status";
|
|
@@ -227,7 +227,7 @@ export function buildPortfolioHeatmapAssets({
|
|
|
227
227
|
// Colored like the market boards: an open extended session's move, else the regular session's.
|
|
228
228
|
const display: (ActiveQuoteDisplay & { session?: ExtendedSession }) | null = regularSession
|
|
229
229
|
? getRegularSessionMoveDisplay(quote)
|
|
230
|
-
:
|
|
230
|
+
: getTradedSessionMoveDisplay(quote);
|
|
231
231
|
const price = display != null && Number.isFinite(display.price) ? display.price : null;
|
|
232
232
|
const size = positiveNumber(getSortValue(sizeColumn, ticker, snapshot, context));
|
|
233
233
|
const hasChange = display?.changePercent != null && Number.isFinite(display.changePercent);
|
|
@@ -5,18 +5,19 @@ import type {
|
|
|
5
5
|
CloudSessionMoversSide,
|
|
6
6
|
} from "../../../api-client/market-movers";
|
|
7
7
|
import type { DataProvider } from "../../../types/data-provider";
|
|
8
|
-
import { CATEGORY_MAP, screenerQuoteFromQuote, type ScreenerTabId } from "./model";
|
|
8
|
+
import { CATEGORY_MAP, moverRegularSession, screenerQuoteFromQuote, type MoverQuote, type ScreenerTabId } from "./model";
|
|
9
9
|
import {
|
|
10
10
|
fetchPreferredMarketMovers,
|
|
11
11
|
fetchTrending,
|
|
12
12
|
type MarketMoversResult,
|
|
13
13
|
type PreferredMoversOptions,
|
|
14
|
-
type ScreenerQuote,
|
|
15
14
|
type TrendingSymbol,
|
|
16
15
|
} from "./screener";
|
|
17
16
|
|
|
18
17
|
export interface MarketMoverTabResult extends MarketMoversResult {
|
|
19
18
|
tab: ScreenerTabId;
|
|
19
|
+
/** In the list's order; Last and Chg% the regular session, as `ticker` reads them. */
|
|
20
|
+
quotes: MoverQuote[];
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface MarketMoverTabDependencies {
|
|
@@ -36,9 +37,9 @@ const defaultDependencies: MarketMoverTabDependencies = {
|
|
|
36
37
|
async function hydrateTrending(
|
|
37
38
|
trending: readonly TrendingSymbol[],
|
|
38
39
|
provider: DataProvider | null,
|
|
39
|
-
): Promise<
|
|
40
|
+
): Promise<MoverQuote[]> {
|
|
40
41
|
const symbols = trending.slice(0, 25).map(({ symbol }) => symbol);
|
|
41
|
-
const bySymbol = new Map<string,
|
|
42
|
+
const bySymbol = new Map<string, MoverQuote>();
|
|
42
43
|
if (!provider) return [];
|
|
43
44
|
if (provider.getQuotesBatch) {
|
|
44
45
|
const results = await provider.getQuotesBatch(
|
|
@@ -79,7 +80,8 @@ export async function loadMarketMoverTab(
|
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
const result = await dependencies.fetchPreferred(CATEGORY_MAP[tab], 25, options);
|
|
82
|
-
|
|
83
|
+
// Ranked by the live print first, so reading each row's regular session keeps its place.
|
|
84
|
+
return { ...result, quotes: result.quotes.map(moverRegularSession), tab };
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
/** The server refused the list for the account's plan. */
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
type MarketMoverColumn,
|
|
35
35
|
type MarketMoverRow,
|
|
36
36
|
type MarketMoverSortPreference,
|
|
37
|
+
type MoverQuote,
|
|
37
38
|
type ScreenerTabId,
|
|
38
39
|
type TabId,
|
|
39
40
|
} from "./model";
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
/** Stable identity: a fresh literal here would reload the board every render. */
|
|
59
60
|
const NO_SAVED_SELECTION: string[] = [];
|
|
60
61
|
const SESSION_CHECK_MS = 30_000;
|
|
61
|
-
const NO_QUOTES:
|
|
62
|
+
const NO_QUOTES: MoverQuote[] = [];
|
|
62
63
|
const moverKey = (row: Pick<ScreenerQuote, "symbol" | "exchange">) => publicTickerKey(row.symbol, row.exchange);
|
|
63
64
|
|
|
64
65
|
/** What is trading in New York, re-read every half minute so the pane follows 04:00, 09:30 and 16:00. */
|
|
@@ -154,7 +155,7 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
|
|
|
154
155
|
}) {
|
|
155
156
|
const dataProvider = useAssetData();
|
|
156
157
|
const { pinTicker } = usePluginTickerActions();
|
|
157
|
-
const [quotes, setQuotes] = useState<
|
|
158
|
+
const [quotes, setQuotes] = useState<MoverQuote[]>([]);
|
|
158
159
|
const [loadedTab, setLoadedTab] = useState<TabId | null>(null);
|
|
159
160
|
const visibleQuotes = loadedTab === activeTab ? quotes : NO_QUOTES;
|
|
160
161
|
// The first load starts before the effect runs; an empty board is not "no data".
|
|
@@ -184,6 +184,36 @@ function moverExtended(quote: Quote): ExtendedSessionDisplay | null {
|
|
|
184
184
|
return extended && isFiniteNumber(extended.price) ? extended : null;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
/**
|
|
188
|
+
* A listed row as `ticker` reads its quote: Last and Chg% are the regular
|
|
189
|
+
* session's close and move, and a pre-market or after-hours print is its
|
|
190
|
+
* `extended`, measured from that close. The list ranked it by its live print
|
|
191
|
+
* first, so its place stays. A row without its quote's sessions (an older
|
|
192
|
+
* server) reads as it came.
|
|
193
|
+
*/
|
|
194
|
+
export function moverRegularSession({ sessions, ...row }: ScreenerQuote): MoverQuote {
|
|
195
|
+
if (!sessions || row.price == null) return row;
|
|
196
|
+
const quote: Quote = {
|
|
197
|
+
symbol: row.symbol,
|
|
198
|
+
price: row.price,
|
|
199
|
+
change: row.change ?? Number.NaN,
|
|
200
|
+
changePercent: row.changePercent ?? Number.NaN,
|
|
201
|
+
previousClose: row.previousClose,
|
|
202
|
+
currency: row.currency,
|
|
203
|
+
lastUpdated: row.lastUpdated ?? Number.NaN,
|
|
204
|
+
listingExchangeName: row.exchange || undefined,
|
|
205
|
+
...sessions,
|
|
206
|
+
};
|
|
207
|
+
const headline = getRegularSessionDisplay(quote)!;
|
|
208
|
+
return {
|
|
209
|
+
...row,
|
|
210
|
+
price: screenerNumber(headline.price),
|
|
211
|
+
change: screenerNumber(headline.change),
|
|
212
|
+
changePercent: screenerNumber(headline.changePercent),
|
|
213
|
+
extended: moverExtended(quote),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
187
217
|
/**
|
|
188
218
|
* A trending row from its quote: Last and Chg% are the regular session, as
|
|
189
219
|
* `ticker` reads it, and a pre-market or after-hours print rides beside them.
|
|
@@ -8,7 +8,9 @@ import type {
|
|
|
8
8
|
CloudMarketScreenerCategory,
|
|
9
9
|
CloudMarketScreenerItem,
|
|
10
10
|
CloudMarketScreenerPayload,
|
|
11
|
+
CloudMoverSessionFields,
|
|
11
12
|
} from "../../../api-client/types";
|
|
13
|
+
import type { MarketState } from "../../../types/financials";
|
|
12
14
|
import { hasProAccess } from "../../../api-client/plan-access";
|
|
13
15
|
|
|
14
16
|
const CACHE_KIND = "market-screener";
|
|
@@ -184,6 +186,32 @@ export function convertScreenerPriceUnit(value: number | undefined, from: string
|
|
|
184
186
|
? value / source.divisor * target.divisor : undefined;
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
const MARKET_STATES = new Set<string>(["PRE", "REGULAR", "POST", "PREPRE", "POSTPOST", "CLOSED"] satisfies MarketState[]);
|
|
190
|
+
const SESSION_NUMBERS = [
|
|
191
|
+
"regularClose", "regularChange", "regularChangePercent",
|
|
192
|
+
"preMarketPrice", "preMarketChange", "preMarketChangePercent",
|
|
193
|
+
"postMarketPrice", "postMarketChange", "postMarketChangePercent",
|
|
194
|
+
] as const;
|
|
195
|
+
const isSessionDate = (value: unknown): value is string => typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A row's quote sessions as the server sends them beside its live print, or
|
|
199
|
+
* undefined when it sends none (an older server), so the row reads as it came.
|
|
200
|
+
*/
|
|
201
|
+
function parseScreenerSessions(row: Record<string, unknown>): CloudMoverSessionFields | undefined {
|
|
202
|
+
if (typeof row.marketState !== "string" || !MARKET_STATES.has(row.marketState)) return undefined;
|
|
203
|
+
const sessions: CloudMoverSessionFields = { marketState: row.marketState as MarketState };
|
|
204
|
+
if (isSessionDate(row.changeSessionDate)) sessions.changeSessionDate = row.changeSessionDate;
|
|
205
|
+
for (const key of SESSION_NUMBERS) {
|
|
206
|
+
const value = screenerNumber(row[key]);
|
|
207
|
+
if (value != null) sessions[key] = value;
|
|
208
|
+
}
|
|
209
|
+
if (sessions.regularClose != null && isSessionDate(row.regularCloseSessionDate)) {
|
|
210
|
+
sessions.regularCloseSessionDate = row.regularCloseSessionDate;
|
|
211
|
+
}
|
|
212
|
+
return sessions;
|
|
213
|
+
}
|
|
214
|
+
|
|
187
215
|
/** Validate numeric fields at the API boundary so absent values stay unavailable. */
|
|
188
216
|
export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
|
|
189
217
|
if (!data || typeof data !== "object" || !("quotes" in data) || !Array.isArray(data.quotes)) {
|
|
@@ -202,6 +230,7 @@ export function parseScreenerResponse(data: unknown): ScreenerQuote[] {
|
|
|
202
230
|
dayHigh: screenerNumber(q.dayHigh) ?? undefined, dayLow: screenerNumber(q.dayLow) ?? undefined,
|
|
203
231
|
previousClose: screenerNumber(q.previousClose) ?? undefined, exchange: typeof q.exchange === "string" ? q.exchange : "",
|
|
204
232
|
lastUpdated: typeof q.lastUpdated === "number" && Number.isFinite(q.lastUpdated) && q.lastUpdated > 0 ? q.lastUpdated : undefined,
|
|
233
|
+
sessions: parseScreenerSessions(q),
|
|
205
234
|
}];
|
|
206
235
|
});
|
|
207
236
|
}
|
|
@@ -274,6 +303,8 @@ function mergeCloudScreenerItem(
|
|
|
274
303
|
dayLow: screenerNumber(item.dayLow) ?? metadataPrice(metadata?.dayLow),
|
|
275
304
|
exchange: item.exchange || metadata?.exchange || "",
|
|
276
305
|
lastUpdated: item.lastUpdated,
|
|
306
|
+
previousClose: screenerNumber(item.previousClose) ?? undefined,
|
|
307
|
+
sessions: parseScreenerSessions(item as unknown as Record<string, unknown>),
|
|
277
308
|
};
|
|
278
309
|
}
|
|
279
310
|
|