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
|
@@ -9,6 +9,7 @@ import { usePluginBrokerActions } from "../../../runtime";
|
|
|
9
9
|
import type { OfflineBroker } from "../../shared/broker-reconnect";
|
|
10
10
|
import { tf } from "../../../../i18n";
|
|
11
11
|
import { isSignedInBrokerProfile, signedInBrokerId } from "../../../../brokers/signed-in/profile";
|
|
12
|
+
import { accountsShownFor } from "../../../../brokers/broker-portfolio-sync";
|
|
12
13
|
import { resolvePortfolioAccountState, type ResolvedPortfolioAccountState } from "./index";
|
|
13
14
|
|
|
14
15
|
const EMPTY_ACCOUNTS = { instanceId: null, accounts: [] as BrokerAccount[], error: null };
|
|
@@ -98,9 +99,10 @@ export interface PortfolioAccountStateResult {
|
|
|
98
99
|
|
|
99
100
|
/**
|
|
100
101
|
* The broker behind a portfolio while Gloom cannot reach it: disconnected,
|
|
101
|
-
* failing,
|
|
102
|
-
*
|
|
103
|
-
*
|
|
102
|
+
* failing, without the plugin that connects it, or turned off (`disabled`),
|
|
103
|
+
* which nothing syncs until it is enabled. Null while it is connected or
|
|
104
|
+
* connecting, before it reports a status, and for one that only syncs on
|
|
105
|
+
* demand (IBKR Flex), which is never connected.
|
|
104
106
|
*/
|
|
105
107
|
export function resolveOfflineBroker(
|
|
106
108
|
portfolio: Portfolio | null,
|
|
@@ -108,16 +110,20 @@ export function resolveOfflineBroker(
|
|
|
108
110
|
broker: BrokerAdapter | null | undefined,
|
|
109
111
|
status: BrokerConnectionStatus | null,
|
|
110
112
|
): OfflineBroker | null {
|
|
111
|
-
if (!portfolio || !brokerInstance
|
|
113
|
+
if (!portfolio || !brokerInstance) return null;
|
|
112
114
|
const syncedAt = portfolio.lastSyncedAt ?? brokerInstance.lastSyncedAt ?? null;
|
|
115
|
+
// A profile signed in through Gloom names its broker, not the adapter it needs.
|
|
116
|
+
const brokerName = broker
|
|
117
|
+
? broker.describeInstance?.(brokerInstance).brokerName ?? broker.name
|
|
118
|
+
: (isSignedInBrokerProfile(brokerInstance) ? signedInBrokerId(brokerInstance) : brokerInstance.brokerType).toUpperCase();
|
|
119
|
+
if (brokerInstance.enabled === false) {
|
|
120
|
+
return { instance: brokerInstance, brokerName, syncedAt, reason: tf("{broker} disabled", { broker: brokerName }), reconnectable: !!broker, disabled: true };
|
|
121
|
+
}
|
|
113
122
|
if (!broker) {
|
|
114
|
-
// A profile signed in through Gloom names its broker, not the adapter it needs.
|
|
115
|
-
const brokerName = (isSignedInBrokerProfile(brokerInstance) ? signedInBrokerId(brokerInstance) : brokerInstance.brokerType).toUpperCase();
|
|
116
123
|
return { instance: brokerInstance, brokerName, syncedAt, reason: tf("{broker} unavailable", { broker: brokerName }), reconnectable: false };
|
|
117
124
|
}
|
|
118
125
|
if (!status || status.state === "connected" || status.state === "connecting") return null;
|
|
119
126
|
if (status.mode?.toLowerCase() === "flex") return null;
|
|
120
|
-
const brokerName = broker.describeInstance?.(brokerInstance).brokerName ?? broker.name;
|
|
121
127
|
const reason = status.state === "error"
|
|
122
128
|
? status.message?.trim() || tf("{broker} unavailable", { broker: brokerName })
|
|
123
129
|
: tf("{broker} disconnected", { broker: brokerName });
|
|
@@ -141,9 +147,10 @@ export function usePortfolioAccountState(
|
|
|
141
147
|
const { getBrokerAdapter } = usePluginBrokerActions();
|
|
142
148
|
const broker = brokerInstance ? getBrokerAdapter(brokerInstance.brokerType) : null;
|
|
143
149
|
const live = useLiveBrokerAccounts(broker, brokerInstance, instanceId ? state.brokerAccounts[instanceId] : undefined);
|
|
150
|
+
// An account another profile holds under its own number is that profile's, here as in sync.
|
|
144
151
|
const snapshot = useMemo(
|
|
145
|
-
() => ({ status: live.status, accounts: live.accounts }),
|
|
146
|
-
[live.accounts, live.status],
|
|
152
|
+
() => ({ status: live.status, accounts: brokerInstance ? accountsShownFor(state.config, brokerInstance, live.accounts) : live.accounts }),
|
|
153
|
+
[brokerInstance, live.accounts, live.status, state.config],
|
|
147
154
|
);
|
|
148
155
|
const accountState = useMemo(
|
|
149
156
|
() => resolvePortfolioAccountState(portfolio, state, snapshot),
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { TickerFinancials } from "../../../../types/financials";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TickerRecord } from "../../../../types/ticker";
|
|
3
3
|
import { convertCurrency, formatCompactAmount } from "../../../../utils/format";
|
|
4
4
|
import { getCurrencySymbol } from "../../../../market-data/market/format";
|
|
5
5
|
import { getActiveQuoteDisplay } from "../../../../market-data/market/status";
|
|
6
6
|
import { combinedChangeBasisLabel, quoteChangeBasis, type QuoteChangeBasis } from "../../../../market-data/market/change-basis";
|
|
7
7
|
import { isQuoteStaleForCurrentSession } from "../../../../market-data/quotes/freshness";
|
|
8
8
|
import { headlineQuoteDisplay } from "../../../../portfolio/column-values";
|
|
9
|
-
import { isManualPortfolio } from "../../../../portfolio/mutations";
|
|
10
9
|
import type { AllocationHolding } from "../../../../portfolio/allocation";
|
|
11
10
|
import { getPortfolioValuationDisplay, type PortfolioValuationBasis } from "../../../../portfolio/valuation-basis";
|
|
12
11
|
import type { PortfolioFuturesTerms } from "../../../../portfolio/futures-positions";
|
|
@@ -76,19 +75,7 @@ function currencyCode(value: string | undefined): string | null {
|
|
|
76
75
|
return CURRENCY_CODE.test(code) ? code : null;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
* The currency a portfolio's totals, market values and P&L are in. A broker
|
|
81
|
-
* portfolio uses its account currency. A manual portfolio uses its stored
|
|
82
|
-
* currency with the default USD base (its first holding sets it, see
|
|
83
|
-
* adoptFirstPositionCurrency); a base currency the user chose is what manual
|
|
84
|
-
* portfolios and watchlists total in.
|
|
85
|
-
*/
|
|
86
|
-
export function resolvePortfolioTotalsCurrency(portfolio: Portfolio | null | undefined, baseCurrency: string): string {
|
|
87
|
-
const base = currencyCode(baseCurrency) ?? "USD";
|
|
88
|
-
if (!portfolio) return base;
|
|
89
|
-
if (isManualPortfolio(portfolio) && base !== "USD") return base;
|
|
90
|
-
return currencyCode(portfolio.currency) ?? base;
|
|
91
|
-
}
|
|
78
|
+
export { resolvePortfolioTotalsCurrency } from "../../../../portfolio/totals-currency";
|
|
92
79
|
|
|
93
80
|
/**
|
|
94
81
|
* A compact total in the portfolio's currency. Bare when both it and the app's
|
|
@@ -15,7 +15,10 @@ const nullableText = (v: unknown) => v === null || text(v);
|
|
|
15
15
|
const nonnegative = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
16
16
|
const integer = (v: unknown) => nonnegative(v) && Number.isInteger(v);
|
|
17
17
|
const instant = (v: unknown) => text(v) && Number.isFinite(Date.parse(v));
|
|
18
|
-
const url = (v: unknown) => { try { return text(v) && new URL(v).protocol === "https:"; } catch {
|
|
18
|
+
const url = (v: unknown) => { try { return text(v) && new URL(v).protocol === "https:"; } catch {
|
|
19
|
+
// Intentional ignore: malformed URLs fail this HTTPS field validator.
|
|
20
|
+
return false;
|
|
21
|
+
} };
|
|
19
22
|
const access = (v: unknown) => v === "full" || v === "preview";
|
|
20
23
|
const entities = (v: unknown) => Array.isArray(v) && v.every((e) => record(e) && text(e.name) && text(e.entityId)
|
|
21
24
|
&& ["utility", "developer"].includes(e.role) && nonnegative(e.confidence) && e.confidence <= 1
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import type { CarbonBoard, CarbonHistory, EuropePowerBoard, EuropePowerHistory, GasStorageBoard, GasStorageSeasonal } from "../../../api-client/europe-energy";
|
|
2
3
|
import type { PowerBoard, PowerHistory } from "../../../api-client/power";
|
|
3
4
|
import type { PaneScreenshotEvidenceHook } from "../../../cli/pane-functions/screenshot-evidence";
|
|
@@ -21,6 +22,7 @@ interface PowerEvidence {
|
|
|
21
22
|
/** The day-ahead board and the EUA board, on the Prices tab. */
|
|
22
23
|
prices?: EuropePowerBoard | null;
|
|
23
24
|
carbon?: CarbonBoard | null;
|
|
25
|
+
carbonError?: string;
|
|
24
26
|
/** The gas storage board, on the Prices tab's gas board. */
|
|
25
27
|
gas?: GasStorageBoard | null;
|
|
26
28
|
tab: string;
|
|
@@ -33,6 +35,8 @@ export interface PowerPricesSnapshot {
|
|
|
33
35
|
history: EuropePowerHistory | CarbonHistory | null;
|
|
34
36
|
/** Null when the server has no EUA price yet; the tab then shows the board alone. */
|
|
35
37
|
carbon: CarbonBoard | null;
|
|
38
|
+
/** A completed optional read that failed; older snapshots omit this field. */
|
|
39
|
+
carbonError?: string;
|
|
36
40
|
}
|
|
37
41
|
/** What the gas board draws, frozen by `shot`: the board and the selected area's seasonal range. */
|
|
38
42
|
export interface GasStorageSnapshot {
|
|
@@ -45,10 +49,10 @@ export function usePowerEvidence(board: PowerBoard | undefined, history: PowerHi
|
|
|
45
49
|
plottedValueCount: rowIds.length, board, history: history ?? null, tab, rowIds,
|
|
46
50
|
}) });
|
|
47
51
|
}
|
|
48
|
-
export function usePowerPricesEvidence(prices: EuropePowerBoard | null, carbon: CarbonBoard | null, rowIds: string[], loading: boolean) {
|
|
52
|
+
export function usePowerPricesEvidence(prices: EuropePowerBoard | null, carbon: CarbonBoard | null, rowIds: string[], loading: boolean, carbonError?: string | null) {
|
|
49
53
|
useRemoteUiNode({ role: "chart-data", label: "Rendered day-ahead power and carbon prices", getMetadata: () => ({
|
|
50
54
|
kind: "power", version: 1, complete: !!prices && !loading, ready: !!prices && !loading,
|
|
51
|
-
plottedValueCount: rowIds.length, board: null, history: null, prices, carbon, tab: "prices", rowIds,
|
|
55
|
+
plottedValueCount: rowIds.length, board: null, history: null, prices, carbon, ...(carbonError ? { carbonError } : {}), tab: "prices", rowIds,
|
|
52
56
|
}) });
|
|
53
57
|
}
|
|
54
58
|
export function useGasStorageEvidence(gas: GasStorageBoard | null, rowIds: string[], loading: boolean) {
|
|
@@ -71,13 +75,19 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
|
|
|
71
75
|
}
|
|
72
76
|
if (tab === "prices") {
|
|
73
77
|
const board = await fetchPowerPrices();
|
|
74
|
-
//
|
|
75
|
-
|
|
78
|
+
// Optional carbon failure travels with the board, just as it does in the live pane.
|
|
79
|
+
let carbonError: string | undefined;
|
|
80
|
+
const carbon = await fetchCarbonPrice().catch((error: unknown) => {
|
|
81
|
+
logFailure("power.evidence", "Load carbon price for capture failed")(error);
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
carbonError = message.trim() ? message : "Request failed";
|
|
84
|
+
return null;
|
|
85
|
+
});
|
|
76
86
|
const arg = resolved.createOptions?.arg;
|
|
77
87
|
const market = powerPriceMarket(arg)?.code ?? DEFAULT_PRICE_MARKET;
|
|
78
88
|
const history = isCarbonQuery(arg) && carbon?.row.date ? await fetchCarbonHistory()
|
|
79
89
|
: board.rows.some((row) => row.code === market && row.date) ? await fetchPowerPriceHistory(market) : null;
|
|
80
|
-
return { settings: { powerPricesSnapshot: { board, history, carbon } satisfies PowerPricesSnapshot }, financials: [] };
|
|
90
|
+
return { settings: { powerPricesSnapshot: { board, history, carbon, ...(carbonError ? { carbonError } : {}) } satisfies PowerPricesSnapshot }, financials: [] };
|
|
81
91
|
}
|
|
82
92
|
const symbol = resolved.createOptions?.symbol ?? resolved.createOptions?.arg;
|
|
83
93
|
const filter = powerQuery({ ...settings, ...resolved.options, tab }, symbol);
|
|
@@ -103,6 +113,7 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
|
|
|
103
113
|
if (!isRecord(value.prices)) return null;
|
|
104
114
|
const prices = validatePowerPrices(value.prices as unknown as EuropePowerBoard);
|
|
105
115
|
if (value.carbon != null) validateCarbonPrice(value.carbon as unknown as CarbonBoard);
|
|
116
|
+
if (value.carbonError !== undefined && (typeof value.carbonError !== "string" || !value.carbonError.trim() || value.carbon != null)) return null;
|
|
106
117
|
if (value.rowIds.some((id) => !prices.rows.some((row) => row.code === id))) return null;
|
|
107
118
|
return value as unknown as PowerEvidence;
|
|
108
119
|
}
|
|
@@ -112,7 +123,10 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
|
|
|
112
123
|
const rows = ["queue", "loads", "capacity"].includes(tab) ? projectRows(board.projects) : otherRows(tab, board, history?.points ?? []);
|
|
113
124
|
if (value.rowIds.some((id) => !rows.some((r) => r.id === id))) return null;
|
|
114
125
|
return value as unknown as PowerEvidence;
|
|
115
|
-
} catch {
|
|
126
|
+
} catch {
|
|
127
|
+
// Intentional ignore: invalid captured observations are rejected as evidence by returning null.
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
116
130
|
},
|
|
117
131
|
mismatches(evidence, { resolved, payload }) {
|
|
118
132
|
const settings = instanceSettings(payload);
|
|
@@ -123,7 +137,8 @@ export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence>
|
|
|
123
137
|
} else if (evidence.tab === "prices") {
|
|
124
138
|
const snapshot = settings?.powerPricesSnapshot;
|
|
125
139
|
if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.prices)
|
|
126
|
-
|| JSON.stringify(snapshot.carbon ?? null) !== JSON.stringify(evidence.carbon ?? null)
|
|
140
|
+
|| JSON.stringify(snapshot.carbon ?? null) !== JSON.stringify(evidence.carbon ?? null)
|
|
141
|
+
|| (snapshot.carbonError ?? null) !== (evidence.carbonError ?? null)) errors.push("Power prices differ from the captured data.");
|
|
127
142
|
} else {
|
|
128
143
|
const snapshot = settings?.powerSnapshot;
|
|
129
144
|
if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.board)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import { useCallback, useMemo } from "react";
|
|
2
3
|
import type { GasStorageRow } from "../../../api-client/europe-energy";
|
|
3
4
|
import {
|
|
@@ -99,7 +100,10 @@ export function GasStorageView({ width, height, focused, snapshot }: {
|
|
|
99
100
|
const frozen = useMemo(() => {
|
|
100
101
|
try {
|
|
101
102
|
return snapshot ? { board: validateGasStorage(snapshot.board), seasonal: snapshot.seasonal ? validateGasSeasonal(snapshot.seasonal) : null } : null;
|
|
102
|
-
} catch {
|
|
103
|
+
} catch (error) {
|
|
104
|
+
logFailure("power.gas", "Validate gas storage snapshot failed")(error);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
103
107
|
}, [snapshot]);
|
|
104
108
|
const resource = useAsyncResource(frozen ? null : loadGasStorage, { initialData: getCachedGasStorage });
|
|
105
109
|
const board = frozen?.board ?? resource.data?.payload ?? null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
3
|
import type { PowerBoard, PowerFilter, PowerHistory } from "../../../api-client/power";
|
|
3
4
|
import { isAccessDenied } from "../../../api-client/errors";
|
|
@@ -8,6 +9,7 @@ import { useAsyncResource, useAutoRefresh, usePaneSettingValue, usePluginAppActi
|
|
|
8
9
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
9
10
|
import type { PaneProps } from "../../../types/plugin";
|
|
10
11
|
import { Box, Text, TextAttributes, useRendererHost, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
|
|
12
|
+
import { withCountryFlag } from "../../../components/ui/country-flag";
|
|
11
13
|
import { publicTickerKey } from "../../../utils/exchanges";
|
|
12
14
|
import { getSharedRegistry } from "../../registry/shared";
|
|
13
15
|
import { usePaneInstance } from "../../../state/app/context";
|
|
@@ -86,7 +88,10 @@ function PowerView({ width, height, focused, scope, needsVerification }: PanePro
|
|
|
86
88
|
const searchFocus = useQueryBarSearch();
|
|
87
89
|
const [snapshotSetting] = usePaneSettingValue<{ board: PowerBoard; history?: PowerHistory; tickerScopes?: PowerTickerScope[] } | null>("powerSnapshot", null);
|
|
88
90
|
const snapshot = useMemo(() => { try { return snapshotSetting ? { board: validatePowerBoard(snapshotSetting.board), history: snapshotSetting.history ? validatePowerHistory(snapshotSetting.history) : undefined,
|
|
89
|
-
tickerScopes: Array.isArray(snapshotSetting.tickerScopes) ? snapshotSetting.tickerScopes : null } : null; } catch {
|
|
91
|
+
tickerScopes: Array.isArray(snapshotSetting.tickerScopes) ? snapshotSetting.tickerScopes : null } : null; } catch (error) {
|
|
92
|
+
logFailure("power.pane", "Validate power snapshot failed")(error);
|
|
93
|
+
return null;
|
|
94
|
+
} }, [snapshotSetting]);
|
|
90
95
|
const projectTab = ["queue", "loads", "capacity"].includes(tab);
|
|
91
96
|
const filter = useMemo(() => powerQuery({ tab, country, region, fuel, status, search, historical, context, loadClass, sourceId, from, to,
|
|
92
97
|
sort: sort.column, direction: sort.direction }, symbol), [tab, country, region, fuel, status, search, historical, context, loadClass, sourceId, from, to, sort.column, sort.direction, symbol]);
|
|
@@ -207,6 +212,8 @@ function PowerView({ width, height, focused, scope, needsVerification }: PanePro
|
|
|
207
212
|
if (column.id === "status") return { text, color: toneColor(STATUS_TONES[text] ?? "text", colors) };
|
|
208
213
|
if (column.id === "changeMw" && typeof value === "number") return { text: `${value > 0 ? "+" : ""}${text}`, value, color: signedColor(value, colors) };
|
|
209
214
|
if (column.id === "ticker") return { text, color: colors.textBright, attributes: state.selected ? 0 : TextAttributes.BOLD };
|
|
215
|
+
// The column has room for the flag beside a code.
|
|
216
|
+
if (column.id === "country") return withCountryFlag({ text, color: colors.textDim }, text, desktop);
|
|
210
217
|
return { text, value: numeric,
|
|
211
218
|
color: column.id === "name" || column.id === "utility" || column.id === "capacityMw" || column.id === "requestedMw" ? colors.textBright
|
|
212
219
|
: ["location", "asOf", "observedAt", "scope", "proposedDate", "region", "country", "kind", "role", "period"].includes(column.id) ? colors.textDim : colors.text };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import { useCallback, useMemo } from "react";
|
|
2
3
|
import type { CarbonBoard, PowerPriceRow } from "../../../api-client/europe-energy";
|
|
3
4
|
import {
|
|
@@ -140,15 +141,21 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
|
|
|
140
141
|
const [snapshotSetting] = usePaneSettingValue<PowerPricesSnapshot | null>("powerPricesSnapshot", null);
|
|
141
142
|
const snapshot = useMemo(() => {
|
|
142
143
|
try {
|
|
144
|
+
if (snapshotSetting?.carbonError !== undefined && (typeof snapshotSetting.carbonError !== "string"
|
|
145
|
+
|| !snapshotSetting.carbonError.trim() || snapshotSetting.carbon != null)) throw new Error("Invalid carbon price failure state.");
|
|
143
146
|
return snapshotSetting ? { ...snapshotSetting, board: validatePowerPrices(snapshotSetting.board),
|
|
144
147
|
carbon: snapshotSetting.carbon ? validateCarbonPrice(snapshotSetting.carbon) : null } : null;
|
|
145
|
-
} catch {
|
|
148
|
+
} catch (error) {
|
|
149
|
+
logFailure("power.prices", "Validate power prices snapshot failed")(error);
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
146
152
|
}, [snapshotSetting]);
|
|
147
153
|
const resource = useAsyncResource(snapshot ? null : loadPowerPrices, { initialData: getCachedPowerPrices });
|
|
148
154
|
const board = snapshot?.board ?? resource.data?.payload ?? null;
|
|
149
155
|
// The carbon allowance loads beside the board; its failure is a notice, never the board's.
|
|
150
156
|
const carbonResource = useAsyncResource(snapshot ? null : loadCarbonPrice, { initialData: getCachedCarbonPrice });
|
|
151
157
|
const carbon = snapshot ? snapshot.carbon : carbonResource.data?.payload ?? null;
|
|
158
|
+
const carbonError = snapshot ? snapshot.carbonError : carbonResource.error;
|
|
152
159
|
const figures = useMemo(() => carbon ? carbonFigures(carbon) : [], [carbon]);
|
|
153
160
|
const rows = useMemo(() => board?.rows.map(boardRow) ?? [], [board]);
|
|
154
161
|
// The band charts the selected market, or the carbon allowance from `c` or EPWR EUA until a market is chosen.
|
|
@@ -160,7 +167,7 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
|
|
|
160
167
|
const loaded = useAsyncResource<{ payload: { code: string; points: ReadonlyArray<{ date: string; value: number }> } }>(
|
|
161
168
|
code && !snapshot ? historyLoader : null, { keepPreviousData: true });
|
|
162
169
|
const history = snapshot ? { ...loaded, data: snapshot.history ? { payload: snapshot.history } : null, loading: false, error: null } : loaded;
|
|
163
|
-
usePowerPricesEvidence(board, carbon, useMemo(() => rows.map((row) => row.id), [rows]), resource.loading || history.loading || carbonResource.loading);
|
|
170
|
+
usePowerPricesEvidence(board, carbon, useMemo(() => rows.map((row) => row.id), [rows]), resource.loading || history.loading || carbonResource.loading, snapshot?.carbonError);
|
|
164
171
|
useAutoRefresh(resource.updatedAt, resource.load);
|
|
165
172
|
useAutoRefresh(carbonResource.updatedAt, carbonResource.load);
|
|
166
173
|
usePaneRefreshKey(() => { void resource.reload(); void history.reload(); void carbonResource.reload(); }, { focused });
|
|
@@ -185,7 +192,7 @@ function PowerPriceBoard({ width, height, focused }: { width: number; height: nu
|
|
|
185
192
|
error: board ? resource.error ?? (open ? null : history.error) : null, stale: !!resource.data?.stale, hints });
|
|
186
193
|
usePaneNoticeFooter({ registrationId: "power-prices:notices", focused,
|
|
187
194
|
notices: [...(board?.gaps ?? []), ...(resource.data?.refreshError ? [resource.data.refreshError] : []),
|
|
188
|
-
...(carbon?.gaps ?? []), ...(board && !carbon &&
|
|
195
|
+
...(carbon?.gaps ?? []), ...(board && !carbon && carbonError ? [carbonError] : [])] });
|
|
189
196
|
return <Box width={width} height={height} flexDirection="column">
|
|
190
197
|
<PaneStatusBody loading={resource.loading && !board} error={!board && !notAvailable ? resource.error : null}
|
|
191
198
|
empty={notAvailable} emptyTitle={POWER_PRICES_NOT_AVAILABLE} subject="power prices" width={width} height={height}>
|
|
@@ -6,11 +6,15 @@ import type {
|
|
|
6
6
|
HeadlessPaneEntry,
|
|
7
7
|
HeadlessPaneLoadArgs,
|
|
8
8
|
} from "../../../types/plugin";
|
|
9
|
-
import type { AnalystResearchData } from "../../../types/financials";
|
|
9
|
+
import type { AnalystResearchData, Quote } from "../../../types/financials";
|
|
10
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
10
11
|
import { formatPercent } from "../../../utils/format";
|
|
11
12
|
import { loadAnalystResearch } from "./client";
|
|
12
13
|
import {
|
|
14
|
+
analystReferenceMetadata,
|
|
13
15
|
analystTargetCurrency,
|
|
16
|
+
analystUpside,
|
|
17
|
+
formatAnalystReference,
|
|
14
18
|
formatAnalystPrice,
|
|
15
19
|
formatRecommendationMix,
|
|
16
20
|
recommendationMix,
|
|
@@ -18,7 +22,6 @@ import {
|
|
|
18
22
|
formatRatingTarget,
|
|
19
23
|
recommendationTotal,
|
|
20
24
|
sortRatingRows,
|
|
21
|
-
targetUpside,
|
|
22
25
|
type RatingColumnId,
|
|
23
26
|
} from "./analyst-model";
|
|
24
27
|
import { REPORTED_DATA } from "../shared/report-freshness";
|
|
@@ -48,10 +51,11 @@ const SORT_COLUMNS: Record<string, RatingColumnId> = {
|
|
|
48
51
|
target: "target",
|
|
49
52
|
};
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
/** The summary: the upside from Last (the quote's regular session price), and the price and time it is measured from, as `analyst` gives them. */
|
|
55
|
+
function overviewEntries(data: AnalystResearchData, quote: Quote | null): HeadlessPaneEntry[] {
|
|
52
56
|
const target = data.priceTarget;
|
|
53
57
|
const currency = analystTargetCurrency(data);
|
|
54
|
-
const upside =
|
|
58
|
+
const { upside, reference } = analystUpside(data, quote);
|
|
55
59
|
return [
|
|
56
60
|
{
|
|
57
61
|
label: "Average target",
|
|
@@ -65,8 +69,8 @@ function overviewEntries(data: AnalystResearchData): HeadlessPaneEntry[] {
|
|
|
65
69
|
},
|
|
66
70
|
{
|
|
67
71
|
label: "Upside reference price",
|
|
68
|
-
value:
|
|
69
|
-
formatted:
|
|
72
|
+
value: reference.price ?? null,
|
|
73
|
+
formatted: formatAnalystReference(reference, currency),
|
|
70
74
|
},
|
|
71
75
|
{
|
|
72
76
|
label: "Target range",
|
|
@@ -97,6 +101,8 @@ export interface AnalystResearchHeadlessDependencies {
|
|
|
97
101
|
args: HeadlessPaneLoadArgs,
|
|
98
102
|
ctx: HeadlessPaneContext,
|
|
99
103
|
): Promise<AnalystResearchData>;
|
|
104
|
+
/** The listing's quote, whose regular session price the upside is measured from; null when none loads. */
|
|
105
|
+
loadQuote?(symbol: string, ctx: HeadlessPaneContext): Promise<Quote | null>;
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
const defaultDependencies: AnalystResearchHeadlessDependencies = {
|
|
@@ -104,6 +110,11 @@ const defaultDependencies: AnalystResearchHeadlessDependencies = {
|
|
|
104
110
|
const instrument = await ctx.resolveInstrument?.(symbol);
|
|
105
111
|
return loadAnalystResearch(ctx.marketData, symbol, instrument?.exchange);
|
|
106
112
|
},
|
|
113
|
+
async loadQuote(symbol, ctx) {
|
|
114
|
+
const instrument = await ctx.resolveInstrument?.(symbol);
|
|
115
|
+
return ctx.marketData.getQuote(instrument?.symbol ?? symbol, instrument?.exchange ?? "")
|
|
116
|
+
.catch(logFailure("analyst", "Read the quote the upside is measured from failed", null));
|
|
117
|
+
},
|
|
107
118
|
};
|
|
108
119
|
|
|
109
120
|
export function createAnalystResearchHeadless(
|
|
@@ -148,7 +159,11 @@ export function createAnalystResearchHeadless(
|
|
|
148
159
|
describe: (args) => `Analyst Research | ${args.symbols[0]}`,
|
|
149
160
|
async load(args, ctx) {
|
|
150
161
|
const symbol = args.symbols[0]!;
|
|
151
|
-
const data = await
|
|
162
|
+
const [data, quote] = await Promise.all([
|
|
163
|
+
dependencies.loadData(symbol, args, ctx),
|
|
164
|
+
dependencies.loadQuote?.(symbol, ctx) ?? Promise.resolve(null),
|
|
165
|
+
]);
|
|
166
|
+
const { upside, reference } = analystUpside(data, quote);
|
|
152
167
|
const currency = analystTargetCurrency(data);
|
|
153
168
|
const ratings = sortRatingRows(data.ratings, {
|
|
154
169
|
columnId: SORT_COLUMNS[String(args.options.sort)] ?? "date",
|
|
@@ -161,7 +176,7 @@ export function createAnalystResearchHeadless(
|
|
|
161
176
|
currency: currency ?? null,
|
|
162
177
|
}));
|
|
163
178
|
const sections: HeadlessBundleSection[] = [
|
|
164
|
-
{ title: "Summary", entries: overviewEntries(data) },
|
|
179
|
+
{ title: "Summary", entries: overviewEntries(data, quote) },
|
|
165
180
|
{ title: "Recent analyst actions", columns: RATING_COLUMNS, rows: ratings },
|
|
166
181
|
];
|
|
167
182
|
return {
|
|
@@ -174,6 +189,8 @@ export function createAnalystResearchHeadless(
|
|
|
174
189
|
currency: currency ?? null,
|
|
175
190
|
fetchedAt: data.fetchedAt,
|
|
176
191
|
stale: data.stale,
|
|
192
|
+
upside: upside ?? null,
|
|
193
|
+
upsideReference: analystReferenceMetadata(reference),
|
|
177
194
|
},
|
|
178
195
|
};
|
|
179
196
|
},
|
|
@@ -6,7 +6,9 @@ import { displayWidth, formatCurrency, formatNumber } from "../../../utils/forma
|
|
|
6
6
|
import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
|
|
7
7
|
import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
8
8
|
import { delayedFooterSegment } from "../../../components/layout/pane/footer/model";
|
|
9
|
-
import { regularSessionValuationPrice } from "../../../market-data/quotes/regular-session-valuation";
|
|
9
|
+
import { regularSessionValuationPrice, regularSessionValuationTime } from "../../../market-data/quotes/regular-session-valuation";
|
|
10
|
+
import { getCompletedRegularSessionDisplay } from "../../../market-data/market/status";
|
|
11
|
+
import { formatUtcDayTime, parseReportTime, type ReportTime } from "../../../utils/utc-time";
|
|
10
12
|
|
|
11
13
|
function compactPeriod(period: string): string {
|
|
12
14
|
return period
|
|
@@ -32,6 +34,15 @@ export interface AnalystReferencePrice {
|
|
|
32
34
|
/** What the price is when it is the live quote, such as `real-time` or `15m delayed`. */
|
|
33
35
|
freshness: string | null;
|
|
34
36
|
live: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* When the price is from: a live quote's regular session close once that session is over, else the quote's own
|
|
39
|
+
* time (regularSessionValuationTime); the provider's reference from when the research was fetched. Null unknown.
|
|
40
|
+
*/
|
|
41
|
+
time?: ReportTime | null;
|
|
42
|
+
/** The live price is a completed session's close. */
|
|
43
|
+
close?: boolean;
|
|
44
|
+
/** The exchange-local date of that session, when the quote names it. */
|
|
45
|
+
sessionDate?: string;
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
function quoteFreshness(quote: Quote): string | null {
|
|
@@ -51,12 +62,62 @@ export function analystReferencePrice(
|
|
|
51
62
|
data: AnalystResearchData | null,
|
|
52
63
|
quote: Quote | null | undefined,
|
|
53
64
|
): AnalystReferencePrice {
|
|
54
|
-
const fallback = { price: data?.priceTarget?.current, freshness: null, live: false };
|
|
65
|
+
const fallback = { price: data?.priceTarget?.current, freshness: null, live: false, time: parseReportTime(data?.fetchedAt), close: false };
|
|
55
66
|
const currency = analystTargetCurrency(data);
|
|
56
67
|
const price = regularSessionValuationPrice(quote);
|
|
57
68
|
if (!quote || quote.stale || !currency || price == null) return fallback;
|
|
58
69
|
if (quote.currency?.trim() !== currency) return fallback;
|
|
59
|
-
return {
|
|
70
|
+
return {
|
|
71
|
+
price, freshness: quoteFreshness(quote), live: true,
|
|
72
|
+
time: regularSessionValuationTime(quote), close: getCompletedRegularSessionDisplay(quote) != null,
|
|
73
|
+
...(quote.regularCloseSessionDate ? { sessionDate: quote.regularCloseSessionDate } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The upside and what it is measured from, as `analyst`, `fn ANR` and the ANR
|
|
79
|
+
* pane read it: the average target over Last (the quote's regular session
|
|
80
|
+
* price, as `valuation` and RV show it), or the provider's reference price when
|
|
81
|
+
* no quote in the target's currency stands (analystReferencePrice).
|
|
82
|
+
*/
|
|
83
|
+
export function analystUpside(data: AnalystResearchData | null, quote: Quote | null | undefined) {
|
|
84
|
+
const reference = analystReferencePrice(data, quote);
|
|
85
|
+
return { upside: targetUpside(data?.priceTarget, reference.price), reference };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** The reference an upside is measured from, for JSON: the price, when it is from, and whose it is. */
|
|
89
|
+
export function analystReferenceMetadata(reference: AnalystReferencePrice) {
|
|
90
|
+
const time = reference.time;
|
|
91
|
+
return {
|
|
92
|
+
price: reference.price ?? null,
|
|
93
|
+
asOf: time ? (time.dateOnly ? new Date(time.time).toISOString().slice(0, 10) : new Date(time.time).toISOString()) : null,
|
|
94
|
+
basis: !reference.live ? "provider reference at retrieval" : reference.close ? "regular session close" : "regular session price",
|
|
95
|
+
...(reference.freshness ? { freshness: reference.freshness } : {}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** When a reference price is from, in the words a change line uses: "Thu 22 Oct close" or a print's time. */
|
|
100
|
+
function analystReferenceWhen(reference: AnalystReferencePrice, now: number): string {
|
|
101
|
+
const at = (time: ReportTime) => formatUtcDayTime(time, now) + (time.dateOnly ? "" : " UTC");
|
|
102
|
+
if (reference.live && reference.close) {
|
|
103
|
+
const day = reference.sessionDate ? { time: Date.parse(`${reference.sessionDate}T00:00:00Z`), dateOnly: true }
|
|
104
|
+
: reference.time ? { ...reference.time, dateOnly: true } : null;
|
|
105
|
+
return day ? `${at(day)} close` : "close";
|
|
106
|
+
}
|
|
107
|
+
return reference.time ? at(reference.time) : "";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The price an upside is measured from and when it is from: "$141.39, Thu 22 Oct close", "$141.39, Fri 23 Oct
|
|
112
|
+
* 14:05 UTC (15m delayed)" while the session trades, or the provider's reference, "$137.32, provider reference at
|
|
113
|
+
* retrieval Wed 21 Oct 21:30 UTC".
|
|
114
|
+
*/
|
|
115
|
+
export function formatAnalystReference(reference: AnalystReferencePrice, currency: string | undefined, now = Date.now()): string {
|
|
116
|
+
if (reference.price == null || !Number.isFinite(reference.price)) return "-";
|
|
117
|
+
const price = formatAnalystPrice(reference.price, currency);
|
|
118
|
+
const when = analystReferenceWhen(reference, now);
|
|
119
|
+
if (!reference.live) return `${price}, provider reference${when ? ` at retrieval ${when}` : ""}`;
|
|
120
|
+
return `${price}${when ? `, ${when}` : ""}${reference.freshness && !reference.close ? ` (${reference.freshness})` : ""}`;
|
|
60
121
|
}
|
|
61
122
|
|
|
62
123
|
function isCurrentMonthPeriod(period: string | undefined): boolean {
|
|
@@ -340,6 +401,7 @@ export function buildAnalystFooterInfo(
|
|
|
340
401
|
export function buildAnalystStatusSegments(
|
|
341
402
|
data: AnalystResearchData | null,
|
|
342
403
|
reference: AnalystReferencePrice = analystReferencePrice(data, null),
|
|
404
|
+
now = Date.now(),
|
|
343
405
|
): PaneFooterSegment[] {
|
|
344
406
|
if (!data) return [];
|
|
345
407
|
|
|
@@ -372,11 +434,14 @@ export function buildAnalystStatusSegments(
|
|
|
372
434
|
if (reference.price != null) {
|
|
373
435
|
// A delayed price is the footer's clock beside it; a real-time one says so in words.
|
|
374
436
|
const delay = reference.freshness?.endsWith(" delayed") ? reference.freshness.slice(0, -" delayed".length) : null;
|
|
437
|
+
const when = !reference.live ? "provider ref" : reference.close ? analystReferenceWhen(reference, now) : null;
|
|
375
438
|
segments.push({
|
|
376
439
|
id: "analyst-reference-price",
|
|
377
440
|
parts: [
|
|
378
441
|
{ text: "upside vs", tone: "label" },
|
|
379
442
|
{ text: price(reference.price) },
|
|
443
|
+
// When it is from, as `analyst` and `fn ANR` print it: "Thu 22 Oct close" or the provider's reference.
|
|
444
|
+
...(when ? [{ text: when, tone: "muted" as const }] : []),
|
|
380
445
|
...(reference.freshness && !delay ? [{ text: reference.freshness, tone: "muted" as const }] : []),
|
|
381
446
|
],
|
|
382
447
|
});
|