gloomberb 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +32 -1
- package/src/account/auth-model.ts +7 -3
- 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 +11 -6
- package/src/api-client/catalysts.ts +2 -1
- 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 +98 -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 +182 -16
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +18 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +224 -26
- package/src/api-client/research-activity.ts +3 -10
- 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/themes.ts +7 -1
- package/src/api-client/types.ts +96 -2
- package/src/app/keybindings/index.ts +3 -0
- package/src/app/keybindings/labels.ts +18 -1
- package/src/app/keybindings/resolve.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/broker-import.ts +43 -26
- 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/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- 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 +9 -2
- package/src/cli/commands/keybindings.ts +25 -2
- package/src/cli/commands/market.ts +1177 -278
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-chain.ts +59 -3
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +222 -61
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +82 -46
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +194 -48
- 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 +21 -3
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +38 -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 +113 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +226 -50
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +123 -27
- package/src/cli/listing-arg.ts +316 -46
- package/src/cli/name-entries.ts +30 -18
- 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 +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +193 -30
- package/src/cli/pane-functions/function-help.ts +76 -30
- package/src/cli/pane-functions/headless.ts +59 -12
- package/src/cli/pane-functions/index.ts +28 -19
- package/src/cli/pane-functions/market-session.ts +15 -5
- 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 +10 -6
- package/src/cli/pane-functions/resolver.ts +64 -11
- 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 +45 -4
- package/src/cli/report-tables.ts +75 -19
- package/src/cli/restore-plugins.ts +42 -15
- package/src/cli/result.ts +164 -23
- 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 +198 -68
- 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 +395 -20
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +7 -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-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +314 -13
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +20 -4
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- 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 +17 -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/panel/prompt-binding.ts +0 -8
- 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/alert.ts +1 -1
- 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/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 +12 -6
- package/src/components/layout/header.tsx +33 -46
- 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/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +38 -5
- 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-frame.tsx +1 -1
- 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/portfolio-step/positions-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 +10 -2
- 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/core/state/app/layout.ts +6 -4
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- 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 +123 -0
- package/src/docs/snapshot.json +422 -112
- package/src/i18n/es.ts +30 -13
- package/src/i18n/ja.ts +30 -13
- package/src/i18n/ko.ts +30 -13
- package/src/i18n/zh-cn.ts +30 -13
- package/src/i18n/zh-tw.ts +30 -13
- 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/coordinator/financials.ts +10 -2
- package/src/market-data/coordinator/index.ts +3 -1
- package/src/market-data/coordinator/quotes.ts +4 -2
- 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 +81 -11
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/status.ts +16 -4
- 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/options-alternatives.ts +60 -0
- 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 +25 -3
- 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 +7 -2
- package/src/market-data/selectors.ts +3 -0
- 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/notifications/notification-log.ts +6 -4
- 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 +34 -20
- package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
- package/src/plugins/builtin/alerts/cli.ts +533 -85
- package/src/plugins/builtin/alerts/command.ts +12 -10
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- 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 +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +119 -0
- package/src/plugins/builtin/alerts/format.ts +10 -3
- package/src/plugins/builtin/alerts/headless.ts +107 -41
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +92 -0
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +107 -30
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +61 -0
- package/src/plugins/builtin/alerts/metric-data.ts +70 -0
- package/src/plugins/builtin/alerts/metric-model.ts +175 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +130 -49
- 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 +76 -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 +38 -12
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/alerts/types.ts +3 -0
- 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 +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- 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 +6 -3
- package/src/plugins/builtin/backtest/headless.ts +13 -8
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -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 +24 -14
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +18 -3
- 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 +66 -24
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +19 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
- 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 +111 -24
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- 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 +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.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 +51 -5
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- 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 +4 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
- package/src/plugins/builtin/chart-composer/headless.ts +266 -37
- 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 +144 -30
- package/src/plugins/builtin/chart-composer/presets.ts +50 -15
- package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
- 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 +31 -28
- 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 +44 -31
- 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/command-suggestions.ts +92 -0
- package/src/plugins/builtin/chat/content/composer.tsx +13 -6
- package/src/plugins/builtin/chat/content/footer.tsx +6 -3
- package/src/plugins/builtin/chat/content/index.tsx +51 -22
- package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
- package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
- package/src/plugins/builtin/chat/index.tsx +23 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
- package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
- package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -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/plugin.tsx +1 -1
- 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 +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- 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 +79 -23
- 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 +1 -1
- 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 +5 -3
- 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 +3 -2
- 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/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/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 +18 -11
- 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 +144 -27
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/figures.ts +72 -0
- 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 +144 -27
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +34 -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 +87 -28
- 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 +104 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
- 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/charts.tsx +2 -2
- 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 +20 -1
- package/src/plugins/builtin/exposure/pane.tsx +10 -5
- 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/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +12 -10
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +3 -3
- 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 +20 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
- package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
- package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- 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 +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- 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/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- 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/headless.ts +7 -4
- 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 +10 -4
- 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 +51 -13
- 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 +33 -19
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- 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 +29 -8
- 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/breadth-pane.tsx +81 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +24 -10
- package/src/plugins/builtin/members/index.tsx +9 -9
- package/src/plugins/builtin/members/model.ts +23 -4
- package/src/plugins/builtin/members/pane.tsx +31 -14
- 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 +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/analytics.ts +26 -2
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +5 -2
- package/src/plugins/builtin/options/strike-window.ts +2 -1
- package/src/plugins/builtin/options/table.ts +1 -7
- package/src/plugins/builtin/options/view.tsx +30 -13
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-positioning/client.ts +19 -0
- package/src/plugins/builtin/options-positioning/headless.ts +54 -14
- package/src/plugins/builtin/options-positioning/index.tsx +3 -3
- package/src/plugins/builtin/options-positioning/model.ts +47 -8
- package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- 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 +36 -15
- 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 +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +14 -9
- 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 +168 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +49 -26
- 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 +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
- 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 +7 -4
- 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/index.tsx +11 -8
- 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 +4 -1
- 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 +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- 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 +80 -13
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/index.ts +24 -1
- package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
- package/src/plugins/builtin/scanner/live-feed.ts +168 -0
- package/src/plugins/builtin/scanner/live-headless.ts +114 -0
- package/src/plugins/builtin/scanner/live-model.ts +351 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
- package/src/plugins/builtin/scanner/live-track.ts +186 -0
- package/src/plugins/builtin/scanner/lock-note.ts +1 -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 +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- 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/macro-releases.ts +65 -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 +21 -0
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
- package/src/plugins/builtin/shared/volatility/pricing.ts +7 -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/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 +11 -6
- package/src/plugins/builtin/themes/model.ts +15 -5
- package/src/plugins/builtin/themes/pane.tsx +27 -8
- 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 +14 -4
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +7 -4
- package/src/plugins/builtin/vol-surface/headless.ts +71 -13
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +26 -9
- package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/volatility/pane.tsx +2 -2
- package/src/plugins/builtin/volatility/series.ts +26 -0
- package/src/plugins/builtin/world-indices/footer.ts +1 -1
- 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 +15 -9
- 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 +15 -13
- 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 +15 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +5 -55
- package/src/renderers/browser/main.tsx +30 -60
- 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/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/styles.css +76 -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/desktop/app-name.ts +222 -0
- 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/relaunch.ts +74 -25
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +36 -2
- 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/app-name.ts +17 -0
- 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/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -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 +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- 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 +1 -1
- package/src/renderers/opentui/toast-host.tsx +71 -43
- 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 +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +16 -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/batches.ts +10 -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 +58 -15
- package/src/sources/provider-router/index.ts +146 -10
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +67 -17
- package/src/sync/core-contributors.ts +46 -14
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +11 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/company-name.ts +59 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-venues.ts +23 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +111 -33
- package/src/tickers/search/ranking.ts +64 -5
- package/src/tickers/search/types.ts +5 -0
- 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 +315 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/field-catalog.ts +1 -3
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +173 -10
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/hooks.ts +1 -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/price-units.ts +72 -2
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +161 -0
- package/src/time-series/resolve.ts +185 -1587
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +242 -0
- package/src/time-series/spec.ts +13 -7
- package/src/time-series/studies.ts +377 -82
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/transforms.ts +1 -0
- package/src/time-series/types.ts +34 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +23 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +145 -8
- package/src/types/headless.ts +117 -9
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +66 -9
- 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 +180 -0
- package/src/updater/index.ts +10 -5
- 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-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 +89 -5
- 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 +86 -0
- package/src/utils/option-expiry.ts +186 -7
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +23 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -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
- package/src/renderers/browser/first-screen.ts +0 -193
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import { financialPeriodCoverage } from "../../../time-series/financial-period-coverage";
|
|
2
3
|
import { FINANCIAL_VINTAGE_NOTICE, SEC_EPS_BASIS_NOTICE } from "../../../utils/financial-statements";
|
|
3
4
|
import { graphRowsForFinancials, summarizeResolvedSeries } from "../../../time-series/reporting";
|
|
@@ -5,13 +6,19 @@ import { priceHistoryIntegrityNotices, chartPriceHistoryIntegrityNotices } from
|
|
|
5
6
|
import type { HeadlessPaneContext, HeadlessPaneDefinition, HeadlessPaneFreshness, HeadlessSeries, HeadlessSeriesResult } from "../../../types/headless";
|
|
6
7
|
import type { CapabilitySeriesSource, ChartResolutionResult, ChartSeriesSource, ChartSeriesSpec, ChartSpec, ChartViewportSpec, ResolvedSeries } from "../../../time-series/types";
|
|
7
8
|
import { resolveGeoChartSeries } from "../world-venue-map/geo-series";
|
|
8
|
-
import { GEO_SERIES_CAPABILITY_ID, parseSeriesExpression } from "./series-expression";
|
|
9
|
-
import {
|
|
9
|
+
import { CHART_FIELD_IDS, GEO_SERIES_CAPABILITY_ID, parseSeriesExpression } from "./series-expression";
|
|
10
|
+
import { buildSeriesSpec } from "./chart-spec-edit";
|
|
11
|
+
import { getSharedRegistry } from "../../registry";
|
|
12
|
+
import { notATickerSymbol } from "../../../sources/provider-errors";
|
|
13
|
+
import { resolveChartSpecData } from "../../../time-series/resolve";
|
|
14
|
+
import { mergePriceHistoryWindows, priceHistoryAcquisitionIdentity, priceHistoryTailAcquisition } from "../../../time-series/history-acquisition";
|
|
10
15
|
import {
|
|
16
|
+
chartBarSizeSource,
|
|
11
17
|
getSupportMaxRange,
|
|
12
18
|
intersectChartResolutionSupport,
|
|
13
19
|
isIntradayResolution,
|
|
14
20
|
normalizeChartResolutionSupport,
|
|
21
|
+
type ChartBarSize,
|
|
15
22
|
type ManualChartResolution,
|
|
16
23
|
} from "../../../time-series/resolution";
|
|
17
24
|
import type { ChartResolution } from "../../../time-series/range";
|
|
@@ -24,14 +31,22 @@ import type { TickerFinancials, PricePoint, Quote } from "../../../types/financi
|
|
|
24
31
|
import { chartQuoteOverrideKeyForTarget, getLiveChartQuoteTargets } from "../../../time-series/live-quotes";
|
|
25
32
|
import { createChartSeriesResolver } from "../../../capabilities";
|
|
26
33
|
import { loadFuturesContractTerms, loadFuturesPriceUnit } from "../../../market-data/futures-contract";
|
|
27
|
-
import { parsePublicTickerKey, publicTickerKey } from "../../../utils/exchanges";
|
|
34
|
+
import { isUsListingExchange, parsePublicTickerKey, publicTickerKey } from "../../../utils/exchanges";
|
|
35
|
+
import { zonedDateTimeParts } from "../../../utils/zoned-date-time";
|
|
36
|
+
import { futuresSessionOpenMinute } from "../../../market-data/market/trading-sessions";
|
|
37
|
+
import { cleanFloat32Price } from "../../../cli/history-rows";
|
|
28
38
|
import { parseChartSpec } from "./chart-spec";
|
|
29
39
|
import { paneSchemas } from "./headless-schema";
|
|
30
|
-
import { barHistoryFreshness, REPORTED_DATA } from "../shared/report-freshness";
|
|
40
|
+
import { barHistoryFreshness, DAILY_CLOSES, REPORTED_DATA } from "../shared/report-freshness";
|
|
31
41
|
import type { BarPeriodToDate } from "../../../market-data/market/bar-period";
|
|
32
42
|
import { closedHistoryBarDay, formingHistoryBar } from "../ticker-detail/data-panes/history-bars";
|
|
33
43
|
import { inferSeriesFrequency } from "../../../series/csv";
|
|
34
44
|
import { isDatasetChart } from "../../../time-series/spec";
|
|
45
|
+
import { loadFundFacts } from "../sec/fund-facts";
|
|
46
|
+
import { comparedFundTickers, loadDailyObjectives, mayDrawDailyObjective, withLeverageOverlay } from "./leverage-overlay";
|
|
47
|
+
import { classifyInstrumentType } from "../../../tickers/instrument-kind";
|
|
48
|
+
import { priceComparisonEndsIntraday, type PriceComparison } from "../../../time-series/price-comparison";
|
|
49
|
+
import { LATEST_INTRADAY_TEXT } from "../../../market-data/market/period-return";
|
|
35
50
|
|
|
36
51
|
export interface ChartPaneModel extends HeadlessSeriesResult {
|
|
37
52
|
/** The renderer consumes the full model; generic reports project series and metadata. */
|
|
@@ -87,7 +102,7 @@ export async function loadChartPaneModel(
|
|
|
87
102
|
if (getQuote && !spec.viewport.dateWindow) {
|
|
88
103
|
await Promise.all(getLiveChartQuoteTargets(spec).map(async (target) => {
|
|
89
104
|
const quote = await getQuote(target.symbol, target.exchange ?? "",
|
|
90
|
-
context.refresh ? { ...target.context, cacheMode: "refresh" } : target.context).catch((
|
|
105
|
+
context.refresh ? { ...target.context, cacheMode: "refresh" } : target.context).catch(logFailure("chart-composer.headless", "Load chart live quote failed", null));
|
|
91
106
|
if (quote) quoteOverrides.set(chartQuoteOverrideKeyForTarget(target), quote);
|
|
92
107
|
}));
|
|
93
108
|
}
|
|
@@ -136,6 +151,7 @@ export async function loadChartPaneModel(
|
|
|
136
151
|
},
|
|
137
152
|
resolveCapabilitySeries: headlessCapabilityResolver(context),
|
|
138
153
|
loadFuturesPriceUnit: (symbol) => loadFuturesPriceUnit(symbol, (key) => loadFuturesContractTerms(key, context.apiClient)),
|
|
154
|
+
loadEarningsHistory: (symbol) => context.apiClient.getCloudEarningsHistory(symbol, 100),
|
|
139
155
|
loadFredSeries: async (request) => ({
|
|
140
156
|
data: await context.apiClient.getCloudFredSeries(request.seriesId, {
|
|
141
157
|
startDate: request.startDate,
|
|
@@ -206,9 +222,12 @@ export async function loadChartPaneModel(
|
|
|
206
222
|
kind, source.fieldId.split(".")[1]!, source.period === "quarterly" ? "quarterly" : "annual",
|
|
207
223
|
source.instrument.symbol,
|
|
208
224
|
).map((row) => [row.date, row.growth])) : null;
|
|
225
|
+
// A formula or a converted price prints at its legs' decimals in text; JSON keeps every digit.
|
|
226
|
+
const { valueDecimals, ...reported } = series;
|
|
209
227
|
return {
|
|
210
|
-
...
|
|
228
|
+
...reported,
|
|
211
229
|
...name ? { name } : {},
|
|
230
|
+
...valueDecimals !== undefined ? { textDecimals: valueDecimals } : {},
|
|
212
231
|
derived: !ids.has(series.id),
|
|
213
232
|
points: series.points.map((point) => ({
|
|
214
233
|
...point,
|
|
@@ -260,31 +279,46 @@ function seriesPeriodicity(dates: readonly Date[]): Periodicity | null {
|
|
|
260
279
|
* days or periods, never instants (FRED's series, a plugin's daily closes): it
|
|
261
280
|
* is dated by the day of its newest observation, with the oldest series'
|
|
262
281
|
* newest when they end apart, and by the period when every series publishes
|
|
263
|
-
* in the same one: `Aug 2026 (monthly)`, not `Sat 1 Aug 2026 00:00 UTC
|
|
264
|
-
*
|
|
282
|
+
* in the same one: `Aug 2026 (monthly)`, not `Sat 1 Aug 2026 00:00 UTC`;
|
|
283
|
+
* with the newest figure's release when its points say it (`releasedOn`):
|
|
284
|
+
* `Sep 2026, released Tue 20 Oct`. Nothing for a chart with a price series
|
|
285
|
+
* or a series observed at a time of day.
|
|
265
286
|
*/
|
|
266
|
-
export function periodChartDates(series: readonly HeadlessSeries[], spec: Pick<ChartSpec, "series">): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "periodicity"> {
|
|
287
|
+
export function periodChartDates(series: readonly HeadlessSeries[], spec: Pick<ChartSpec, "series">): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "periodicity" | "releasedOn"> {
|
|
267
288
|
if (!spec.series.length || spec.series.some(({ source }) => source.kind !== "economic" && source.kind !== "capability")) return {};
|
|
268
|
-
const ends: string
|
|
289
|
+
const ends: Array<{ day: string; releasedOn: string | null }> = [];
|
|
269
290
|
const periods = new Set<Periodicity | null>();
|
|
270
291
|
for (const entry of series) {
|
|
271
|
-
const
|
|
292
|
+
const points = entry.points.filter((point) => (point.value ?? point.close) != null);
|
|
293
|
+
const dates = points.map((point) => new Date(point.date));
|
|
272
294
|
if (!dates.length) continue;
|
|
273
295
|
// A date at midnight UTC is a day; anything else is an observation time and keeps it.
|
|
274
296
|
if (dates.some((date) => !Number.isFinite(date.getTime()) || date.getTime() % DAY_MS !== 0)) return {};
|
|
275
|
-
|
|
297
|
+
const newest = dates.reduce((latest, date, index) => (date > dates[latest]! ? index : latest), 0);
|
|
298
|
+
ends.push({ day: dates[newest]!.toISOString().slice(0, 10), releasedOn: releaseDay(points[newest]!.releasedOn) });
|
|
276
299
|
periods.add(seriesPeriodicity(dates));
|
|
277
300
|
}
|
|
278
301
|
if (!ends.length) return {};
|
|
279
|
-
ends.sort();
|
|
302
|
+
ends.sort((left, right) => left.day.localeCompare(right.day));
|
|
280
303
|
const [periodicity] = periods.size === 1 ? [...periods] : [null];
|
|
304
|
+
const asOf = ends.at(-1)!.day;
|
|
305
|
+
// The newest figure's release, when every series ending that day says the same one: `Sep 2026, released Tue 20 Oct`.
|
|
306
|
+
const releases = new Set(ends.filter((end) => end.day === asOf).map((end) => end.releasedOn));
|
|
307
|
+
const [releasedOn] = releases.size === 1 ? [...releases] : [null];
|
|
281
308
|
return {
|
|
282
|
-
asOf
|
|
283
|
-
...(ends[0] !==
|
|
309
|
+
asOf,
|
|
310
|
+
...(ends[0]!.day !== asOf ? { oldest: ends[0]!.day } : {}),
|
|
284
311
|
...(periodicity ? { periodicity } : {}),
|
|
312
|
+
...(releasedOn ? { releasedOn } : {}),
|
|
285
313
|
};
|
|
286
314
|
}
|
|
287
315
|
|
|
316
|
+
/** A point's release (`releasedOn`) as a day, when it is one. */
|
|
317
|
+
function releaseDay(value: unknown): string | null {
|
|
318
|
+
const time = value instanceof Date ? value.getTime() : typeof value === "string" || typeof value === "number" ? new Date(value).getTime() : Number.NaN;
|
|
319
|
+
return Number.isFinite(time) ? new Date(time).toISOString().slice(0, 10) : null;
|
|
320
|
+
}
|
|
321
|
+
|
|
288
322
|
/**
|
|
289
323
|
* Who a chart cites when each of its series names its own dataset (CBR's
|
|
290
324
|
* policy rates: `FRED series ECBDFR`); nothing, so Gloom Cloud, otherwise.
|
|
@@ -306,12 +340,28 @@ function seriesAttribution(series: readonly HeadlessSeries[]): Pick<HeadlessPane
|
|
|
306
340
|
* capability series alone (CHOKE's vessel transits) is a dataset, dated by its
|
|
307
341
|
* newest observation and how far behind that is.
|
|
308
342
|
*/
|
|
309
|
-
function chartFreshness(
|
|
343
|
+
function chartFreshness(
|
|
344
|
+
allSeries: readonly HeadlessSeries[],
|
|
345
|
+
spec: ChartSpec,
|
|
346
|
+
comparison?: PriceComparison | null,
|
|
347
|
+
quoteTimes: ReadonlyMap<string, number> = new Map(),
|
|
348
|
+
): HeadlessPaneFreshness {
|
|
310
349
|
const order = ["1wk", "1mo"];
|
|
350
|
+
// A leg that failed to load has no bars to date; the ones that loaded say what the chart is.
|
|
351
|
+
const loaded = allSeries.filter((entry) => entry.points.length > 0);
|
|
352
|
+
const series = loaded.length ? loaded : allSeries;
|
|
353
|
+
const visible = spec.series.filter((entry) => entry.visible !== false);
|
|
354
|
+
if (visible.length && series.every(entry => (entry as HeadlessSeries & Pick<ResolvedSeries, "nativeFrequency">).nativeFrequency === "daily")
|
|
355
|
+
&& visible.every((entry) => entry.source.kind === "security"
|
|
356
|
+
&& entry.source.period === "daily" && entry.source.fieldId.startsWith("valuation."))) {
|
|
357
|
+
const ends = series.flatMap((entry) => entry.points.at(-1)?.date ?? []).map((date) => new Date(date).toISOString().slice(0, 10)).sort();
|
|
358
|
+
return { ...DAILY_CLOSES, ...(ends.length ? { asOf: ends.at(-1)!, oldest: ends[0]! } : {}) };
|
|
359
|
+
}
|
|
311
360
|
const resolutions = series.map((entry) => (entry as HeadlessSeries & { historyResolution?: string }).historyResolution);
|
|
312
361
|
const dataset = isDatasetChart(spec);
|
|
313
362
|
if (!series.length || resolutions.some((resolution) => !resolution)) {
|
|
314
|
-
|
|
363
|
+
const dates = resolutions.some(Boolean) ? mixedChartDates(series, spec, quoteTimes) : periodChartDates(series, spec);
|
|
364
|
+
return { ...REPORTED_DATA, basis: "reported and published data", ...(dataset ? { dataset } : {}), ...dates, ...seriesAttribution(series) };
|
|
315
365
|
}
|
|
316
366
|
const coarsest = resolutions.reduce((worst, resolution) => (
|
|
317
367
|
order.indexOf(resolution!) > order.indexOf(worst!) ? resolution : worst
|
|
@@ -320,7 +370,73 @@ function chartFreshness(series: readonly HeadlessSeries[], spec: ChartSpec): Hea
|
|
|
320
370
|
// A history: its first bars are not stale data, so the line dates it by the bar still forming alone.
|
|
321
371
|
if (forming) return { ...barHistoryFreshness(coarsest), periodToDate: forming, oldest: null };
|
|
322
372
|
const closedDay = closedPriceBarDay(series);
|
|
323
|
-
|
|
373
|
+
// A comparison whose newest point is a session still trading is not a day's closes.
|
|
374
|
+
const basis = coarsest === "1d" && priceComparisonEndsIntraday(comparison) ? { basis: LATEST_INTRADAY_TEXT } : {};
|
|
375
|
+
// Daily bars are dated by the time of the newest point: a closed session's day, or when a session still trading was last quoted.
|
|
376
|
+
const asOf = coarsest === "1d" ? newestDailyPoint(series, closedDay, quoteTimes) : closedDay;
|
|
377
|
+
return { ...barHistoryFreshness(coarsest), ...basis, ...(asOf ? { asOf } : {}) };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* The dates of a chart of price bars beside reported series (`G DHI,
|
|
382
|
+
* FRED:PERMIT`): as of its newest daily point, as a chart of the prices alone
|
|
383
|
+
* is, and when the reported series end before it, the oldest is their newest
|
|
384
|
+
* period: `Fri 23 Oct 2026 (oldest Sep 2026)`. Bars of a time of day keep the
|
|
385
|
+
* line's own dating; only the oldest is named.
|
|
386
|
+
*/
|
|
387
|
+
function mixedChartDates(series: readonly HeadlessSeries[], spec: ChartSpec, quoteTimes: ReadonlyMap<string, number>): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "oldestPeriodicity"> {
|
|
388
|
+
const withResolution = series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution">>>;
|
|
389
|
+
const priced = withResolution.filter((entry) => entry.historyResolution);
|
|
390
|
+
const reported = withResolution.filter((entry) => !entry.historyResolution);
|
|
391
|
+
const reportedIds = new Set(reported.map((entry) => entry.id));
|
|
392
|
+
const ends = periodChartDates(reported, { series: spec.series.filter((entry) => reportedIds.has(entry.id)) });
|
|
393
|
+
const daily = priced.every((entry) => ["1d", "1wk", "1mo"].includes(entry.historyResolution!));
|
|
394
|
+
const asOf = !daily ? null
|
|
395
|
+
: priced.every((entry) => entry.historyResolution === "1d") ? newestDailyPoint(priced, closedPriceBarDay(priced), quoteTimes)
|
|
396
|
+
: closedPriceBarDay(priced);
|
|
397
|
+
const newestPrice = asOf ?? priced.flatMap((entry) => entry.points.at(-1)?.date ?? []).map((date) => new Date(date).toISOString()).sort().at(-1);
|
|
398
|
+
const oldest = typeof ends.asOf === "string" && newestPrice && ends.asOf < newestPrice.slice(0, 10) ? ends.asOf : null;
|
|
399
|
+
return {
|
|
400
|
+
...(asOf ? { asOf } : {}),
|
|
401
|
+
...(oldest ? { oldest, oldestPeriodicity: ends.periodicity ?? null } : {}),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* When the newest point of a chart of daily bars is from: for a session still
|
|
407
|
+
* trading, the time its listing was last quoted (`Fri 23 Oct 2026 15:42 UTC`),
|
|
408
|
+
* or its day when no quote of that day is known; else the day of the newest
|
|
409
|
+
* closed session (`closedDay`). Never the midnight a daily bar is dated at.
|
|
410
|
+
*/
|
|
411
|
+
function newestDailyPoint(series: readonly HeadlessSeries[], closedDay: string | null, quoteTimes: ReadonlyMap<string, number>): string | null {
|
|
412
|
+
const now = Date.now();
|
|
413
|
+
const stamps = closedDay ? [{ time: Date.parse(`${closedDay}T00:00:00Z`), text: closedDay }] : [];
|
|
414
|
+
for (const entry of series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis" | "listing">>>) {
|
|
415
|
+
const bar = entry.historyResolution === "1d" ? newestBar(entry) : null;
|
|
416
|
+
if (!bar || closedHistoryBarDay("1d", bar.day, bar.venue, now)) continue;
|
|
417
|
+
const quoted = quoteTimes.get(entry.id);
|
|
418
|
+
const dayStart = Date.parse(`${bar.day}T00:00:00Z`);
|
|
419
|
+
stamps.push(quoted != null && quoted >= dayStart && quoted <= now + 10 * 60_000
|
|
420
|
+
? { time: quoted, text: new Date(quoted).toISOString() }
|
|
421
|
+
: { time: dayStart, text: bar.day });
|
|
422
|
+
}
|
|
423
|
+
return stamps.reduce<{ time: number; text: string } | null>((newest, stamp) => (!newest || stamp.time > newest.time ? stamp : newest), null)?.text ?? null;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** When each security series' listing was last quoted, by series id, from the quotes the chart was read with. */
|
|
427
|
+
function chartQuoteTimes(model: Pick<ChartPaneModel, "spec" | "snapshot">): Map<string, number> {
|
|
428
|
+
const times = new Map<string, number>();
|
|
429
|
+
for (const entry of model.spec.series) {
|
|
430
|
+
if (entry.source.kind !== "security") continue;
|
|
431
|
+
const { instrument } = entry.source;
|
|
432
|
+
const key = publicTickerKey(instrument.symbol, instrument.exchange);
|
|
433
|
+
const instrumentKey = snapshotInstrumentKey(instrument);
|
|
434
|
+
const data = model.snapshot.financials.find(([candidate]) => candidate === key)?.[1]
|
|
435
|
+
?? model.snapshot.instrumentFinancials?.find((item) => snapshotInstrumentKey(item.instrument) === instrumentKey)?.financials;
|
|
436
|
+
const time = data?.quote?.lastUpdated;
|
|
437
|
+
if (typeof time === "number" && Number.isFinite(time)) times.set(entry.id, time);
|
|
438
|
+
}
|
|
439
|
+
return times;
|
|
324
440
|
}
|
|
325
441
|
|
|
326
442
|
/** A series' venue and the day its newest bar starts, as the forming and closed bar checks read them. */
|
|
@@ -332,9 +448,9 @@ function newestBar(entry: HeadlessSeries & Partial<Pick<ResolvedSeries, "history
|
|
|
332
448
|
}
|
|
333
449
|
|
|
334
450
|
/**
|
|
335
|
-
* The day the newest complete weekly or monthly bar of the chart closed
|
|
336
|
-
* the latest across its series: a week of bars dated Mon 12 Oct 2026 is
|
|
337
|
-
* Fri 16 Oct, the day their closes are from. Null for
|
|
451
|
+
* The day the newest complete daily, weekly or monthly bar of the chart closed
|
|
452
|
+
* on, the latest across its series: a week of bars dated Mon 12 Oct 2026 is
|
|
453
|
+
* dated Fri 16 Oct, the day their closes are from. Null for intraday bars.
|
|
338
454
|
*/
|
|
339
455
|
function closedPriceBarDay(series: readonly HeadlessSeries[]): string | null {
|
|
340
456
|
const days = (series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis" | "listing">>>).flatMap((entry) => {
|
|
@@ -360,6 +476,48 @@ function formingPriceBar(series: readonly HeadlessSeries[]): BarPeriodToDate | n
|
|
|
360
476
|
return null;
|
|
361
477
|
}
|
|
362
478
|
|
|
479
|
+
const REGULAR_OPEN_MINUTE = 9 * 60 + 30;
|
|
480
|
+
const REGULAR_CLOSE_MINUTE = 16 * 60;
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* GIP asks for a US listing's regular session only, so an 08:30 New York
|
|
484
|
+
* release is not in its bars. Said when every bar of a US stock venue's
|
|
485
|
+
* window starts from the 09:30 open to the 16:00 close; null for another
|
|
486
|
+
* venue, a future, or bars outside those hours.
|
|
487
|
+
*/
|
|
488
|
+
function regularSessionNotice(windows: ReadonlyArray<{ symbol: string; exchange: string; points: ReadonlyArray<Pick<PricePoint, "date">> }>): string | null {
|
|
489
|
+
const us = windows.filter(({ symbol, exchange, points }) => points.length > 0 && isUsListingExchange(exchange) && futuresSessionOpenMinute(symbol, exchange) == null);
|
|
490
|
+
if (!us.length) return null;
|
|
491
|
+
const regular = us.every(({ points }) => points.every(({ date }) => {
|
|
492
|
+
const { hour, minute } = zonedDateTimeParts(new Date(date).getTime(), "America/New_York");
|
|
493
|
+
const at = hour * 60 + minute;
|
|
494
|
+
return at >= REGULAR_OPEN_MINUTE && at <= REGULAR_CLOSE_MINUTE;
|
|
495
|
+
}));
|
|
496
|
+
return regular ? "Regular session only, from the 09:30 New York open: pre-market and after-hours bars are not included." : null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Intraday bars as traded: each price the decimal the feed's float stands
|
|
501
|
+
* for (85.1, not 85.099998; a sub-penny print such as 86.3775 stays), as
|
|
502
|
+
* `history` writes them. A `value` that only repeats each bar's close is
|
|
503
|
+
* marked so, and `--csv` writes Close alone.
|
|
504
|
+
*/
|
|
505
|
+
function tradedBars(series: HeadlessSeries): HeadlessSeries {
|
|
506
|
+
if (!series.points.some((point) => point.close != null)) return series;
|
|
507
|
+
const valueIsClose = series.points.every((point) => point.value == null || point.value === point.close);
|
|
508
|
+
const traded = (price: number | null | undefined) => price == null || !Number.isFinite(price) ? price : cleanFloat32Price(price);
|
|
509
|
+
return {
|
|
510
|
+
...series,
|
|
511
|
+
...(valueIsClose ? { valueIsClose } : {}),
|
|
512
|
+
points: series.points.map((point) => {
|
|
513
|
+
const bar = { ...point };
|
|
514
|
+
for (const field of ["open", "high", "low", "close"] as const) if (point[field] !== undefined) bar[field] = traded(point[field]);
|
|
515
|
+
if (point.value != null && valueIsClose) bar.value = bar.close;
|
|
516
|
+
return bar;
|
|
517
|
+
}),
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
363
521
|
/** What a chart series was asked as: a listing as typed (`USDZAR=X`, `SAN:EPA`), a FRED series by its ID. */
|
|
364
522
|
function askedSymbol(source: ChartSeriesSource): string {
|
|
365
523
|
switch (source.kind) {
|
|
@@ -374,8 +532,8 @@ function askedSymbol(source: ChartSeriesSource): string {
|
|
|
374
532
|
* observes (`quarterly`), else how far apart its points are (a FRED series
|
|
375
533
|
* charts at its own frequency, `daily` for DEXSFUS).
|
|
376
534
|
*/
|
|
377
|
-
function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "nativeFrequency"> & Pick<HeadlessSeries, "points">): string | undefined {
|
|
378
|
-
if (series.historyResolution) return series.historyResolution;
|
|
535
|
+
function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "barSize" | "nativeFrequency"> & Pick<HeadlessSeries, "points">): string | undefined {
|
|
536
|
+
if (series.historyResolution) return series.barSize ?? series.historyResolution;
|
|
379
537
|
if (series.nativeFrequency && series.nativeFrequency !== "auto") return series.nativeFrequency;
|
|
380
538
|
const spacing = inferSeriesFrequency(series.points.map((point) => ({ date: point.date, value: 0 })));
|
|
381
539
|
return spacing === "irregular" ? undefined : spacing;
|
|
@@ -383,8 +541,8 @@ function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "nati
|
|
|
383
541
|
|
|
384
542
|
/** A dropped resolution, as JSON's `metadata.resolution` states it. */
|
|
385
543
|
export interface ChartResolutionDrop {
|
|
386
|
-
requested:
|
|
387
|
-
returned:
|
|
544
|
+
requested: ChartBarSize;
|
|
545
|
+
returned: ChartBarSize;
|
|
388
546
|
range: string;
|
|
389
547
|
reason: string;
|
|
390
548
|
}
|
|
@@ -398,18 +556,21 @@ export interface ChartResolutionDrop {
|
|
|
398
556
|
export function chartResolutionDrop(
|
|
399
557
|
requested: ChartResolution,
|
|
400
558
|
viewport: Pick<ChartViewportSpec, "range" | "dateWindow">,
|
|
401
|
-
series: ReadonlyArray<Pick<ResolvedSeries, "historyResolution"> & { symbol?: string }>,
|
|
559
|
+
series: ReadonlyArray<Pick<ResolvedSeries, "historyResolution" | "barSize"> & { symbol?: string }>,
|
|
402
560
|
support: ChartResolutionResult["resolutionSupport"],
|
|
403
561
|
): { drop: ChartResolutionDrop; warning: string } | null {
|
|
404
562
|
if (requested === "auto") return null;
|
|
405
|
-
const
|
|
406
|
-
const
|
|
563
|
+
const servedIn = (entry: Pick<ResolvedSeries, "historyResolution" | "barSize">) => entry.historyResolution ? entry.barSize ?? entry.historyResolution : null;
|
|
564
|
+
const dropped = series.filter((entry) => servedIn(entry) && servedIn(entry) !== requested);
|
|
565
|
+
const returned = dropped[0] ? servedIn(dropped[0]) : null;
|
|
407
566
|
if (!returned) return null;
|
|
408
567
|
const range = viewport.dateWindow ? "this window" : viewport.range;
|
|
409
568
|
const symbols = [...new Set(dropped.flatMap((entry) => entry.symbol ? [entry.symbol] : []))];
|
|
410
|
-
|
|
569
|
+
// A size built from shorter bars reaches back as far as those do.
|
|
570
|
+
const source = chartBarSizeSource(requested, support ?? []);
|
|
571
|
+
const maxRange = support?.length ? getSupportMaxRange(support, source) : null;
|
|
411
572
|
const reason = !support?.length ? `the source returned ${returned} bars`
|
|
412
|
-
: maxRange == null ? `the source does not serve ${requested} bars`
|
|
573
|
+
: maxRange == null ? `the source does not serve ${source === requested ? requested : `the ${source} bars ${requested} bars are built from`}`
|
|
413
574
|
: `${requested} bars go back ${maxRange} at most`;
|
|
414
575
|
const on = symbols.length > 0 ? ` on ${symbols.join(" and ")}` : "";
|
|
415
576
|
return {
|
|
@@ -436,19 +597,79 @@ export function argumentWithListing(argument: string, symbol: string, key: strin
|
|
|
436
597
|
return named ? legs.join("") : key;
|
|
437
598
|
}
|
|
438
599
|
|
|
600
|
+
/**
|
|
601
|
+
* A FRED series id typed where a ticker goes (`fn G DFII10`), as the chart of
|
|
602
|
+
* FRED:DFII10: the catalog lists it, no listing answers to it, and the quote
|
|
603
|
+
* source says it is not a ticker. A real ticker of the same letters, read as
|
|
604
|
+
* a listing or quoted, still charts as the ticker; null then, and for any
|
|
605
|
+
* other series.
|
|
606
|
+
*/
|
|
607
|
+
export async function bareFredSeries(
|
|
608
|
+
series: ChartSeriesSpec,
|
|
609
|
+
readListing: () => Promise<unknown>,
|
|
610
|
+
context: Pick<HeadlessPaneContext, "marketData" | "catalogSeriesName">,
|
|
611
|
+
): Promise<ChartSeriesSpec | null> {
|
|
612
|
+
const { source } = series;
|
|
613
|
+
if (source.kind !== "security" || source.instrument.exchange || source.instrument.instrument || source.fieldId !== CHART_FIELD_IDS.price) return null;
|
|
614
|
+
const id = source.instrument.symbol.trim().toUpperCase();
|
|
615
|
+
const expression = `FRED:${id}`;
|
|
616
|
+
const label = /^[A-Z0-9]+$/.test(id)
|
|
617
|
+
? context.catalogSeriesName?.(expression) ?? getSharedRegistry()?.series?.findByExpression(expression)?.definition.name
|
|
618
|
+
: undefined;
|
|
619
|
+
if (!label || await readListing()) return null;
|
|
620
|
+
const failure = await Promise.resolve().then(() => context.marketData.getQuote(id, ""))
|
|
621
|
+
.then((quote) => quote ? null : `Not a ticker: ${id}.`, (error: unknown) => error instanceof Error ? error.message : String(error));
|
|
622
|
+
if (!failure || !notATickerSymbol(failure)) return null;
|
|
623
|
+
const fred = buildSeriesSpec({ kind: "economic", provider: "fred", seriesId: id, label }, 0);
|
|
624
|
+
return { ...fred, id: series.id, transform: series.transform, axis: series.axis, panelId: series.panelId };
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* The compared tickers whose fund facts could state a daily objective: each
|
|
629
|
+
* but those a quote already cached says are not funds (a stock, an index).
|
|
630
|
+
* The facts are read through the ETF pane's cache, so a ticker read once
|
|
631
|
+
* is not asked again for a day.
|
|
632
|
+
*/
|
|
633
|
+
async function possibleFundTickers(spec: ChartSpec, context: HeadlessPaneContext): Promise<string[]> {
|
|
634
|
+
const tickers = comparedFundTickers(spec);
|
|
635
|
+
const read = context.marketData.getCachedFinancialsForTargets;
|
|
636
|
+
const cached = tickers.length && read
|
|
637
|
+
? await Promise.resolve().then(() => read.call(context.marketData, tickers.map((symbol) => ({ symbol })), { allowExpired: true, includeStaleQuotes: true }))
|
|
638
|
+
.catch(logFailure("chart-composer.headless", "Read cached chart fund types failed", null))
|
|
639
|
+
: null;
|
|
640
|
+
return tickers.filter((ticker) => {
|
|
641
|
+
const financials = cached?.get(ticker);
|
|
642
|
+
const kind = classifyInstrumentType(financials?.quote?.instrumentType ?? financials?.quoteMetadata?.instrumentType);
|
|
643
|
+
return kind === null || kind === "fund";
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
|
|
439
647
|
export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneDefinition<"series"> {
|
|
440
648
|
return {
|
|
441
649
|
...paneSchemas[template],
|
|
442
650
|
shape: "series",
|
|
443
651
|
async load(args, context) {
|
|
444
652
|
const intradayHistories: ChartPaneModel["snapshot"]["intradayHistories"] = [];
|
|
445
|
-
const
|
|
446
|
-
if (!
|
|
653
|
+
const saved = parseChartSpec(context.settings?.chartSpec);
|
|
654
|
+
if (!saved) throw new Error("The chart specification is invalid.");
|
|
655
|
+
// A leveraged or inverse fund compared with anything draws its daily objective beside it.
|
|
656
|
+
const parsed = template === "comparison-chart-pane" && mayDrawDailyObjective(saved)
|
|
657
|
+
? withLeverageOverlay(saved, await loadDailyObjectives(
|
|
658
|
+
await possibleFundTickers(saved, context),
|
|
659
|
+
async (ticker, signal) => (await loadFundFacts(ticker, false, { client: context.apiClient, signal })).payload,
|
|
660
|
+
{ signal: context.signal },
|
|
661
|
+
))
|
|
662
|
+
: saved;
|
|
447
663
|
// A bare symbol is the listing `quote` reads it as: BDI, which two companies list, asks which,
|
|
448
664
|
// as `quote BDI` does, instead of charting whichever line a source picked.
|
|
449
665
|
const reads = new Map<string, ReturnType<typeof readSeriesListing>>();
|
|
666
|
+
const listings = new Map<string, Promise<Awaited<ReturnType<NonNullable<typeof context.resolveListing>>> | null>>();
|
|
667
|
+
const readListing = (symbol: string) => {
|
|
668
|
+
if (!listings.has(symbol)) listings.set(symbol, context.resolveListing?.(symbol, (key) => argumentWithListing(args.rawArgument, symbol, key)) ?? Promise.resolve(null));
|
|
669
|
+
return listings.get(symbol)!;
|
|
670
|
+
};
|
|
450
671
|
const readSeriesListing = async (symbol: string): Promise<{ symbol: string; exchange?: string } | null> => {
|
|
451
|
-
const read = await
|
|
672
|
+
const read = await readListing(symbol);
|
|
452
673
|
if (read) return { symbol: read.symbol, ...read.exchange ? { exchange: read.exchange } : {} };
|
|
453
674
|
return context.resolveInstrument ? context.resolveInstrument(symbol) : null;
|
|
454
675
|
};
|
|
@@ -457,6 +678,9 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
457
678
|
series: await Promise.all(parsed.series.map(async (series) => {
|
|
458
679
|
if (series.source.kind !== "security" || series.source.instrument.exchange) return series;
|
|
459
680
|
const { symbol } = series.source.instrument;
|
|
681
|
+
// A FRED id no ticker answers to (DFII10) is its FRED series; an intraday chart has none.
|
|
682
|
+
const fred = template === "graph-intraday-price-pane" ? null : await bareFredSeries(series, () => readListing(symbol), context);
|
|
683
|
+
if (fred) return fred;
|
|
460
684
|
if (!reads.has(symbol)) reads.set(symbol, readSeriesListing(symbol));
|
|
461
685
|
const instrument = await reads.get(symbol)!;
|
|
462
686
|
return instrument ? { ...series, source: { ...series.source, instrument: { ...series.source.instrument, ...instrument } } } : series;
|
|
@@ -469,7 +693,7 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
469
693
|
? intersectChartResolutionSupport(await Promise.all([...instruments.values()].map(async (target) => (
|
|
470
694
|
normalizeChartResolutionSupport(await Promise.resolve(context.marketData.getChartResolutionSupport!(
|
|
471
695
|
target.symbol, target.exchange ?? "", { brokerId: target.brokerId, brokerInstanceId: target.brokerInstanceId, instrument: target.instrument },
|
|
472
|
-
)).catch((
|
|
696
|
+
)).catch(logFailure("chart-composer.headless", "Read intraday resolution support failed", [])))
|
|
473
697
|
))))
|
|
474
698
|
: [];
|
|
475
699
|
const request = resolveIntradayRequest({
|
|
@@ -534,20 +758,25 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
534
758
|
const asked = new Map(parsed.series.map((series) => [series.id, askedSymbol(series.source)]));
|
|
535
759
|
model.series = model.series.map((series) => {
|
|
536
760
|
const symbol = asked.get(series.id);
|
|
537
|
-
const interval = servedInterval(series as HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "nativeFrequency">);
|
|
761
|
+
const interval = servedInterval(series as HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "barSize" | "nativeFrequency">);
|
|
538
762
|
return { ...series, ...(symbol ? { symbol } : {}), ...(interval ? { interval } : {}) };
|
|
539
763
|
});
|
|
764
|
+
if (template === "graph-intraday-price-pane") {
|
|
765
|
+
model.series = model.series.map(tradedBars);
|
|
766
|
+
const regular = regularSessionNotice(intradayHistories.map((window) => ({ ...window, exchange: listingExchange(window.symbol, window.exchange) })));
|
|
767
|
+
if (regular) model.metadata = { ...model.metadata, notices: [...(Array.isArray(model.metadata?.notices) ? model.metadata.notices : []), regular] };
|
|
768
|
+
}
|
|
540
769
|
const dropped = chartResolutionDrop(
|
|
541
770
|
parsed.viewport.resolution,
|
|
542
771
|
model.spec.viewport,
|
|
543
|
-
(model.series as Array<HeadlessSeries & Pick<ResolvedSeries, "historyResolution"> & { derived?: boolean }>).filter((series) => !series.derived),
|
|
772
|
+
(model.series as Array<HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "barSize"> & { derived?: boolean }>).filter((series) => !series.derived),
|
|
544
773
|
model.chart.resolutionSupport,
|
|
545
774
|
);
|
|
546
775
|
if (dropped) {
|
|
547
776
|
model.warnings = [...model.warnings ?? [], dropped.warning];
|
|
548
777
|
model.metadata = { ...model.metadata, resolution: dropped.drop };
|
|
549
778
|
}
|
|
550
|
-
model.freshness = chartFreshness(model.series, model.spec);
|
|
779
|
+
model.freshness = chartFreshness(model.series, model.spec, model.chart.priceComparison, chartQuoteTimes(model));
|
|
551
780
|
const priceDomainFailures = intradayHistories.flatMap(({ symbol, exchange, priceDomainFailure }) =>
|
|
552
781
|
priceDomainFailure ? [{ symbol, exchange, ...priceDomainFailure }] : []);
|
|
553
782
|
if (priceDomainFailures.length) {
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from "./catalog-inventory";
|
|
23
23
|
import {
|
|
24
24
|
CHART_INTERACTION_VIEWPORT_SETTING_KEY,
|
|
25
|
+
CHART_LEVERAGE_PENDING_SETTING_KEY,
|
|
25
26
|
CHART_PINNED_MOMENT_SETTING_KEY,
|
|
26
27
|
CHART_SPEC_SETTING_KEY,
|
|
27
28
|
parseChartInteractionViewport,
|
|
@@ -259,6 +260,7 @@ function securityTemplate({
|
|
|
259
260
|
minimumSymbols,
|
|
260
261
|
build,
|
|
261
262
|
keywords = [],
|
|
263
|
+
settings,
|
|
262
264
|
}: {
|
|
263
265
|
id: Parameters<typeof chartHeadless>[0];
|
|
264
266
|
prefix: "GP" | "GIP" | "CMP" | "GF" | "GE";
|
|
@@ -272,6 +274,8 @@ function securityTemplate({
|
|
|
272
274
|
argKind: "ticker" | "ticker-list";
|
|
273
275
|
minimumSymbols: number;
|
|
274
276
|
build: (symbols: string[]) => ChartSpec;
|
|
277
|
+
/** Pane settings the template opens with besides the chart. */
|
|
278
|
+
settings?: Record<string, unknown>;
|
|
275
279
|
}): PaneTemplateDef {
|
|
276
280
|
return {
|
|
277
281
|
id,
|
|
@@ -296,7 +300,9 @@ function securityTemplate({
|
|
|
296
300
|
canCreate: (context, options) => templateSymbols(context, options).length >= minimumSymbols,
|
|
297
301
|
createInstance: (context, options) => {
|
|
298
302
|
const symbols = templateSymbols(context, options);
|
|
299
|
-
|
|
303
|
+
if (symbols.length < minimumSymbols) return null;
|
|
304
|
+
const instance = selectedInstanceFor(build(symbols), prefix, context, options);
|
|
305
|
+
return settings ? { ...instance, settings: { ...instance.settings, ...settings } } : instance;
|
|
300
306
|
},
|
|
301
307
|
};
|
|
302
308
|
}
|
|
@@ -399,6 +405,7 @@ const chartComposerTemplates: PaneTemplateDef[] = [
|
|
|
399
405
|
"positioning",
|
|
400
406
|
],
|
|
401
407
|
shortcut: { prefix: "CAT", argPlaceholder: "query", argKind: "text", argOptional: true },
|
|
408
|
+
reportFreshness: { status: "not-a-feed", basis: "series catalog" },
|
|
402
409
|
canCreate: () => true,
|
|
403
410
|
createInstance: (_context, options) => {
|
|
404
411
|
const query = options?.arg?.trim() ?? options?.values?.query?.trim() ?? "";
|
|
@@ -446,10 +453,13 @@ const chartComposerTemplates: PaneTemplateDef[] = [
|
|
|
446
453
|
prefix: "CMP",
|
|
447
454
|
aliases: ["COMP", "TRA"],
|
|
448
455
|
label: "Comparison Chart",
|
|
449
|
-
description: "Compare price returns over shared observation dates for two or more tickers.",
|
|
456
|
+
description: "Compare price returns over shared observation dates for two or more tickers. A leveraged or inverse fund gets its daily objective drawn from its index fund (3× daily QQQ beside TQQQ) and its decay against it.",
|
|
457
|
+
// Leveraged and inverse funds: the daily line and the decay come with the comparison.
|
|
458
|
+
keywords: ["leveraged", "inverse", "decay", "daily-reset", "daily reset", "volatility decay"],
|
|
450
459
|
argKind: "ticker-list",
|
|
451
460
|
minimumSymbols: 2,
|
|
452
461
|
build: buildComparisonChartPreset,
|
|
462
|
+
settings: { [CHART_LEVERAGE_PENDING_SETTING_KEY]: true },
|
|
453
463
|
}),
|
|
454
464
|
securityTemplate({
|
|
455
465
|
id: "fundamental-graph-pane",
|