gloomberb 0.18.3 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +84 -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 +22 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +21 -4
- 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 +90 -2
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/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 +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1117 -264
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +192 -47
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +300 -41
- 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 +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +24 -11
- package/src/cli/pane-functions/index.ts +18 -16
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +47 -10
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +61 -16
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +111 -22
- 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 +373 -16
- 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 +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +305 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +13 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/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 +7 -6
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +29 -12
- package/src/i18n/ja.ts +29 -12
- package/src/i18n/ko.ts +29 -12
- package/src/i18n/zh-cn.ts +29 -12
- package/src/i18n/zh-tw.ts +29 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +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 +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +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 +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
- 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 +1 -1
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +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 +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +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 +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +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 +45 -10
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +6 -1
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +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 +4 -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 +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- 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/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/view.tsx +10 -10
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- 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 +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +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 +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +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/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- 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 +2 -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/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/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +5 -4
- package/src/plugins/builtin/vol-surface/headless.ts +12 -3
- package/src/plugins/builtin/vol-surface/model.ts +4 -2
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/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/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +46 -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/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +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/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 +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +14 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +76 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/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 +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +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
|
@@ -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,7 +31,10 @@ 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
40
|
import { barHistoryFreshness, REPORTED_DATA } from "../shared/report-freshness";
|
|
@@ -32,6 +42,11 @@ 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
|
}
|
|
@@ -260,31 +275,46 @@ function seriesPeriodicity(dates: readonly Date[]): Periodicity | null {
|
|
|
260
275
|
* days or periods, never instants (FRED's series, a plugin's daily closes): it
|
|
261
276
|
* is dated by the day of its newest observation, with the oldest series'
|
|
262
277
|
* 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
|
-
*
|
|
278
|
+
* in the same one: `Aug 2026 (monthly)`, not `Sat 1 Aug 2026 00:00 UTC`;
|
|
279
|
+
* with the newest figure's release when its points say it (`releasedOn`):
|
|
280
|
+
* `Sep 2026, released Tue 20 Oct`. Nothing for a chart with a price series
|
|
281
|
+
* or a series observed at a time of day.
|
|
265
282
|
*/
|
|
266
|
-
export function periodChartDates(series: readonly HeadlessSeries[], spec: Pick<ChartSpec, "series">): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "periodicity"> {
|
|
283
|
+
export function periodChartDates(series: readonly HeadlessSeries[], spec: Pick<ChartSpec, "series">): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "periodicity" | "releasedOn"> {
|
|
267
284
|
if (!spec.series.length || spec.series.some(({ source }) => source.kind !== "economic" && source.kind !== "capability")) return {};
|
|
268
|
-
const ends: string
|
|
285
|
+
const ends: Array<{ day: string; releasedOn: string | null }> = [];
|
|
269
286
|
const periods = new Set<Periodicity | null>();
|
|
270
287
|
for (const entry of series) {
|
|
271
|
-
const
|
|
288
|
+
const points = entry.points.filter((point) => (point.value ?? point.close) != null);
|
|
289
|
+
const dates = points.map((point) => new Date(point.date));
|
|
272
290
|
if (!dates.length) continue;
|
|
273
291
|
// A date at midnight UTC is a day; anything else is an observation time and keeps it.
|
|
274
292
|
if (dates.some((date) => !Number.isFinite(date.getTime()) || date.getTime() % DAY_MS !== 0)) return {};
|
|
275
|
-
|
|
293
|
+
const newest = dates.reduce((latest, date, index) => (date > dates[latest]! ? index : latest), 0);
|
|
294
|
+
ends.push({ day: dates[newest]!.toISOString().slice(0, 10), releasedOn: releaseDay(points[newest]!.releasedOn) });
|
|
276
295
|
periods.add(seriesPeriodicity(dates));
|
|
277
296
|
}
|
|
278
297
|
if (!ends.length) return {};
|
|
279
|
-
ends.sort();
|
|
298
|
+
ends.sort((left, right) => left.day.localeCompare(right.day));
|
|
280
299
|
const [periodicity] = periods.size === 1 ? [...periods] : [null];
|
|
300
|
+
const asOf = ends.at(-1)!.day;
|
|
301
|
+
// The newest figure's release, when every series ending that day says the same one: `Sep 2026, released Tue 20 Oct`.
|
|
302
|
+
const releases = new Set(ends.filter((end) => end.day === asOf).map((end) => end.releasedOn));
|
|
303
|
+
const [releasedOn] = releases.size === 1 ? [...releases] : [null];
|
|
281
304
|
return {
|
|
282
|
-
asOf
|
|
283
|
-
...(ends[0] !==
|
|
305
|
+
asOf,
|
|
306
|
+
...(ends[0]!.day !== asOf ? { oldest: ends[0]!.day } : {}),
|
|
284
307
|
...(periodicity ? { periodicity } : {}),
|
|
308
|
+
...(releasedOn ? { releasedOn } : {}),
|
|
285
309
|
};
|
|
286
310
|
}
|
|
287
311
|
|
|
312
|
+
/** A point's release (`releasedOn`) as a day, when it is one. */
|
|
313
|
+
function releaseDay(value: unknown): string | null {
|
|
314
|
+
const time = value instanceof Date ? value.getTime() : typeof value === "string" || typeof value === "number" ? new Date(value).getTime() : Number.NaN;
|
|
315
|
+
return Number.isFinite(time) ? new Date(time).toISOString().slice(0, 10) : null;
|
|
316
|
+
}
|
|
317
|
+
|
|
288
318
|
/**
|
|
289
319
|
* Who a chart cites when each of its series names its own dataset (CBR's
|
|
290
320
|
* policy rates: `FRED series ECBDFR`); nothing, so Gloom Cloud, otherwise.
|
|
@@ -306,12 +336,21 @@ function seriesAttribution(series: readonly HeadlessSeries[]): Pick<HeadlessPane
|
|
|
306
336
|
* capability series alone (CHOKE's vessel transits) is a dataset, dated by its
|
|
307
337
|
* newest observation and how far behind that is.
|
|
308
338
|
*/
|
|
309
|
-
function chartFreshness(
|
|
339
|
+
function chartFreshness(
|
|
340
|
+
allSeries: readonly HeadlessSeries[],
|
|
341
|
+
spec: ChartSpec,
|
|
342
|
+
comparison?: PriceComparison | null,
|
|
343
|
+
quoteTimes: ReadonlyMap<string, number> = new Map(),
|
|
344
|
+
): HeadlessPaneFreshness {
|
|
310
345
|
const order = ["1wk", "1mo"];
|
|
346
|
+
// A leg that failed to load has no bars to date; the ones that loaded say what the chart is.
|
|
347
|
+
const loaded = allSeries.filter((entry) => entry.points.length > 0);
|
|
348
|
+
const series = loaded.length ? loaded : allSeries;
|
|
311
349
|
const resolutions = series.map((entry) => (entry as HeadlessSeries & { historyResolution?: string }).historyResolution);
|
|
312
350
|
const dataset = isDatasetChart(spec);
|
|
313
351
|
if (!series.length || resolutions.some((resolution) => !resolution)) {
|
|
314
|
-
|
|
352
|
+
const dates = resolutions.some(Boolean) ? mixedChartDates(series, spec, quoteTimes) : periodChartDates(series, spec);
|
|
353
|
+
return { ...REPORTED_DATA, basis: "reported and published data", ...(dataset ? { dataset } : {}), ...dates, ...seriesAttribution(series) };
|
|
315
354
|
}
|
|
316
355
|
const coarsest = resolutions.reduce((worst, resolution) => (
|
|
317
356
|
order.indexOf(resolution!) > order.indexOf(worst!) ? resolution : worst
|
|
@@ -320,7 +359,73 @@ function chartFreshness(series: readonly HeadlessSeries[], spec: ChartSpec): Hea
|
|
|
320
359
|
// A history: its first bars are not stale data, so the line dates it by the bar still forming alone.
|
|
321
360
|
if (forming) return { ...barHistoryFreshness(coarsest), periodToDate: forming, oldest: null };
|
|
322
361
|
const closedDay = closedPriceBarDay(series);
|
|
323
|
-
|
|
362
|
+
// A comparison whose newest point is a session still trading is not a day's closes.
|
|
363
|
+
const basis = coarsest === "1d" && priceComparisonEndsIntraday(comparison) ? { basis: LATEST_INTRADAY_TEXT } : {};
|
|
364
|
+
// 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.
|
|
365
|
+
const asOf = coarsest === "1d" ? newestDailyPoint(series, closedDay, quoteTimes) : closedDay;
|
|
366
|
+
return { ...barHistoryFreshness(coarsest), ...basis, ...(asOf ? { asOf } : {}) };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* The dates of a chart of price bars beside reported series (`G DHI,
|
|
371
|
+
* FRED:PERMIT`): as of its newest daily point, as a chart of the prices alone
|
|
372
|
+
* is, and when the reported series end before it, the oldest is their newest
|
|
373
|
+
* period: `Fri 23 Oct 2026 (oldest Sep 2026)`. Bars of a time of day keep the
|
|
374
|
+
* line's own dating; only the oldest is named.
|
|
375
|
+
*/
|
|
376
|
+
function mixedChartDates(series: readonly HeadlessSeries[], spec: ChartSpec, quoteTimes: ReadonlyMap<string, number>): Pick<HeadlessPaneFreshness, "asOf" | "oldest" | "oldestPeriodicity"> {
|
|
377
|
+
const withResolution = series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution">>>;
|
|
378
|
+
const priced = withResolution.filter((entry) => entry.historyResolution);
|
|
379
|
+
const reported = withResolution.filter((entry) => !entry.historyResolution);
|
|
380
|
+
const reportedIds = new Set(reported.map((entry) => entry.id));
|
|
381
|
+
const ends = periodChartDates(reported, { series: spec.series.filter((entry) => reportedIds.has(entry.id)) });
|
|
382
|
+
const daily = priced.every((entry) => ["1d", "1wk", "1mo"].includes(entry.historyResolution!));
|
|
383
|
+
const asOf = !daily ? null
|
|
384
|
+
: priced.every((entry) => entry.historyResolution === "1d") ? newestDailyPoint(priced, closedPriceBarDay(priced), quoteTimes)
|
|
385
|
+
: closedPriceBarDay(priced);
|
|
386
|
+
const newestPrice = asOf ?? priced.flatMap((entry) => entry.points.at(-1)?.date ?? []).map((date) => new Date(date).toISOString()).sort().at(-1);
|
|
387
|
+
const oldest = typeof ends.asOf === "string" && newestPrice && ends.asOf < newestPrice.slice(0, 10) ? ends.asOf : null;
|
|
388
|
+
return {
|
|
389
|
+
...(asOf ? { asOf } : {}),
|
|
390
|
+
...(oldest ? { oldest, oldestPeriodicity: ends.periodicity ?? null } : {}),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* When the newest point of a chart of daily bars is from: for a session still
|
|
396
|
+
* trading, the time its listing was last quoted (`Fri 23 Oct 2026 15:42 UTC`),
|
|
397
|
+
* or its day when no quote of that day is known; else the day of the newest
|
|
398
|
+
* closed session (`closedDay`). Never the midnight a daily bar is dated at.
|
|
399
|
+
*/
|
|
400
|
+
function newestDailyPoint(series: readonly HeadlessSeries[], closedDay: string | null, quoteTimes: ReadonlyMap<string, number>): string | null {
|
|
401
|
+
const now = Date.now();
|
|
402
|
+
const stamps = closedDay ? [{ time: Date.parse(`${closedDay}T00:00:00Z`), text: closedDay }] : [];
|
|
403
|
+
for (const entry of series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis" | "listing">>>) {
|
|
404
|
+
const bar = entry.historyResolution === "1d" ? newestBar(entry) : null;
|
|
405
|
+
if (!bar || closedHistoryBarDay("1d", bar.day, bar.venue, now)) continue;
|
|
406
|
+
const quoted = quoteTimes.get(entry.id);
|
|
407
|
+
const dayStart = Date.parse(`${bar.day}T00:00:00Z`);
|
|
408
|
+
stamps.push(quoted != null && quoted >= dayStart && quoted <= now + 10 * 60_000
|
|
409
|
+
? { time: quoted, text: new Date(quoted).toISOString() }
|
|
410
|
+
: { time: dayStart, text: bar.day });
|
|
411
|
+
}
|
|
412
|
+
return stamps.reduce<{ time: number; text: string } | null>((newest, stamp) => (!newest || stamp.time > newest.time ? stamp : newest), null)?.text ?? null;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/** When each security series' listing was last quoted, by series id, from the quotes the chart was read with. */
|
|
416
|
+
function chartQuoteTimes(model: Pick<ChartPaneModel, "spec" | "snapshot">): Map<string, number> {
|
|
417
|
+
const times = new Map<string, number>();
|
|
418
|
+
for (const entry of model.spec.series) {
|
|
419
|
+
if (entry.source.kind !== "security") continue;
|
|
420
|
+
const { instrument } = entry.source;
|
|
421
|
+
const key = publicTickerKey(instrument.symbol, instrument.exchange);
|
|
422
|
+
const instrumentKey = snapshotInstrumentKey(instrument);
|
|
423
|
+
const data = model.snapshot.financials.find(([candidate]) => candidate === key)?.[1]
|
|
424
|
+
?? model.snapshot.instrumentFinancials?.find((item) => snapshotInstrumentKey(item.instrument) === instrumentKey)?.financials;
|
|
425
|
+
const time = data?.quote?.lastUpdated;
|
|
426
|
+
if (typeof time === "number" && Number.isFinite(time)) times.set(entry.id, time);
|
|
427
|
+
}
|
|
428
|
+
return times;
|
|
324
429
|
}
|
|
325
430
|
|
|
326
431
|
/** A series' venue and the day its newest bar starts, as the forming and closed bar checks read them. */
|
|
@@ -332,9 +437,9 @@ function newestBar(entry: HeadlessSeries & Partial<Pick<ResolvedSeries, "history
|
|
|
332
437
|
}
|
|
333
438
|
|
|
334
439
|
/**
|
|
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
|
|
440
|
+
* The day the newest complete daily, weekly or monthly bar of the chart closed
|
|
441
|
+
* on, the latest across its series: a week of bars dated Mon 12 Oct 2026 is
|
|
442
|
+
* dated Fri 16 Oct, the day their closes are from. Null for intraday bars.
|
|
338
443
|
*/
|
|
339
444
|
function closedPriceBarDay(series: readonly HeadlessSeries[]): string | null {
|
|
340
445
|
const days = (series as ReadonlyArray<HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis" | "listing">>>).flatMap((entry) => {
|
|
@@ -360,6 +465,48 @@ function formingPriceBar(series: readonly HeadlessSeries[]): BarPeriodToDate | n
|
|
|
360
465
|
return null;
|
|
361
466
|
}
|
|
362
467
|
|
|
468
|
+
const REGULAR_OPEN_MINUTE = 9 * 60 + 30;
|
|
469
|
+
const REGULAR_CLOSE_MINUTE = 16 * 60;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* GIP asks for a US listing's regular session only, so an 08:30 New York
|
|
473
|
+
* release is not in its bars. Said when every bar of a US stock venue's
|
|
474
|
+
* window starts from the 09:30 open to the 16:00 close; null for another
|
|
475
|
+
* venue, a future, or bars outside those hours.
|
|
476
|
+
*/
|
|
477
|
+
function regularSessionNotice(windows: ReadonlyArray<{ symbol: string; exchange: string; points: ReadonlyArray<Pick<PricePoint, "date">> }>): string | null {
|
|
478
|
+
const us = windows.filter(({ symbol, exchange, points }) => points.length > 0 && isUsListingExchange(exchange) && futuresSessionOpenMinute(symbol, exchange) == null);
|
|
479
|
+
if (!us.length) return null;
|
|
480
|
+
const regular = us.every(({ points }) => points.every(({ date }) => {
|
|
481
|
+
const { hour, minute } = zonedDateTimeParts(new Date(date).getTime(), "America/New_York");
|
|
482
|
+
const at = hour * 60 + minute;
|
|
483
|
+
return at >= REGULAR_OPEN_MINUTE && at <= REGULAR_CLOSE_MINUTE;
|
|
484
|
+
}));
|
|
485
|
+
return regular ? "Regular session only, from the 09:30 New York open: pre-market and after-hours bars are not included." : null;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Intraday bars as traded: each price the decimal the feed's float stands
|
|
490
|
+
* for (85.1, not 85.099998; a sub-penny print such as 86.3775 stays), as
|
|
491
|
+
* `history` writes them. A `value` that only repeats each bar's close is
|
|
492
|
+
* marked so, and `--csv` writes Close alone.
|
|
493
|
+
*/
|
|
494
|
+
function tradedBars(series: HeadlessSeries): HeadlessSeries {
|
|
495
|
+
if (!series.points.some((point) => point.close != null)) return series;
|
|
496
|
+
const valueIsClose = series.points.every((point) => point.value == null || point.value === point.close);
|
|
497
|
+
const traded = (price: number | null | undefined) => price == null || !Number.isFinite(price) ? price : cleanFloat32Price(price);
|
|
498
|
+
return {
|
|
499
|
+
...series,
|
|
500
|
+
...(valueIsClose ? { valueIsClose } : {}),
|
|
501
|
+
points: series.points.map((point) => {
|
|
502
|
+
const bar = { ...point };
|
|
503
|
+
for (const field of ["open", "high", "low", "close"] as const) if (point[field] !== undefined) bar[field] = traded(point[field]);
|
|
504
|
+
if (point.value != null && valueIsClose) bar.value = bar.close;
|
|
505
|
+
return bar;
|
|
506
|
+
}),
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
363
510
|
/** What a chart series was asked as: a listing as typed (`USDZAR=X`, `SAN:EPA`), a FRED series by its ID. */
|
|
364
511
|
function askedSymbol(source: ChartSeriesSource): string {
|
|
365
512
|
switch (source.kind) {
|
|
@@ -374,8 +521,8 @@ function askedSymbol(source: ChartSeriesSource): string {
|
|
|
374
521
|
* observes (`quarterly`), else how far apart its points are (a FRED series
|
|
375
522
|
* charts at its own frequency, `daily` for DEXSFUS).
|
|
376
523
|
*/
|
|
377
|
-
function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "nativeFrequency"> & Pick<HeadlessSeries, "points">): string | undefined {
|
|
378
|
-
if (series.historyResolution) return series.historyResolution;
|
|
524
|
+
function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "barSize" | "nativeFrequency"> & Pick<HeadlessSeries, "points">): string | undefined {
|
|
525
|
+
if (series.historyResolution) return series.barSize ?? series.historyResolution;
|
|
379
526
|
if (series.nativeFrequency && series.nativeFrequency !== "auto") return series.nativeFrequency;
|
|
380
527
|
const spacing = inferSeriesFrequency(series.points.map((point) => ({ date: point.date, value: 0 })));
|
|
381
528
|
return spacing === "irregular" ? undefined : spacing;
|
|
@@ -383,8 +530,8 @@ function servedInterval(series: Pick<ResolvedSeries, "historyResolution" | "nati
|
|
|
383
530
|
|
|
384
531
|
/** A dropped resolution, as JSON's `metadata.resolution` states it. */
|
|
385
532
|
export interface ChartResolutionDrop {
|
|
386
|
-
requested:
|
|
387
|
-
returned:
|
|
533
|
+
requested: ChartBarSize;
|
|
534
|
+
returned: ChartBarSize;
|
|
388
535
|
range: string;
|
|
389
536
|
reason: string;
|
|
390
537
|
}
|
|
@@ -398,18 +545,21 @@ export interface ChartResolutionDrop {
|
|
|
398
545
|
export function chartResolutionDrop(
|
|
399
546
|
requested: ChartResolution,
|
|
400
547
|
viewport: Pick<ChartViewportSpec, "range" | "dateWindow">,
|
|
401
|
-
series: ReadonlyArray<Pick<ResolvedSeries, "historyResolution"> & { symbol?: string }>,
|
|
548
|
+
series: ReadonlyArray<Pick<ResolvedSeries, "historyResolution" | "barSize"> & { symbol?: string }>,
|
|
402
549
|
support: ChartResolutionResult["resolutionSupport"],
|
|
403
550
|
): { drop: ChartResolutionDrop; warning: string } | null {
|
|
404
551
|
if (requested === "auto") return null;
|
|
405
|
-
const
|
|
406
|
-
const
|
|
552
|
+
const servedIn = (entry: Pick<ResolvedSeries, "historyResolution" | "barSize">) => entry.historyResolution ? entry.barSize ?? entry.historyResolution : null;
|
|
553
|
+
const dropped = series.filter((entry) => servedIn(entry) && servedIn(entry) !== requested);
|
|
554
|
+
const returned = dropped[0] ? servedIn(dropped[0]) : null;
|
|
407
555
|
if (!returned) return null;
|
|
408
556
|
const range = viewport.dateWindow ? "this window" : viewport.range;
|
|
409
557
|
const symbols = [...new Set(dropped.flatMap((entry) => entry.symbol ? [entry.symbol] : []))];
|
|
410
|
-
|
|
558
|
+
// A size built from shorter bars reaches back as far as those do.
|
|
559
|
+
const source = chartBarSizeSource(requested, support ?? []);
|
|
560
|
+
const maxRange = support?.length ? getSupportMaxRange(support, source) : null;
|
|
411
561
|
const reason = !support?.length ? `the source returned ${returned} bars`
|
|
412
|
-
: maxRange == null ? `the source does not serve ${requested} bars`
|
|
562
|
+
: maxRange == null ? `the source does not serve ${source === requested ? requested : `the ${source} bars ${requested} bars are built from`}`
|
|
413
563
|
: `${requested} bars go back ${maxRange} at most`;
|
|
414
564
|
const on = symbols.length > 0 ? ` on ${symbols.join(" and ")}` : "";
|
|
415
565
|
return {
|
|
@@ -436,19 +586,79 @@ export function argumentWithListing(argument: string, symbol: string, key: strin
|
|
|
436
586
|
return named ? legs.join("") : key;
|
|
437
587
|
}
|
|
438
588
|
|
|
589
|
+
/**
|
|
590
|
+
* A FRED series id typed where a ticker goes (`fn G DFII10`), as the chart of
|
|
591
|
+
* FRED:DFII10: the catalog lists it, no listing answers to it, and the quote
|
|
592
|
+
* source says it is not a ticker. A real ticker of the same letters, read as
|
|
593
|
+
* a listing or quoted, still charts as the ticker; null then, and for any
|
|
594
|
+
* other series.
|
|
595
|
+
*/
|
|
596
|
+
export async function bareFredSeries(
|
|
597
|
+
series: ChartSeriesSpec,
|
|
598
|
+
readListing: () => Promise<unknown>,
|
|
599
|
+
context: Pick<HeadlessPaneContext, "marketData" | "catalogSeriesName">,
|
|
600
|
+
): Promise<ChartSeriesSpec | null> {
|
|
601
|
+
const { source } = series;
|
|
602
|
+
if (source.kind !== "security" || source.instrument.exchange || source.instrument.instrument || source.fieldId !== CHART_FIELD_IDS.price) return null;
|
|
603
|
+
const id = source.instrument.symbol.trim().toUpperCase();
|
|
604
|
+
const expression = `FRED:${id}`;
|
|
605
|
+
const label = /^[A-Z0-9]+$/.test(id)
|
|
606
|
+
? context.catalogSeriesName?.(expression) ?? getSharedRegistry()?.series?.findByExpression(expression)?.definition.name
|
|
607
|
+
: undefined;
|
|
608
|
+
if (!label || await readListing()) return null;
|
|
609
|
+
const failure = await Promise.resolve().then(() => context.marketData.getQuote(id, ""))
|
|
610
|
+
.then((quote) => quote ? null : `Not a ticker: ${id}.`, (error: unknown) => error instanceof Error ? error.message : String(error));
|
|
611
|
+
if (!failure || !notATickerSymbol(failure)) return null;
|
|
612
|
+
const fred = buildSeriesSpec({ kind: "economic", provider: "fred", seriesId: id, label }, 0);
|
|
613
|
+
return { ...fred, id: series.id, transform: series.transform, axis: series.axis, panelId: series.panelId };
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* The compared tickers whose fund facts could state a daily objective: each
|
|
618
|
+
* but those a quote already cached says are not funds (a stock, an index).
|
|
619
|
+
* The facts are read through the ETF pane's cache, so a ticker read once
|
|
620
|
+
* is not asked again for a day.
|
|
621
|
+
*/
|
|
622
|
+
async function possibleFundTickers(spec: ChartSpec, context: HeadlessPaneContext): Promise<string[]> {
|
|
623
|
+
const tickers = comparedFundTickers(spec);
|
|
624
|
+
const read = context.marketData.getCachedFinancialsForTargets;
|
|
625
|
+
const cached = tickers.length && read
|
|
626
|
+
? await Promise.resolve().then(() => read.call(context.marketData, tickers.map((symbol) => ({ symbol })), { allowExpired: true, includeStaleQuotes: true }))
|
|
627
|
+
.catch(logFailure("chart-composer.headless", "Read cached chart fund types failed", null))
|
|
628
|
+
: null;
|
|
629
|
+
return tickers.filter((ticker) => {
|
|
630
|
+
const financials = cached?.get(ticker);
|
|
631
|
+
const kind = classifyInstrumentType(financials?.quote?.instrumentType ?? financials?.quoteMetadata?.instrumentType);
|
|
632
|
+
return kind === null || kind === "fund";
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
|
|
439
636
|
export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneDefinition<"series"> {
|
|
440
637
|
return {
|
|
441
638
|
...paneSchemas[template],
|
|
442
639
|
shape: "series",
|
|
443
640
|
async load(args, context) {
|
|
444
641
|
const intradayHistories: ChartPaneModel["snapshot"]["intradayHistories"] = [];
|
|
445
|
-
const
|
|
446
|
-
if (!
|
|
642
|
+
const saved = parseChartSpec(context.settings?.chartSpec);
|
|
643
|
+
if (!saved) throw new Error("The chart specification is invalid.");
|
|
644
|
+
// A leveraged or inverse fund compared with anything draws its daily objective beside it.
|
|
645
|
+
const parsed = template === "comparison-chart-pane" && mayDrawDailyObjective(saved)
|
|
646
|
+
? withLeverageOverlay(saved, await loadDailyObjectives(
|
|
647
|
+
await possibleFundTickers(saved, context),
|
|
648
|
+
async (ticker, signal) => (await loadFundFacts(ticker, false, { client: context.apiClient, signal })).payload,
|
|
649
|
+
{ signal: context.signal },
|
|
650
|
+
))
|
|
651
|
+
: saved;
|
|
447
652
|
// A bare symbol is the listing `quote` reads it as: BDI, which two companies list, asks which,
|
|
448
653
|
// as `quote BDI` does, instead of charting whichever line a source picked.
|
|
449
654
|
const reads = new Map<string, ReturnType<typeof readSeriesListing>>();
|
|
655
|
+
const listings = new Map<string, Promise<Awaited<ReturnType<NonNullable<typeof context.resolveListing>>> | null>>();
|
|
656
|
+
const readListing = (symbol: string) => {
|
|
657
|
+
if (!listings.has(symbol)) listings.set(symbol, context.resolveListing?.(symbol, (key) => argumentWithListing(args.rawArgument, symbol, key)) ?? Promise.resolve(null));
|
|
658
|
+
return listings.get(symbol)!;
|
|
659
|
+
};
|
|
450
660
|
const readSeriesListing = async (symbol: string): Promise<{ symbol: string; exchange?: string } | null> => {
|
|
451
|
-
const read = await
|
|
661
|
+
const read = await readListing(symbol);
|
|
452
662
|
if (read) return { symbol: read.symbol, ...read.exchange ? { exchange: read.exchange } : {} };
|
|
453
663
|
return context.resolveInstrument ? context.resolveInstrument(symbol) : null;
|
|
454
664
|
};
|
|
@@ -457,6 +667,9 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
457
667
|
series: await Promise.all(parsed.series.map(async (series) => {
|
|
458
668
|
if (series.source.kind !== "security" || series.source.instrument.exchange) return series;
|
|
459
669
|
const { symbol } = series.source.instrument;
|
|
670
|
+
// A FRED id no ticker answers to (DFII10) is its FRED series; an intraday chart has none.
|
|
671
|
+
const fred = template === "graph-intraday-price-pane" ? null : await bareFredSeries(series, () => readListing(symbol), context);
|
|
672
|
+
if (fred) return fred;
|
|
460
673
|
if (!reads.has(symbol)) reads.set(symbol, readSeriesListing(symbol));
|
|
461
674
|
const instrument = await reads.get(symbol)!;
|
|
462
675
|
return instrument ? { ...series, source: { ...series.source, instrument: { ...series.source.instrument, ...instrument } } } : series;
|
|
@@ -469,7 +682,7 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
469
682
|
? intersectChartResolutionSupport(await Promise.all([...instruments.values()].map(async (target) => (
|
|
470
683
|
normalizeChartResolutionSupport(await Promise.resolve(context.marketData.getChartResolutionSupport!(
|
|
471
684
|
target.symbol, target.exchange ?? "", { brokerId: target.brokerId, brokerInstanceId: target.brokerInstanceId, instrument: target.instrument },
|
|
472
|
-
)).catch((
|
|
685
|
+
)).catch(logFailure("chart-composer.headless", "Read intraday resolution support failed", [])))
|
|
473
686
|
))))
|
|
474
687
|
: [];
|
|
475
688
|
const request = resolveIntradayRequest({
|
|
@@ -534,20 +747,25 @@ export function chartHeadless(template: keyof typeof paneSchemas): HeadlessPaneD
|
|
|
534
747
|
const asked = new Map(parsed.series.map((series) => [series.id, askedSymbol(series.source)]));
|
|
535
748
|
model.series = model.series.map((series) => {
|
|
536
749
|
const symbol = asked.get(series.id);
|
|
537
|
-
const interval = servedInterval(series as HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "nativeFrequency">);
|
|
750
|
+
const interval = servedInterval(series as HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "barSize" | "nativeFrequency">);
|
|
538
751
|
return { ...series, ...(symbol ? { symbol } : {}), ...(interval ? { interval } : {}) };
|
|
539
752
|
});
|
|
753
|
+
if (template === "graph-intraday-price-pane") {
|
|
754
|
+
model.series = model.series.map(tradedBars);
|
|
755
|
+
const regular = regularSessionNotice(intradayHistories.map((window) => ({ ...window, exchange: listingExchange(window.symbol, window.exchange) })));
|
|
756
|
+
if (regular) model.metadata = { ...model.metadata, notices: [...(Array.isArray(model.metadata?.notices) ? model.metadata.notices : []), regular] };
|
|
757
|
+
}
|
|
540
758
|
const dropped = chartResolutionDrop(
|
|
541
759
|
parsed.viewport.resolution,
|
|
542
760
|
model.spec.viewport,
|
|
543
|
-
(model.series as Array<HeadlessSeries & Pick<ResolvedSeries, "historyResolution"> & { derived?: boolean }>).filter((series) => !series.derived),
|
|
761
|
+
(model.series as Array<HeadlessSeries & Pick<ResolvedSeries, "historyResolution" | "barSize"> & { derived?: boolean }>).filter((series) => !series.derived),
|
|
544
762
|
model.chart.resolutionSupport,
|
|
545
763
|
);
|
|
546
764
|
if (dropped) {
|
|
547
765
|
model.warnings = [...model.warnings ?? [], dropped.warning];
|
|
548
766
|
model.metadata = { ...model.metadata, resolution: dropped.drop };
|
|
549
767
|
}
|
|
550
|
-
model.freshness = chartFreshness(model.series, model.spec);
|
|
768
|
+
model.freshness = chartFreshness(model.series, model.spec, model.chart.priceComparison, chartQuoteTimes(model));
|
|
551
769
|
const priceDomainFailures = intradayHistories.flatMap(({ symbol, exchange, priceDomainFailure }) =>
|
|
552
770
|
priceDomainFailure ? [{ symbol, exchange, ...priceDomainFailure }] : []);
|
|
553
771
|
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",
|