gloomberb 0.18.2 → 0.18.4
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 +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { scalarPointValue } from "./alignment";
|
|
2
2
|
import { getTimeSeriesField } from "./field-catalog";
|
|
3
3
|
import type { ChartSpec, ResolvedSeries, TimeSeriesPoint } from "./types";
|
|
4
|
-
import type
|
|
4
|
+
import { chartBarSizeSource, type ManualChartResolution } from "./resolution";
|
|
5
|
+
import type { TimeRange } from "./range";
|
|
5
6
|
import { zonedDateTimeParts } from "../utils/zoned-date-time";
|
|
6
7
|
import { barLastSession } from "../market-data/market/bar-period";
|
|
8
|
+
import {
|
|
9
|
+
barCloseDay, isIntradayDailyBar, isReturnPeriod, LATEST_INTRADAY_TEXT, periodBaseDay, periodBaseIndex, periodDayText,
|
|
10
|
+
} from "../market-data/market/period-return";
|
|
7
11
|
|
|
8
12
|
const PRICE_COMPARISON_BASIS = "Price returns in each listing's currency; cash distributions and FX conversion excluded.";
|
|
9
13
|
|
|
@@ -15,6 +19,26 @@ export interface PriceComparison {
|
|
|
15
19
|
notice: string;
|
|
16
20
|
alignment?: "session-date" | "timestamp";
|
|
17
21
|
sourceBounds?: Record<string, { start: number; end: number }>;
|
|
22
|
+
/**
|
|
23
|
+
* Each compared leg's base and end as the notice names them, `YYYY-MM-DD`:
|
|
24
|
+
* the day its base close is from, the day of its newest observation, and
|
|
25
|
+
* whether that observation is the session still trading.
|
|
26
|
+
*/
|
|
27
|
+
legs?: Record<string, { baseDay: string; endDay: string; intraday: boolean }>;
|
|
28
|
+
/** Legs left out of the comparison, by the symbol asked for, and why; the rest still compare. */
|
|
29
|
+
dropped?: Array<{ seriesId: string; label: string; reason: string }>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PriceComparisonOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The chart's untouched preset range; null for authored dates or a view
|
|
35
|
+
* panned or zoomed off it. A preset's legs each run to their own newest
|
|
36
|
+
* observation, so one that is behind does not cut the others short, and a
|
|
37
|
+
* calendar range (1W to 5Y) is measured from the close on or before the
|
|
38
|
+
* same date a range before (periodBaseDay), as RETURN is.
|
|
39
|
+
*/
|
|
40
|
+
preset?: TimeRange | null;
|
|
41
|
+
now?: number;
|
|
18
42
|
}
|
|
19
43
|
|
|
20
44
|
export function observationDate(time: number, series: Pick<ResolvedSeries, "timeBasis">): string {
|
|
@@ -47,6 +71,8 @@ export function priceObservationWindowFilter(
|
|
|
47
71
|
}
|
|
48
72
|
|
|
49
73
|
export function priceComparisonBoundsForSeries(series: ResolvedSeries, comparison: PriceComparison | null) {
|
|
74
|
+
// A leg left out of the comparison shows nothing of it.
|
|
75
|
+
if (comparison?.dropped?.some((entry) => entry.seriesId === series.id)) return { start: null, end: null };
|
|
50
76
|
return comparison?.sourceBounds?.[series.id] ?? comparison;
|
|
51
77
|
}
|
|
52
78
|
|
|
@@ -55,6 +81,20 @@ function displayDate(time: number): string {
|
|
|
55
81
|
return iso.endsWith("T00:00:00.000Z") ? iso.slice(0, 10) : iso.replace("T", " ").replace(".000Z", " UTC");
|
|
56
82
|
}
|
|
57
83
|
|
|
84
|
+
/** "Mon 21 Sep close (EWJ Fri 18 Sep close)": the text most legs share, then the others by symbol. */
|
|
85
|
+
function legsText(entries: ReadonlyArray<{ label: string; text: string }>): string {
|
|
86
|
+
const groups = new Map<string, string[]>();
|
|
87
|
+
for (const { label, text } of entries) groups.set(text, [...groups.get(text) ?? [], label]);
|
|
88
|
+
const [main, ...rest] = [...groups].sort((left, right) => right[1].length - left[1].length);
|
|
89
|
+
if (!main) return "";
|
|
90
|
+
return rest.length ? `${main[0]} (${rest.map(([text, labels]) => `${labels.join(", ")} ${text}`).join("; ")})` : main[0];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** A leg's venue, whose sessions say whether its newest bar is still trading. */
|
|
94
|
+
function legVenue(series: ResolvedSeries | undefined): string | undefined {
|
|
95
|
+
return series?.timeBasis?.exchange || series?.listing?.exchange || undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
58
98
|
/** Comparable normalized closing-price legs share observed endpoints. Other chart meanings are unchanged. */
|
|
59
99
|
export function priceComparisonSeriesIds(spec: ChartSpec): string[] | null {
|
|
60
100
|
if (spec.viewport.maxPoints !== undefined) return null;
|
|
@@ -71,58 +111,163 @@ export function priceComparisonSeriesIds(spec: ChartSpec): string[] | null {
|
|
|
71
111
|
return visible.map((entry) => entry.id);
|
|
72
112
|
}
|
|
73
113
|
|
|
114
|
+
interface ComparedLeg {
|
|
115
|
+
id: string;
|
|
116
|
+
label: string;
|
|
117
|
+
entry: ResolvedSeries;
|
|
118
|
+
/** Every priced observation by key, chronological: a period's base can be before the window. */
|
|
119
|
+
keys: string[];
|
|
120
|
+
points: Map<string, TimeSeriesPoint>;
|
|
121
|
+
/** The keys inside the window. */
|
|
122
|
+
window: string[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Where each compared leg starts and ends, and what the comparison says of it.
|
|
127
|
+
*
|
|
128
|
+
* Calendar bars compare by session date. An untouched preset range measures
|
|
129
|
+
* each leg from its own close on or before the same date a range before the
|
|
130
|
+
* newest observation of the chart (periodBaseDay), the convention RETURN
|
|
131
|
+
* and every period return share, and runs each leg to its own newest
|
|
132
|
+
* observation. Authored dates and a panned view start every leg at the first
|
|
133
|
+
* date they share and end them at the last. A leg with no prices, or one,
|
|
134
|
+
* is left out with its reason and the others still compare.
|
|
135
|
+
*/
|
|
74
136
|
export function resolvePriceComparison(
|
|
75
137
|
spec: ChartSpec,
|
|
76
138
|
series: readonly ResolvedSeries[],
|
|
77
139
|
bounds: { start: number | null; end: number | null },
|
|
78
|
-
resolution: ManualChartResolution | "auto" = spec.viewport.resolution,
|
|
140
|
+
resolution: ManualChartResolution | "auto" = spec.viewport.resolution === "auto" ? "auto" : chartBarSizeSource(spec.viewport.resolution),
|
|
79
141
|
dateWindow: ChartSpec["viewport"]["dateWindow"] | null = spec.viewport.dateWindow,
|
|
142
|
+
options: PriceComparisonOptions = {},
|
|
80
143
|
): PriceComparison | null {
|
|
81
144
|
const seriesIds = priceComparisonSeriesIds(spec);
|
|
82
145
|
if (!seriesIds) return null;
|
|
146
|
+
const now = options.now ?? Date.now();
|
|
83
147
|
const byId = new Map(series.map((entry) => [entry.id, entry]));
|
|
84
148
|
const calendarBars = resolution === "1d" || resolution === "1wk" || resolution === "1mo";
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
149
|
+
const order = (left: string, right: string) => calendarBars ? left.localeCompare(right) : Number(left) - Number(right);
|
|
150
|
+
const symbolOf = (id: string) => {
|
|
151
|
+
const source = spec.series.find((entry) => entry.id === id)?.source;
|
|
152
|
+
return source?.kind === "security" ? source.instrument.symbol : id;
|
|
153
|
+
};
|
|
154
|
+
// A leg not loaded yet (a seed from cached history) has not failed: nothing compares until it is.
|
|
155
|
+
const unavailable = `${PRICE_COMPARISON_BASIS} Comparison unavailable: need two shared dates and a nonzero baseline.`;
|
|
156
|
+
if (seriesIds.some((id) => !byId.has(id))) return { seriesIds, start: null, end: null, notice: unavailable };
|
|
157
|
+
const dropped: NonNullable<PriceComparison["dropped"]> = [];
|
|
158
|
+
const reported = new Set<string>();
|
|
159
|
+
const legs: ComparedLeg[] = [];
|
|
160
|
+
for (const id of seriesIds) {
|
|
161
|
+
const entry = byId.get(id)!;
|
|
88
162
|
const inWindow = priceObservationWindowFilter(entry, bounds, resolution, dateWindow);
|
|
89
|
-
|
|
163
|
+
const points = new Map<string, TimeSeriesPoint>();
|
|
164
|
+
const window = new Set<string>();
|
|
165
|
+
for (const point of entry.points) {
|
|
90
166
|
const time = point.date.getTime();
|
|
91
|
-
if (!
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
};
|
|
167
|
+
if (!Number.isFinite(time) || scalarPointValue(point) === null) continue;
|
|
168
|
+
const key = calendarBars ? observationDate(time, entry) : String(time);
|
|
169
|
+
points.set(key, point);
|
|
170
|
+
if (inWindow(time)) window.add(key);
|
|
171
|
+
}
|
|
172
|
+
const leg = { id, label: symbolOf(id), entry, keys: [...points.keys()].sort(order), points, window: [...window].sort(order) };
|
|
173
|
+
if (leg.window.length) legs.push(leg);
|
|
174
|
+
else if (entry.warning?.trim()) {
|
|
175
|
+
// A leg that failed to load: the chart's errors already say why.
|
|
176
|
+
dropped.push({ seriesId: id, label: leg.label, reason: entry.warning.trim() });
|
|
177
|
+
reported.add(id);
|
|
178
|
+
} else dropped.push({ seriesId: id, label: leg.label, reason: "no prices in this range" });
|
|
179
|
+
}
|
|
180
|
+
const nonzero = (leg: ComparedLeg, key: string) => scalarPointValue(leg.points.get(key)!) !== 0;
|
|
106
181
|
// A weekly or monthly bar's close is from the last session of its period, which the notice dates it by.
|
|
107
|
-
const
|
|
108
|
-
const venue =
|
|
109
|
-
const sessionDay = (key: string) => (
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
182
|
+
const barPeriod = resolution === "1wk" ? "week" : resolution === "1mo" ? "month" : null;
|
|
183
|
+
const venue = legVenue(byId.get(seriesIds[0]!));
|
|
184
|
+
const sessionDay = (key: string) => (barPeriod ? barLastSession(key, barPeriod, venue, now) : null) ?? key;
|
|
185
|
+
const dayOf = (leg: ComparedLeg, key: string) => calendarBars ? key : observationDate(Number(key), leg.entry);
|
|
186
|
+
const preset = options.preset ?? null;
|
|
187
|
+
const period = !dateWindow && isReturnPeriod(preset) ? preset : null;
|
|
188
|
+
const ownEnds = preset !== null && !dateWindow;
|
|
189
|
+
const shared = (keys: (leg: ComparedLeg) => readonly string[]) => {
|
|
190
|
+
const sets = legs.map((leg) => new Set(keys(leg)));
|
|
191
|
+
return legs.length ? keys(legs[0]!).filter((key) => sets.every((set) => set.has(key))) : [];
|
|
192
|
+
};
|
|
193
|
+
const sharedWindow = shared((leg) => leg.window);
|
|
194
|
+
const sharedStart = sharedWindow.find((key) => legs.every((leg) => nonzero(leg, key)));
|
|
195
|
+
// The period is measured back from the chart's newest observation, by its session day.
|
|
196
|
+
const anchor = period && legs.length
|
|
197
|
+
? legs.map((leg) => calendarBars ? sessionDay(leg.window.at(-1)!) : dayOf(leg, leg.window.at(-1)!)).sort().at(-1)!
|
|
198
|
+
: null;
|
|
199
|
+
const baseDay = anchor && period ? periodBaseDay(anchor, period) : null;
|
|
200
|
+
const closeDay = (leg: ComparedLeg, key: string) => calendarBars && resolution !== "1d" ? barCloseDay(key, resolution, legVenue(leg.entry)) : key;
|
|
201
|
+
// Intraday bars share their times, so their base is the last bar the legs share on or before the base day.
|
|
202
|
+
const sharedBase = baseDay && !calendarBars ? (() => {
|
|
203
|
+
const keys = shared((leg) => leg.keys).filter((key) => legs.every((leg) => nonzero(leg, key)));
|
|
204
|
+
const index = periodBaseIndex(keys.map((key) => dayOf(legs[0]!, key)), baseDay);
|
|
205
|
+
return index < 0 ? undefined : keys[index];
|
|
206
|
+
})() : undefined;
|
|
207
|
+
const startOf = (leg: ComparedLeg): string | undefined => {
|
|
208
|
+
if (!baseDay) return sharedStart;
|
|
209
|
+
if (!calendarBars) return sharedBase ?? sharedStart;
|
|
210
|
+
const index = periodBaseIndex(leg.keys.map((key) => closeDay(leg, key)), baseDay);
|
|
211
|
+
const base = index < 0 ? undefined : leg.keys[index];
|
|
212
|
+
// Without a close on or before the base day (a listing younger than the range), its first close in range.
|
|
213
|
+
return base !== undefined && nonzero(leg, base) ? base : leg.window.find((key) => nonzero(leg, key));
|
|
214
|
+
};
|
|
215
|
+
const sharedEnd = sharedWindow.at(-1);
|
|
216
|
+
// Legs that share their dates compare over two of them or not at all; a leg that runs on its own is left out alone.
|
|
217
|
+
const sharedSpan = sharedStart !== undefined && sharedEnd !== undefined && order(sharedStart, sharedEnd) < 0;
|
|
218
|
+
const compared = baseDay || ownEnds || sharedSpan ? legs.flatMap((leg) => {
|
|
219
|
+
const start = startOf(leg);
|
|
220
|
+
const end = ownEnds ? leg.window.at(-1) : sharedEnd;
|
|
221
|
+
if (start !== undefined && end !== undefined && order(start, end) < 0) return [{ leg, start, end }];
|
|
222
|
+
if (baseDay || sharedStart !== undefined) {
|
|
223
|
+
dropped.push({ seriesId: leg.id, label: leg.label, reason: start === undefined ? "no nonzero price to measure from in this range" : "only one price in this range" });
|
|
224
|
+
}
|
|
225
|
+
return [];
|
|
226
|
+
}) : [];
|
|
227
|
+
// "Left out: VIX; EWJ (only one price in this range)."
|
|
228
|
+
const droppedText = dropped.length
|
|
229
|
+
? ` Left out: ${dropped.map((entry) => reported.has(entry.seriesId) ? entry.label : `${entry.label} (${entry.reason})`).join("; ")}.`
|
|
230
|
+
: "";
|
|
231
|
+
if (!compared.length) return { seriesIds, start: null, end: null, notice: unavailable, ...(dropped.length ? { dropped } : {}) };
|
|
232
|
+
const sourceBounds = Object.fromEntries(compared.map(({ leg, start, end }) => [leg.id, {
|
|
233
|
+
start: leg.points.get(start)!.date.getTime(),
|
|
234
|
+
end: leg.points.get(end)!.date.getTime(),
|
|
113
235
|
}]));
|
|
236
|
+
const currentYear = new Date(now).getUTCFullYear();
|
|
237
|
+
const legDays = Object.fromEntries(compared.map(({ leg, start, end }) => {
|
|
238
|
+
const endDay = calendarBars ? sessionDay(end) : dayOf(leg, end);
|
|
239
|
+
// A daily bar of the session still trading, or a week or month running through it.
|
|
240
|
+
return [leg.id, { baseDay: calendarBars ? sessionDay(start) : dayOf(leg, start), endDay,
|
|
241
|
+
intraday: calendarBars && isIntradayDailyBar(endDay, legVenue(leg.entry), now) }];
|
|
242
|
+
}));
|
|
243
|
+
const span = calendarBars
|
|
244
|
+
? (() => {
|
|
245
|
+
const from = legsText(compared.map(({ leg }) => ({ label: leg.label, text: `${periodDayText(legDays[leg.id]!.baseDay, currentYear)} close` })));
|
|
246
|
+
const to = legsText(compared.map(({ leg }) => ({ label: leg.label, text: legDays[leg.id]!.intraday
|
|
247
|
+
? `${periodDayText(legDays[leg.id]!.endDay, currentYear)}, ${LATEST_INTRADAY_TEXT}`
|
|
248
|
+
: `${periodDayText(legDays[leg.id]!.endDay, currentYear)} close` })));
|
|
249
|
+
return `From ${from} to ${to}; market session times may differ.`;
|
|
250
|
+
})()
|
|
251
|
+
: baseDay && sharedBase !== undefined
|
|
252
|
+
? `From ${periodDayText(legDays[compared[0]!.leg.id]!.baseDay, currentYear)} close to ${displayDate(Math.max(...Object.values(sourceBounds).map((range) => range.end)))}.`
|
|
253
|
+
: `Shared observations: ${displayDate(Math.min(...Object.values(sourceBounds).map((range) => range.start)))} to ${displayDate(Math.max(...Object.values(sourceBounds).map((range) => range.end)))}.`;
|
|
114
254
|
return {
|
|
115
255
|
seriesIds,
|
|
116
256
|
start: Math.min(...Object.values(sourceBounds).map((range) => range.start)),
|
|
117
257
|
end: Math.max(...Object.values(sourceBounds).map((range) => range.end)),
|
|
118
258
|
alignment: calendarBars ? "session-date" : "timestamp",
|
|
119
259
|
sourceBounds,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
260
|
+
legs: legDays,
|
|
261
|
+
...(dropped.length ? { dropped } : {}),
|
|
262
|
+
notice: `${PRICE_COMPARISON_BASIS} ${span}${droppedText}`,
|
|
123
263
|
};
|
|
124
264
|
}
|
|
125
265
|
|
|
266
|
+
/** Whether a comparison's newest point is the session still trading on any leg. */
|
|
267
|
+
export function priceComparisonEndsIntraday(comparison: PriceComparison | null | undefined): boolean {
|
|
268
|
+
return Object.values(comparison?.legs ?? {}).some((leg) => leg.intraday);
|
|
269
|
+
}
|
|
270
|
+
|
|
126
271
|
/**
|
|
127
272
|
* The bars a compared leg pans and zooms over: inside the view only its shared
|
|
128
273
|
* dates, as the chart shows them, and every loaded bar past either edge of the
|
package/src/time-series/range.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
export type TimeRange = "1D" | "1W" | "1M" | "3M" | "6M" | "1Y" | "5Y" | "ALL";
|
|
2
|
-
|
|
2
|
+
/** A bar size's unit: minutes, hours, days, weeks and months. */
|
|
3
|
+
export type ChartBarSizeUnit = "m" | "h" | "d" | "wk" | "mo";
|
|
4
|
+
/**
|
|
5
|
+
* A bar size a chart builds from the bars a source serves: `10m` from 5-minute
|
|
6
|
+
* bars, `4h` from hourly ones, `2d` from daily ones. Always in the form
|
|
7
|
+
* `parseChartBarSize` returns; sources and brokers never see one.
|
|
8
|
+
*/
|
|
9
|
+
export type CustomChartResolution = `${number}${ChartBarSizeUnit}`;
|
|
10
|
+
export type ChartResolution = "auto" | "1m" | "5m" | "15m" | "30m" | "45m" | "1h" | "1d" | "1wk" | "1mo" | CustomChartResolution;
|
|
3
11
|
|
|
4
12
|
export interface ChartDateWindow {
|
|
5
13
|
start: Date | null;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { ChartResolution, TimeRange } from "./range";
|
|
1
|
+
import type { ChartBarSizeUnit, ChartResolution, CustomChartResolution, TimeRange } from "./range";
|
|
2
2
|
import { CHART_RESOLUTIONS, TIME_RANGES } from "./range";
|
|
3
3
|
import { isDateWindowWithinTimeRange } from "./date-window";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/** The bar sizes sources and brokers serve, and the only ones they are asked for. */
|
|
6
|
+
export type ManualChartResolution = "1m" | "5m" | "15m" | "30m" | "45m" | "1h" | "1d" | "1wk" | "1mo";
|
|
7
|
+
/** Any bar size a chart draws: one a source serves, or one built from them. */
|
|
8
|
+
export type ChartBarSize = Exclude<ChartResolution, "auto">;
|
|
6
9
|
|
|
7
10
|
export interface ChartResolutionSupport {
|
|
8
11
|
resolution: ManualChartResolution;
|
|
@@ -13,7 +16,7 @@ export interface ChartResolutionSupport {
|
|
|
13
16
|
export const TIME_RANGE_ORDER = TIME_RANGES;
|
|
14
17
|
const CHART_RESOLUTION_ORDER = CHART_RESOLUTIONS;
|
|
15
18
|
|
|
16
|
-
const CHART_RESOLUTION_LABELS: Record<
|
|
19
|
+
const CHART_RESOLUTION_LABELS: Record<ManualChartResolution | "auto", string> = {
|
|
17
20
|
auto: "AUTO",
|
|
18
21
|
"1m": "1M",
|
|
19
22
|
"5m": "5M",
|
|
@@ -39,7 +42,7 @@ const RANGE_PRESET_RESOLUTION: Record<TimeRange, ManualChartResolution> = {
|
|
|
39
42
|
|
|
40
43
|
/**
|
|
41
44
|
* The bar size a price history for a range is served in, unlike the chart
|
|
42
|
-
* presets above: what `
|
|
45
|
+
* presets above: what `gloom history` and the historical prices pane get.
|
|
43
46
|
*/
|
|
44
47
|
export const RANGE_HISTORY_RESOLUTION: Readonly<Record<TimeRange, ManualChartResolution>> = {
|
|
45
48
|
"1D": "5m",
|
|
@@ -137,21 +140,153 @@ function compareTimeRange(left: TimeRange, right: TimeRange): number {
|
|
|
137
140
|
return getTimeRangeIndex(left) - getTimeRangeIndex(right);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
function
|
|
141
|
-
return CHART_RESOLUTION_ORDER.includes(value as ChartResolution);
|
|
143
|
+
export function isManualChartResolution(value: unknown): value is ManualChartResolution {
|
|
144
|
+
return value !== "auto" && CHART_RESOLUTION_ORDER.includes(value as ChartResolution);
|
|
142
145
|
}
|
|
143
146
|
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
const BAR_SIZE_UNIT_MS: Readonly<Record<ChartBarSizeUnit, number>> = {
|
|
148
|
+
m: 60_000,
|
|
149
|
+
h: 60 * 60_000,
|
|
150
|
+
d: 24 * 60 * 60_000,
|
|
151
|
+
wk: 7 * 24 * 60 * 60_000,
|
|
152
|
+
mo: 30 * 24 * 60 * 60_000,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** The longest bar of each unit: a day of minutes or hours, a year of days, weeks or months. */
|
|
156
|
+
const BAR_SIZE_MAX_COUNT: Readonly<Record<ChartBarSizeUnit, number>> = { m: 1440, h: 24, d: 365, wk: 52, mo: 12 };
|
|
157
|
+
|
|
158
|
+
const BAR_SIZE_UNITS: Readonly<Record<string, ChartBarSizeUnit>> = {
|
|
159
|
+
m: "m", min: "m", mins: "m", minute: "m", minutes: "m",
|
|
160
|
+
h: "h", hr: "h", hrs: "h", hour: "h", hours: "h",
|
|
161
|
+
d: "d", day: "d", days: "d",
|
|
162
|
+
w: "wk", wk: "wk", week: "wk", weeks: "wk",
|
|
163
|
+
mo: "mo", mon: "mo", month: "mo", months: "mo",
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/** A bar size in its one stored form: `90m`, `4h` (not `240m`), `2d`, `1wk`, `3mo`. */
|
|
167
|
+
function canonicalBarSize(count: number, unit: ChartBarSizeUnit): ChartBarSize | null {
|
|
168
|
+
if (!Number.isSafeInteger(count) || count <= 0) return null;
|
|
169
|
+
if (unit === "m" && count % 60 === 0) return canonicalBarSize(count / 60, "h");
|
|
170
|
+
if (count > BAR_SIZE_MAX_COUNT[unit]) return null;
|
|
171
|
+
return `${count}${unit}` as ChartBarSize;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** A stored bar size's count and unit; null for anything that is not one. */
|
|
175
|
+
export function chartBarSizeParts(size: unknown): { count: number; unit: ChartBarSizeUnit } | null {
|
|
176
|
+
if (typeof size !== "string") return null;
|
|
177
|
+
const match = /^([1-9]\d{0,3})(m|h|d|wk|mo)$/.exec(size);
|
|
178
|
+
if (!match) return null;
|
|
179
|
+
const count = Number(match[1]);
|
|
180
|
+
const unit = match[2] as ChartBarSizeUnit;
|
|
181
|
+
return canonicalBarSize(count, unit) === size ? { count, unit } : null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** A stored bar size (`4h`, `2d`, `1wk`); `auto` is not one. */
|
|
185
|
+
function isChartBarSize(value: unknown): value is ChartBarSize {
|
|
186
|
+
return chartBarSizeParts(value) !== null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Any value a chart's resolution may hold: `auto` or a stored bar size. */
|
|
190
|
+
export function isChartResolution(value: unknown): value is ChartResolution {
|
|
191
|
+
return value === "auto" || isChartBarSize(value);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** A bar size the source does not serve, which the chart builds from one it does. */
|
|
195
|
+
export function isCustomChartResolution(value: unknown): value is CustomChartResolution {
|
|
196
|
+
return isChartBarSize(value) && !isManualChartResolution(value);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Reads a bar size as typed: `10m`, `10 min`, `4h`, `240` (minutes), `2D`,
|
|
201
|
+
* `3 days`, `2W`, `3mo`, `1Y`. A capital `M` alone is read as nothing: the
|
|
202
|
+
* chart labels months `M` and the command line minutes `1M`, so `3M` could be
|
|
203
|
+
* either. Null for anything else, and for bars longer than a day of minutes
|
|
204
|
+
* or hours, a year of days or weeks, or twelve months.
|
|
205
|
+
*/
|
|
206
|
+
export function parseChartBarSize(value: unknown): ChartBarSize | null {
|
|
207
|
+
if (typeof value !== "string") return null;
|
|
208
|
+
const match = /^(\d{1,4})\s*([A-Za-z]*)$/.exec(value.trim());
|
|
209
|
+
if (!match) return null;
|
|
210
|
+
const count = Number(match[1]);
|
|
211
|
+
const written = match[2]!;
|
|
212
|
+
if (written === "") return canonicalBarSize(count, "m");
|
|
213
|
+
if (written === "M") return null;
|
|
214
|
+
const lower = written.toLowerCase();
|
|
215
|
+
if (lower === "y" || lower === "yr" || lower === "year" || lower === "years") return canonicalBarSize(count * 12, "mo");
|
|
216
|
+
const unit = BAR_SIZE_UNITS[lower];
|
|
217
|
+
return unit ? canonicalBarSize(count, unit) : null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** A chart resolution as typed or stored: `auto`, or any bar size `parseChartBarSize` reads. */
|
|
221
|
+
export function parseChartResolution(value: unknown): ChartResolution | null {
|
|
222
|
+
if (typeof value === "string" && value.trim().toLowerCase() === "auto") return "auto";
|
|
223
|
+
return parseChartBarSize(value);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** How long one bar is; a month counts as 30 days. */
|
|
227
|
+
export function chartBarSizeStepMs(size: ChartBarSize): number {
|
|
228
|
+
const parts = chartBarSizeParts(size);
|
|
229
|
+
return parts ? parts.count * BAR_SIZE_UNIT_MS[parts.unit] : Number.NaN;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Source bar sizes that can make up minute and hour bars, longest first. */
|
|
233
|
+
const INTRADAY_SOURCE_RESOLUTIONS: readonly ManualChartResolution[] = ["1h", "45m", "30m", "15m", "5m", "1m"];
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The bars a source serves that a bar size is built from: the longest that
|
|
237
|
+
* divide it (1h for 4h, 5m for 10m, 30m for 90m), among those the source
|
|
238
|
+
* serves when `support` says. Day, week and month multiples come from 1d, 1wk
|
|
239
|
+
* and 1mo bars. `openMinute`, minutes after local midnight, is when sessions
|
|
240
|
+
* open on a listing whose source bars start on the clock rather than at the
|
|
241
|
+
* open (futures): its source bars must also divide it, or a bar would straddle
|
|
242
|
+
* the open. A bar size the source serves is its own.
|
|
243
|
+
*/
|
|
244
|
+
export function chartBarSizeSource(
|
|
245
|
+
size: ChartBarSize,
|
|
246
|
+
support: readonly ChartResolutionSupport[] = [],
|
|
247
|
+
openMinute: number | null = null,
|
|
248
|
+
): ManualChartResolution {
|
|
249
|
+
if (isManualChartResolution(size)) return size;
|
|
250
|
+
const parts = chartBarSizeParts(size);
|
|
251
|
+
if (!parts) return "1d";
|
|
252
|
+
if (parts.unit === "d") return "1d";
|
|
253
|
+
if (parts.unit === "wk") return "1wk";
|
|
254
|
+
if (parts.unit === "mo") return "1mo";
|
|
255
|
+
const minutes = parts.unit === "h" ? parts.count * 60 : parts.count;
|
|
256
|
+
const candidates = INTRADAY_SOURCE_RESOLUTIONS.filter((resolution) => {
|
|
257
|
+
const step = CHART_RESOLUTION_STEP_MS[resolution] / 60_000;
|
|
258
|
+
return minutes % step === 0 && (openMinute === null || openMinute % step === 0);
|
|
259
|
+
});
|
|
260
|
+
const served = support.length > 0
|
|
261
|
+
? candidates.find((resolution) => getSupportMaxRange(support, resolution) !== null)
|
|
262
|
+
: undefined;
|
|
263
|
+
return served ?? candidates[0] ?? "1m";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Every bar size the chart lists, shortest first: the ones sources serve and
|
|
268
|
+
* the ones most asked for that it builds from them. Any other is typed in.
|
|
269
|
+
*/
|
|
270
|
+
export const CHART_BAR_SIZE_PRESETS: readonly ChartBarSize[] = [
|
|
271
|
+
"1m", "5m", "10m", "15m", "30m", "45m", "1h", "2h", "4h", "1d", "2d", "3d", "1wk", "1mo",
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
/** Orders bar sizes from the shortest bar to the longest. */
|
|
275
|
+
export function sortChartBarSizes<T extends ChartBarSize>(sizes: readonly T[]): T[] {
|
|
276
|
+
return [...sizes].sort((left, right) => chartBarSizeStepMs(left) - chartBarSizeStepMs(right));
|
|
146
277
|
}
|
|
147
278
|
|
|
148
|
-
/** @deprecated Slated for removal. Check the value
|
|
279
|
+
/** @deprecated Slated for removal. Check the value with `isChartResolution` instead. */
|
|
149
280
|
export function normalizeChartResolution(value: unknown, fallback: ChartResolution = "auto"): ChartResolution {
|
|
150
281
|
return isChartResolution(value) ? value : fallback;
|
|
151
282
|
}
|
|
152
283
|
|
|
284
|
+
const CUSTOM_BAR_UNIT_LABELS: Readonly<Record<ChartBarSizeUnit, string>> = { m: "M", h: "H", d: "D", wk: "W", mo: "MO" };
|
|
285
|
+
|
|
153
286
|
export function getChartResolutionLabel(resolution: ChartResolution): string {
|
|
154
|
-
return CHART_RESOLUTION_LABELS[resolution];
|
|
287
|
+
if (isManualChartResolution(resolution) || resolution === "auto") return CHART_RESOLUTION_LABELS[resolution];
|
|
288
|
+
const parts = chartBarSizeParts(resolution);
|
|
289
|
+
return parts ? `${parts.count}${CUSTOM_BAR_UNIT_LABELS[parts.unit]}` : String(resolution).toUpperCase();
|
|
155
290
|
}
|
|
156
291
|
|
|
157
292
|
export function getPresetResolution(range: TimeRange): ManualChartResolution {
|
|
@@ -199,11 +334,11 @@ export function getExpandedBufferRange(
|
|
|
199
334
|
const nextCandidate = getNextBufferRange(bufferRange);
|
|
200
335
|
const nextBufferRange = resolution === "auto"
|
|
201
336
|
? nextCandidate
|
|
202
|
-
: clampTimeRangeToMaxRange(nextCandidate, supportMap.get(resolution) ?? bufferRange);
|
|
337
|
+
: clampTimeRangeToMaxRange(nextCandidate, supportMap.get(chartBarSizeSource(resolution)) ?? bufferRange);
|
|
203
338
|
return isTimeRangeAtOrBelow(nextBufferRange, bufferRange) ? null : nextBufferRange;
|
|
204
339
|
}
|
|
205
340
|
|
|
206
|
-
export function sortChartResolutions<T extends
|
|
341
|
+
export function sortChartResolutions<T extends "auto" | ManualChartResolution>(resolutions: readonly T[]): T[] {
|
|
207
342
|
return [...resolutions].sort((left, right) => (
|
|
208
343
|
CHART_RESOLUTION_ORDER.indexOf(left) - CHART_RESOLUTION_ORDER.indexOf(right)
|
|
209
344
|
));
|
|
@@ -267,6 +402,31 @@ export function getSupportMaxRange(
|
|
|
267
402
|
return normalizeChartResolutionSupport(support).find((entry) => entry.resolution === resolution)?.maxRange ?? null;
|
|
268
403
|
}
|
|
269
404
|
|
|
405
|
+
function viewportSpanMs(range: TimeRange, dateWindow?: { start: string | Date; end: string | Date }): number {
|
|
406
|
+
const start = dateWindow ? new Date(dateWindow.start).getTime() : Number.NaN;
|
|
407
|
+
const end = dateWindow ? new Date(dateWindow.end).getTime() : Number.NaN;
|
|
408
|
+
return Number.isFinite(start) && Number.isFinite(end) && start <= end
|
|
409
|
+
? end - start
|
|
410
|
+
: TIME_RANGE_APPROXIMATE_DAYS[range] * CHART_RESOLUTION_STEP_MS["1d"];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* The bar sizes of `sizes` a chart of this range or window can draw: each
|
|
415
|
+
* one's source bars reach back over it, and it holds at least two bars.
|
|
416
|
+
*/
|
|
417
|
+
export function getSupportedChartBarSizesForViewport<T extends ChartBarSize>(
|
|
418
|
+
range: TimeRange,
|
|
419
|
+
support: readonly ChartResolutionSupport[],
|
|
420
|
+
sizes: readonly T[],
|
|
421
|
+
dateWindow?: { start: string | Date; end: string | Date },
|
|
422
|
+
openMinute: number | null = null,
|
|
423
|
+
): T[] {
|
|
424
|
+
const served = new Set<ManualChartResolution>(getSupportedChartResolutionsForViewport(range, support, dateWindow));
|
|
425
|
+
const span = viewportSpanMs(range, dateWindow);
|
|
426
|
+
return sizes.filter((size) => served.has(chartBarSizeSource(size, support, openMinute))
|
|
427
|
+
&& span / chartBarSizeStepMs(size) >= MINIMUM_USEFUL_CHART_POINTS);
|
|
428
|
+
}
|
|
429
|
+
|
|
270
430
|
export function getSupportedChartResolutionsForViewport(
|
|
271
431
|
range: TimeRange,
|
|
272
432
|
support: readonly ChartResolutionSupport[],
|
|
@@ -279,9 +439,7 @@ export function getSupportedChartResolutionsForViewport(
|
|
|
279
439
|
&& !!end
|
|
280
440
|
&& Number.isFinite(end.getTime())
|
|
281
441
|
&& start.getTime() <= end.getTime();
|
|
282
|
-
const
|
|
283
|
-
? Math.max(end.getTime() - start.getTime(), 0)
|
|
284
|
-
: TIME_RANGE_APPROXIMATE_DAYS[range] * CHART_RESOLUTION_STEP_MS["1d"];
|
|
442
|
+
const spanMs = viewportSpanMs(range, dateWindow);
|
|
285
443
|
return normalizeChartResolutionSupport(support)
|
|
286
444
|
.filter((entry) => (
|
|
287
445
|
hasValidDateWindow
|
|
@@ -289,7 +447,7 @@ export function getSupportedChartResolutionsForViewport(
|
|
|
289
447
|
: isTimeRangeAtOrBelow(range, entry.maxRange)
|
|
290
448
|
))
|
|
291
449
|
.filter((entry) => (
|
|
292
|
-
|
|
450
|
+
spanMs / CHART_RESOLUTION_STEP_MS[entry.resolution]
|
|
293
451
|
>= MINIMUM_USEFUL_CHART_POINTS
|
|
294
452
|
))
|
|
295
453
|
.map((entry) => entry.resolution);
|