gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -5,9 +5,10 @@ import { isAccessDenied } from "../../../api-client/errors";
|
|
|
5
5
|
import { usePlanAccess } from "../../../api-client/plan-access";
|
|
6
6
|
import type { SupplyChainPayload, SupplyOptions, SupplyRole, SupplyRow, SupplyTierFilter } from "../../../api-client/supply-chain";
|
|
7
7
|
import {
|
|
8
|
-
Badge, buildSectionedRows, DataTableView, EmptyState, isSectionedItemRow, PageStackView, renderSectionedRowHeader, PaneStatusBody, QueryBar, StatGrid,
|
|
9
|
-
usePaneStatusFooter, usePaneTabs, type DataTableCell, type DataTableColumn, type PaneHint, type SectionedRow, type StatItem,
|
|
8
|
+
Badge, buildSectionedRows, ChartTableHeader, DataTableView, EmptyState, formatPercentAxis, isSectionedItemRow, PageStackView, renderSectionedRowHeader, PaneStatusBody, QueryBar, StatGrid,
|
|
9
|
+
statGridRows, useChartTableSelection, usePaneNoticeFooter, usePaneStatusFooter, usePaneTabs, type DataTableCell, type DataTableColumn, type PaneHint, type SectionedRow, type StatItem,
|
|
10
10
|
} from "../../../components";
|
|
11
|
+
import { staticSeries } from "../../../components/chart/static/series";
|
|
11
12
|
import { ClippedText } from "../../../components/ui/display";
|
|
12
13
|
import { RatioBar } from "../../../components/ui/ratio-bar";
|
|
13
14
|
import { getTableWidth } from "../../../components/ui/table-layout";
|
|
@@ -30,7 +31,7 @@ import { SupplyFlow } from "./flow";
|
|
|
30
31
|
import { SupplyGraphPane } from "./graph-pane";
|
|
31
32
|
import { entityTicker } from "./graph-model";
|
|
32
33
|
import {
|
|
33
|
-
cellText, counterpartyKind, counterpartyKindLabel, counterpartyLabel, counterpartyName, disclosedValue, earlierRows, lockedDisclosures, nativeValue, percentage, ROLE_COLORS, roleLabel,
|
|
34
|
+
cellText, counterpartyKind, counterpartyKindLabel, counterpartyLabel, counterpartyName, disclosedValue, earlierRows, fitShareBasis, receivablesConcentration, lockedDisclosures, nativeValue, percentage, ROLE_COLORS, roleLabel,
|
|
34
35
|
shareParts, sortRows, supplyPreviewNote, supplyRoleCounts, type SupplySort,
|
|
35
36
|
} from "./model";
|
|
36
37
|
import { RowEvidence } from "./row-evidence";
|
|
@@ -38,37 +39,58 @@ import { evidenceDate, evidenceLabel, isUnconfirmed, matchesSupplyOptions, suppl
|
|
|
38
39
|
|
|
39
40
|
type Item = { kind: "edge"; row: SupplyRow } | { kind: "locked"; id: string };
|
|
40
41
|
const itemId = (item: Item) => item.kind === "edge" ? item.row.id : item.id;
|
|
42
|
+
const rowId = (row: SupplyRow) => row.id;
|
|
43
|
+
const formatShare = (value: number) => `${Number(value.toFixed(2))}%`;
|
|
41
44
|
const ROLE_PLURALS: Record<SupplyRole, string> = { customer: "Customers", supplier: "Suppliers", partner: "Partners", competitor: "Competitors", investee: "Investees" };
|
|
42
45
|
/** A share figure is at most five cells (`99.9%`, `100%`), right-aligned so the bars line up. */
|
|
43
46
|
const SHARE_FIGURE_CELLS = 5;
|
|
44
|
-
/** Bar, gap and figure:
|
|
47
|
+
/** Bar, gap and figure: the least a share cell draws with its bar. */
|
|
45
48
|
const SHARE_BAR_MIN_CELLS = 3 + 1 + SHARE_FIGURE_CELLS;
|
|
49
|
+
/** Cells a column keeps for the bare basis of the longest row (`cost of sales`); a longer one is cut by an ellipsis. */
|
|
50
|
+
const SHARE_BASIS_FLOOR_CELLS = 13;
|
|
51
|
+
/** Cells of basis kept in the last resort: three letters and an ellipsis. */
|
|
52
|
+
const SHARE_BASIS_LAST_CELLS = 4;
|
|
53
|
+
|
|
54
|
+
/** Every row's basis as the cells of each form, whole wording first: what a share column is laid out by. */
|
|
55
|
+
type BasisForms = readonly (readonly number[])[];
|
|
56
|
+
|
|
57
|
+
/** Cells a row's basis keeps in `room`: its longest whole form that fits, else as much of its bare form as the floor allows. */
|
|
58
|
+
const keptBasis = (forms: readonly number[], room: number) => forms.find((cells) => cells <= room) ?? Math.min(room, SHARE_BASIS_FLOOR_CELLS);
|
|
59
|
+
/** The cells the narrowest column keeps for the longest bare basis. */
|
|
60
|
+
const bareBasis = (bases: BasisForms) => Math.min(SHARE_BASIS_FLOOR_CELLS, Math.max(0, ...bases.map((forms) => forms[forms.length - 1]!)));
|
|
61
|
+
|
|
62
|
+
/** Cells of a share column's bar and of its basis; no bar leaves the figure beside its basis. */
|
|
63
|
+
interface ShareLayout { bar: number; basis: number }
|
|
46
64
|
|
|
47
65
|
/**
|
|
48
|
-
*
|
|
49
|
-
* and
|
|
50
|
-
*
|
|
66
|
+
* The bar and the basis of a share column, the same on every row so the bars
|
|
67
|
+
* and figures line up. A share keeps what it is a share of: the column gives
|
|
68
|
+
* up the bar, then the whole wording, before it gives up the basis. The bar
|
|
69
|
+
* takes what the longest basis leaves, between 3 and 8 cells.
|
|
51
70
|
*/
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
function shareLayout(width: number, bases: BasisForms): ShareLayout {
|
|
72
|
+
const beside = width - SHARE_BAR_MIN_CELLS - 1;
|
|
73
|
+
if (beside >= bareBasis(bases)) {
|
|
74
|
+
const longest = Math.max(0, ...bases.map((forms) => keptBasis(forms, beside)));
|
|
75
|
+
const bar = Math.min(width >= 36 ? 8 : 5, Math.max(3, width - SHARE_FIGURE_CELLS - 2 - longest));
|
|
76
|
+
return { bar, basis: width - bar - SHARE_FIGURE_CELLS - 2 };
|
|
77
|
+
}
|
|
78
|
+
return { bar: 0, basis: Math.max(0, width - SHARE_FIGURE_CELLS - 1) };
|
|
57
79
|
}
|
|
58
|
-
const longestBasis = (bases: readonly number[], width: number) => Math.max(0, ...bases.filter((cells) => SHARE_BAR_MIN_CELLS + 1 + cells <= width));
|
|
59
80
|
|
|
60
81
|
/** A period end date; its length, when the source states it, follows it in a wider column. */
|
|
61
82
|
const PERIOD_DATE_CELLS = 10;
|
|
62
83
|
/**
|
|
63
84
|
* Columns that fit the pane, giving up the least first: the share bar shortens
|
|
64
85
|
* to keep the whole basis, the name shortens to 18 cells, the ticker folds into
|
|
65
|
-
* the name and the period is left to the evidence view; then the share
|
|
66
|
-
* its
|
|
67
|
-
*
|
|
86
|
+
* the name and the period is left to the evidence view; then the share gives
|
|
87
|
+
* its bar, then its whole wording for the bare basis, and the name shortens
|
|
88
|
+
* further. A share never loses its basis. Only a pane narrower than that
|
|
89
|
+
* scrolls sideways, so the pane edge never cuts a share in half.
|
|
68
90
|
* Value shows only when some row discloses a value, retaining its original
|
|
69
91
|
* currency and units.
|
|
70
92
|
*/
|
|
71
|
-
function tableColumns(width: number, desktop: boolean, locked: boolean, valueWidth: number | null, bases:
|
|
93
|
+
function tableColumns(width: number, desktop: boolean, locked: boolean, valueWidth: number | null, bases: BasisForms, periodWidth = PERIOD_DATE_CELLS): DataTableColumn[] {
|
|
72
94
|
const wide = width >= 150, medium = width >= 110;
|
|
73
95
|
const name: DataTableColumn = { id: "name", label: "Counterparty", width: Math.max(locked && !desktop ? 34 : 0, wide ? 30 : medium ? 26 : 20), flexGrow: 1, align: "left" };
|
|
74
96
|
const share: DataTableColumn = { id: "pct", label: "Share", width: wide ? 34 : medium ? 30 : 26, align: "left" };
|
|
@@ -89,8 +111,11 @@ function tableColumns(width: number, desktop: boolean, locked: boolean, valueWid
|
|
|
89
111
|
const preferred = { share: share.width, name: name.width };
|
|
90
112
|
// The table ignores its last trailing gutter when deciding whether it fits.
|
|
91
113
|
const overflow = () => getTableWidth(columns) - width - 1;
|
|
92
|
-
// Native units keep their column before the share keeps its bar or
|
|
93
|
-
const
|
|
114
|
+
// Native units keep their column before the share keeps its bar or its whole wording.
|
|
115
|
+
const withBar = SHARE_BAR_MIN_CELLS + 1;
|
|
116
|
+
const plain = SHARE_FIGURE_CELLS + 1;
|
|
117
|
+
const bare = bareBasis(bases);
|
|
118
|
+
const shareFloor = withBar + (valueWidth !== null ? bare : Math.max(bare, ...bases.map((forms) => keptBasis(forms, preferred.share - withBar))));
|
|
94
119
|
const fit = (shareMin: number, nameMin = 18) => {
|
|
95
120
|
share.width = preferred.share; name.width = preferred.name;
|
|
96
121
|
share.width = Math.max(shareMin, share.width - Math.max(0, overflow()));
|
|
@@ -103,9 +128,12 @@ function tableColumns(width: number, desktop: boolean, locked: boolean, valueWid
|
|
|
103
128
|
columns = columns.filter((column) => column.id !== id);
|
|
104
129
|
fit(shareFloor);
|
|
105
130
|
}
|
|
106
|
-
// The narrowest panes keep the figure
|
|
107
|
-
|
|
108
|
-
if (overflow() > 0) fit(
|
|
131
|
+
// The narrowest panes keep the figure and the bare basis, then a shorter name and a cut basis, before anything scrolls.
|
|
132
|
+
const shares = bases.length > 0;
|
|
133
|
+
if (overflow() > 0) fit(withBar + bare);
|
|
134
|
+
if (overflow() > 0 && shares) fit(plain + bare);
|
|
135
|
+
if (overflow() > 0) fit(shares ? plain + bare : SHARE_FIGURE_CELLS + 2, 12);
|
|
136
|
+
if (overflow() > 0 && shares) fit(plain + SHARE_BASIS_LAST_CELLS, 12);
|
|
109
137
|
return columns;
|
|
110
138
|
}
|
|
111
139
|
|
|
@@ -123,20 +151,20 @@ function supplyFigures(data: SupplyChainPayload, views: readonly ("says" | "name
|
|
|
123
151
|
|
|
124
152
|
/**
|
|
125
153
|
* The share as a bar on a 0 to 100% scale, the figure, and what it is a share
|
|
126
|
-
* of. The basis
|
|
127
|
-
*
|
|
154
|
+
* of. The basis never goes: a column too narrow for the whole wording shows a
|
|
155
|
+
* shorter form of it, then drops the bar, then cuts it behind an ellipsis.
|
|
156
|
+
* The evidence view and the selected row's line say it whole.
|
|
128
157
|
*/
|
|
129
|
-
function ShareCell({ row, focusId, width,
|
|
158
|
+
function ShareCell({ row, focusId, width, layout, selected }: { row: SupplyRow; focusId?: string; width: number; layout: ShareLayout; selected: boolean }) {
|
|
130
159
|
const colors = useThemeColors();
|
|
131
160
|
const share = shareParts(row, focusId);
|
|
132
161
|
if (!share) return <Text fg={colors.textMuted}>{""}</Text>;
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
const basis = bar + SHARE_FIGURE_CELLS + 2 + displayWidth(share.basis) <= width;
|
|
162
|
+
const ink = selected ? colors.selectedText : colors.textBright;
|
|
163
|
+
const basis = fitShareBasis(share, layout.basis);
|
|
136
164
|
return <Box flexDirection="row" width={width} height={1} gap={1} overflow="hidden">
|
|
137
|
-
<RatioBar ratio={row.pctOfRevenue! / 100} width={bar} color={ROLE_COLORS[row.role]} track />
|
|
138
|
-
<Text fg={
|
|
139
|
-
{basis ? <Text fg={selected ? colors.selectedText : colors.textDim}>{
|
|
165
|
+
{layout.bar ? <RatioBar ratio={row.pctOfRevenue! / 100} width={layout.bar} color={ROLE_COLORS[row.role]} track /> : null}
|
|
166
|
+
<Text fg={ink} attributes={TextAttributes.BOLD}>{share.value.padStart(SHARE_FIGURE_CELLS)}</Text>
|
|
167
|
+
{basis ? <Text fg={selected ? colors.selectedText : colors.textDim}>{basis}</Text> : null}
|
|
140
168
|
</Box>;
|
|
141
169
|
}
|
|
142
170
|
|
|
@@ -225,9 +253,18 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
225
253
|
...(savedTab === "flow" && tooSmall ? ["Flow needs a wider pane. Showing the table."] : []),
|
|
226
254
|
] });
|
|
227
255
|
const focusId = data?.entity?.id;
|
|
256
|
+
// Over the table, how much of the receivables one customer holds at each period end the company disclosed.
|
|
257
|
+
const concentration = useMemo(() => tab === "table" && view === "says" ? receivablesConcentration(tableRows, focusId) : [], [tab, view, tableRows, focusId]);
|
|
258
|
+
const concentrationDates = useMemo(() => new Map(concentration.map((point) => [point.rowId, point.date])), [concentration]);
|
|
259
|
+
const getConcentrationDate = useCallback((row: SupplyRow) => concentrationDates.get(row.id) ?? null, [concentrationDates]);
|
|
260
|
+
const chartSelection = useChartTableSelection({ rows: tableRows, getId: rowId, getDate: getConcentrationDate,
|
|
261
|
+
selectedId: selected?.id ?? null, onSelect: setSelected, focused: focused && !openRow, enabled: concentration.length > 0 });
|
|
262
|
+
const concentrationSeries = useMemo(() => [{ ...staticSeries(concentration.map((point) => ({ date: point.date, observedAt: point.date, value: point.pct })),
|
|
263
|
+
{ id: "receivables-concentration", label: "Largest disclosed customer · receivables", color: ROLE_COLORS.customer, calendarSpaced: true, style: "points" }), unit: "%", unitGroup: "percent" }], [concentration]);
|
|
264
|
+
const concentrationChart = concentration.length ? { series: concentrationSeries, formatValue: formatShare, formatAxisValue: formatPercentAxis, strip: null, ...chartSelection } : null;
|
|
228
265
|
const values = tableRows.filter((row) => nativeValue(row) !== null || row.usd !== null);
|
|
229
266
|
const valueWidth = values.length ? Math.min(28, Math.max(...values.map((row) => displayWidth(disclosedValue(row).replace(/ (disclosed|derived)$/, ""))))) : null;
|
|
230
|
-
const bases = tableRows.flatMap((row) => { const share = shareParts(row, focusId); return share ? [
|
|
267
|
+
const bases: BasisForms = tableRows.flatMap((row) => { const share = shareParts(row, focusId); return share ? [share.forms.map(displayWidth)] : []; });
|
|
231
268
|
// The period's length follows its end date when the source states it (2026-07-31 half) and costs
|
|
232
269
|
// no column; laid out a cell narrower, the table also clears its own scrollbar. Otherwise the
|
|
233
270
|
// evidence view says it.
|
|
@@ -235,6 +272,7 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
235
272
|
const dated = tableColumns(width, desktop, locked > 0, valueWidth, bases);
|
|
236
273
|
const lengths = periodWidth > PERIOD_DATE_CELLS ? tableColumns(width - 1, desktop, locked > 0, valueWidth, bases, periodWidth) : null;
|
|
237
274
|
const columns = lengths?.some((column) => column.id === "fy") && lengths.map((column) => column.id).join() === dated.map((column) => column.id).join() ? lengths : dated;
|
|
275
|
+
const shareColumn = shareLayout(columns.find((column) => column.id === "pct")?.width ?? 0, bases);
|
|
238
276
|
const renderCell = (entry: SectionedRow<Item>, column: DataTableColumn, _index: number, state: { selected: boolean }): DataTableCell => {
|
|
239
277
|
if (!isSectionedItemRow(entry)) return { text: "" };
|
|
240
278
|
const item = entry.item;
|
|
@@ -278,7 +316,7 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
278
316
|
<Text fg={ink ?? ROLE_COLORS[row.role]}>{` ${roleLabel(row.role)}`}</Text>
|
|
279
317
|
</Box> };
|
|
280
318
|
case "pct": return { text: percentage(row) === "--" ? "" : `${shareParts(row, focusId)?.value ?? ""} ${shareParts(row, focusId)?.basis ?? ""}`.trim(), value: row.pctOfRevenue,
|
|
281
|
-
content: <ShareCell row={row} focusId={focusId} width={column.width}
|
|
319
|
+
content: <ShareCell row={row} focusId={focusId} width={column.width} layout={shareColumn} selected={state.selected} /> };
|
|
282
320
|
case "usd": return nativeValue(row) === null && row.usd === null ? { text: "", value: null }
|
|
283
321
|
: { text: disclosedValue(row).replace(/ (disclosed|derived)$/, ""), value: row.nativeAmount != null ? row.nativeAmount * (row.nativeScale ?? 1) : row.usd, color: colors.text };
|
|
284
322
|
case "fy": return { text: displayWidth(cellText(row, "fy")) <= column.width ? cellText(row, "fy") : row.period, color: colors.textDim };
|
|
@@ -291,12 +329,13 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
291
329
|
const bodyHeight = Math.max(3, height - tabRows);
|
|
292
330
|
const figures = data ? supplyFigures(data, tab === "flow" ? ["says", "names"] : [view], options) : [];
|
|
293
331
|
const tierFilter = { id: "tiers", label: "Evidence", kind: "multi" as const, emptyLabel: "Primary", values: options.tiers, options: TIER_OPTIONS, onChange: (value: string[]) => { setTiers(supplyOptions(value).tiers); setSelected(null); setOpen(null); } };
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
332
|
+
const query = <QueryBar width={width} filters={[{ id: "direction", label: "Direction", inline: true, value: view,
|
|
333
|
+
options: [{ value: "says", label: `${symbol} says` }, { value: "names", label: `Names ${symbol}` }], onChange: (value: string) => { setView(value); setSelected(null); setOpen(null); } }, tierFilter]}
|
|
334
|
+
meta={view === "names" ? "% of reporting company's basis" : undefined} />;
|
|
335
|
+
// Without a trend the figures keep every row they had; the chart layout shares the height with the table only when it draws.
|
|
336
|
+
const header = concentrationChart
|
|
337
|
+
? <ChartTableHeader width={width} height={bodyHeight} tableRows={items.length} tableColumns={columns} figures={figures} chart={concentrationChart} query={query} />
|
|
338
|
+
: <Box flexDirection="column" flexShrink={0}>{query}<StatGrid items={figures} width={width} /></Box>;
|
|
300
339
|
const flowFigureColumns = Math.min(Math.max(1, figures.length), Math.max(1, Math.floor(width / 24)));
|
|
301
340
|
// A short flow keeps one row of figures, dropping the last roles, so the cards keep their room.
|
|
302
341
|
const flowFigures = bodyHeight < 26 ? figures.slice(0, flowFigureColumns) : figures;
|
|
@@ -25,7 +25,7 @@ export function SupplyVerification({ row }: { row: SupplyRow }) {
|
|
|
25
25
|
<KeyValueRow label="Corroboration" value={corroborationLabel(row)} labelWidth={20} />
|
|
26
26
|
{row.pctScope ? <KeyValueRow label={row.sourceKind === "xbrl" ? "Tagged context" : "Percentage scope"} value={row.pctScope} labelWidth={20} /> : null}
|
|
27
27
|
{row.sectionRef ? <KeyValueRow label="Section" value={row.sectionRef} labelWidth={20} /> : null}
|
|
28
|
-
{row.jurisdiction ? <KeyValueRow label="Jurisdiction" value={row.jurisdiction} labelWidth={20} /> : null}
|
|
28
|
+
{row.jurisdiction ? <KeyValueRow label="Jurisdiction" value={row.jurisdiction} country={row.jurisdiction} labelWidth={20} /> : null}
|
|
29
29
|
{row.firstSeenAt ? <KeyValueRow label="First seen" value={row.firstSeenAt.slice(0, 10)} detail={row.lastSeenAt ? `last seen ${row.lastSeenAt.slice(0, 10)}` : undefined} labelWidth={20} /> : null}
|
|
30
30
|
{!isUnconfirmed(row) && row.lastConfirmedAt ? <KeyValueRow label="Last confirmed" value={row.lastConfirmedAt.slice(0, 10)} labelWidth={20} /> : null}
|
|
31
31
|
</>;
|
|
@@ -5,7 +5,7 @@ import { formatRelativeAge } from "../../../utils/datetime-format";
|
|
|
5
5
|
import { fetchThemeMembers, fetchThemes } from "./client";
|
|
6
6
|
import {
|
|
7
7
|
aggregateText, boardClose, boardYtdBase, DEFAULT_SORT, matchTheme, memberExtended, memberExtendedSessions, memberPrice, percent, periodLabel,
|
|
8
|
-
SNAPSHOT_STALE_MS, sortMembers, sortThemes,
|
|
8
|
+
isLiveBoard, SNAPSHOT_STALE_MS, sortMembers, sortThemes,
|
|
9
9
|
} from "./model";
|
|
10
10
|
|
|
11
11
|
/** The period columns; YTD names the close it is measured from, `YTD vs 31 Dec close`. */
|
|
@@ -50,13 +50,15 @@ function boardObservation(payload: ThemesPayload | ThemeMembersPayload, now = Da
|
|
|
50
50
|
regularSessionDate: close?.date ?? null,
|
|
51
51
|
regularSessionClosedAt: close?.closedAt ?? null,
|
|
52
52
|
};
|
|
53
|
+
// A Pro account's board is priced from the server's live read.
|
|
54
|
+
const feed = isLiveBoard(payload) ? { status: "live" as const } : {};
|
|
53
55
|
if (close && now - assembledAt <= SNAPSHOT_STALE_MS) {
|
|
54
56
|
return {
|
|
55
57
|
metadata: { asOf: close.closedAt != null ? new Date(close.closedAt).toISOString() : close.date, sessionExchange: "NYSE", ...snapshot },
|
|
56
|
-
freshness: { tradingDayMarket: "US", note: `snapshot ${formatRelativeAge(assembledAt, now)}` },
|
|
58
|
+
freshness: { ...feed, tradingDayMarket: "US", note: `snapshot ${formatRelativeAge(assembledAt, now)}` },
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
|
-
return { metadata: { asOf: payload.asOf, ...snapshot }, freshness: { maxAgeMinutes: 30 } };
|
|
61
|
+
return { metadata: { asOf: payload.asOf, ...snapshot }, freshness: { ...feed, maxAgeMinutes: 30 } };
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
/**
|
|
@@ -74,14 +76,15 @@ function themeReportTitle(query: string | undefined, theme: Pick<ThemeSummary, "
|
|
|
74
76
|
|
|
75
77
|
export const themesHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
76
78
|
shape: "rows",
|
|
77
|
-
// The pane's stored snapshot
|
|
79
|
+
// The pane's stored snapshot, refreshed every 15 minutes, priced in real time for a Pro account and
|
|
80
|
+
// fifteen minutes delayed otherwise (boardObservation says which). As in the pane,
|
|
78
81
|
// the payload's stale flags are historical; a snapshot over 30 minutes old is what reads stale
|
|
79
82
|
// (boardObservation, which dates a board outside the regular session by its close).
|
|
80
83
|
freshness: { status: "delayed", delayMinutes: 15, ignoreStaleFlags: true },
|
|
81
84
|
argument: { kind: "free-text", optional: true, placeholder: "theme", description: "Theme name or keyword, such as nuclear; omit for all themes." },
|
|
82
85
|
options: [],
|
|
83
86
|
discovery: { aliases: ["THEM"], dataRequirements: ["Gloom Cloud stored equity snapshot"],
|
|
84
|
-
limitations: ["
|
|
87
|
+
limitations: ["Prices and 1D are real-time with Pro and fifteen minutes delayed otherwise; the longer returns start from a snapshot updated every 15 minutes.", "Equal-weight price returns; missing observations reduce coverage.", "Below half coverage a period is unavailable.",
|
|
85
88
|
"Outside the regular session Price, 1D and the returns end at the last regular close; a pre-market or after-hours print is shown beside it and never enters them."] },
|
|
86
89
|
describe: (args, result) => themeReportTitle(args.rawArgument, (result?.metadata as { theme?: ThemeSummary } | undefined)?.theme),
|
|
87
90
|
async load(args, context) {
|
|
@@ -82,14 +82,24 @@ function closeLabel(date: string): string {
|
|
|
82
82
|
* How current the board is, for its footer. Outside the regular session the
|
|
83
83
|
* close its figures describe and how old the snapshot is, `Fri 9 Oct close ·
|
|
84
84
|
* snapshot 12m ago`; while a session trades, or from a server that does not
|
|
85
|
-
* name the close,
|
|
86
|
-
*
|
|
85
|
+
* name the close, whether its prices are live (a Pro account's) or delayed,
|
|
86
|
+
* and the snapshot's age, which the longer returns start from. `age` is the
|
|
87
|
+
* relative age (`12m ago`).
|
|
87
88
|
*/
|
|
88
|
-
export function snapshotFooterText(payload: { regularSessionDate?: unknown; regularSessionClosedAt?: unknown }, age: string): string {
|
|
89
|
+
export function snapshotFooterText(payload: { regularSessionDate?: unknown; regularSessionClosedAt?: unknown; access?: unknown }, age: string): string {
|
|
89
90
|
const close = boardClose(payload);
|
|
90
|
-
|
|
91
|
+
if (close) return `${closeLabel(close.date)} · snapshot ${age}`;
|
|
92
|
+
return `${isLiveBoard(payload) ? "live" : "15m delayed"} · snapshot ${age}`;
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
/** Whether a board's prices are real-time: a Pro account's, priced from the server's live read. */
|
|
96
|
+
export function isLiveBoard(payload: { access?: unknown } | null | undefined): boolean {
|
|
97
|
+
return payload?.access === "realtime";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** How often a board is worth checking again: the server renews a live board's prices every 15 seconds. */
|
|
101
|
+
export const LIVE_BOARD_REFRESH_MS = 15_000;
|
|
102
|
+
|
|
93
103
|
/** A member's pre-market or after-hours print and its move from the close in Price, when it has a valid one. */
|
|
94
104
|
export function memberExtended(row: ThemeMember): { session: ExtendedSession; price: number; change: number | null; changePercent: number | null } | null {
|
|
95
105
|
const session = row.extendedSession;
|
|
@@ -13,10 +13,21 @@ import { useMembersMenu } from "../shared/members-menu";
|
|
|
13
13
|
import { cachedMembers, cachedThemes, loadMembers, loadThemes } from "./client";
|
|
14
14
|
import {
|
|
15
15
|
aggregateText, boardYtdBase, coverageWidth, DEFAULT_SORT, extendedMove, matchTheme, memberColumns, memberExtendedSessions, memberPrice, percent,
|
|
16
|
-
SNAPSHOT_STALE_MS, snapshotFooterText, sortMembers, sortThemes, themeColumns, type ThemeSort,
|
|
16
|
+
isLiveBoard, LIVE_BOARD_REFRESH_MS, SNAPSHOT_STALE_MS, snapshotFooterText, sortMembers, sortThemes, themeColumns, type ThemeSort,
|
|
17
17
|
} from "./model";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const LIVE_LEAD = "live · ";
|
|
20
|
+
type SnapshotPayload = { asOf: string; stale: boolean; access?: "realtime" | "delayed"; regularSessionDate?: string | null; regularSessionClosedAt?: number | null };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Refreshes a board on the user's interval, or every 15 seconds while it is
|
|
24
|
+
* live: a Pro account's prices are renewed that often on the server.
|
|
25
|
+
*/
|
|
26
|
+
function useBoardRefresh(resource: { updatedAt: number | null; load: (force?: boolean) => Promise<unknown>; data: { payload: SnapshotPayload } | null }) {
|
|
27
|
+
const live = isLiveBoard(resource.data?.payload);
|
|
28
|
+
const { load } = resource;
|
|
29
|
+
useAutoRefresh(resource.updatedAt, live ? () => void load(true) : () => void load(), { intervalMs: live ? LIVE_BOARD_REFRESH_MS : null });
|
|
30
|
+
}
|
|
20
31
|
|
|
21
32
|
function useSnapshotFooter(id: string, resource: { loading: boolean; error: string | null; data: { payload: SnapshotPayload; stale: boolean; refreshError: string | null } | null }, focused: boolean, enabled = true) {
|
|
22
33
|
const data = resource.data;
|
|
@@ -24,7 +35,15 @@ function useSnapshotFooter(id: string, resource: { loading: boolean; error: stri
|
|
|
24
35
|
const payload = data?.payload;
|
|
25
36
|
// Outside the regular session the figures are a close, so the footer names it, not the snapshot's time.
|
|
26
37
|
const text = age && payload ? snapshotFooterText(payload, age) : null;
|
|
27
|
-
const info = useMemo(() =>
|
|
38
|
+
const info = useMemo(() => {
|
|
39
|
+
if (!text) return [];
|
|
40
|
+
// A live board says so as the other live panes do, before the snapshot's age.
|
|
41
|
+
if (text.startsWith(LIVE_LEAD)) {
|
|
42
|
+
return [{ id: "snapshot-live", parts: [{ text: "live", tone: "positive" as const }] },
|
|
43
|
+
{ id: "snapshot", parts: [{ text: text.slice(LIVE_LEAD.length), tone: "muted" as const }] }];
|
|
44
|
+
}
|
|
45
|
+
return splitDelayedStatus({ id: "snapshot", parts: [{ text, tone: "muted" }] });
|
|
46
|
+
}, [text]);
|
|
28
47
|
// The server flag includes retained historical returns; it does not mean the daily board is old.
|
|
29
48
|
const snapshotStale = !!data && Date.now() - Date.parse(data.payload.asOf) > SNAPSHOT_STALE_MS;
|
|
30
49
|
usePaneStatusFooter({ registrationId: id, enabled, loading: resource.loading && !!data,
|
|
@@ -49,7 +68,7 @@ function Members({ id, width, height, focused }: { id: string; width: number; he
|
|
|
49
68
|
const ytdBase = data ? boardYtdBase(data) : null;
|
|
50
69
|
const columns = useMemo(() => memberColumns(width, extendedSessionsKey ? extendedSessionsKey.split(",") as ExtendedSession[] : [], ytdBase),
|
|
51
70
|
[extendedSessionsKey, width, ytdBase]);
|
|
52
|
-
|
|
71
|
+
useBoardRefresh(resource);
|
|
53
72
|
usePaneRefreshKey(() => void resource.reload(), { focused });
|
|
54
73
|
useSnapshotFooter("themes:members", resource, focused);
|
|
55
74
|
const memberList = useMemo(() => data ? { title: data.theme.name, watchlistName: data.theme.name, members: rows } : null, [data, rows]);
|
|
@@ -107,7 +126,7 @@ export function ThemesBoard({ width, height, focused, tabStrip, tabRows = 0 }: T
|
|
|
107
126
|
const rows = useMemo(() => sortThemes(data?.themes ?? [], sort), [data, sort]);
|
|
108
127
|
const columns = useMemo(() => themeColumns(width, data?.themes ?? [], data ? boardYtdBase(data) : null), [width, data]);
|
|
109
128
|
const theme = opened && data ? matchTheme(data.themes, opened) : null;
|
|
110
|
-
|
|
129
|
+
useBoardRefresh(resource);
|
|
111
130
|
usePaneRefreshKey(() => void resource.reload(), { focused, enabled: !opened });
|
|
112
131
|
useSnapshotFooter("themes:list", resource, focused, !opened || !data);
|
|
113
132
|
const renderCell = useCallback((row: ThemeSummary, column: DataTableColumn): DataTableCell => {
|
|
@@ -471,10 +471,10 @@ function thirteenFShotState(args: HeadlessPaneLoadArgs, metadata: Record<string,
|
|
|
471
471
|
});
|
|
472
472
|
}
|
|
473
473
|
case "crowding":
|
|
474
|
-
if (query) throw new Error(`The 13F pane draws the whole crowding ranking, not one ticker's rank. Drop "${query}" from shot, or run the report:
|
|
474
|
+
if (query) throw new Error(`The 13F pane draws the whole crowding ranking, not one ticker's rank. Drop "${query}" from shot, or run the report: gloom fn 13F ${query} --view crowding`);
|
|
475
475
|
return { pluginState: { [PANE_STATE_ID]: { browserTab: "crowding", "13f-crowding:ranking": CROWDING_RANKING[String(metadata.rank ?? "new")] ?? "newCount" } } };
|
|
476
476
|
case "performance":
|
|
477
|
-
if (cik) throw new Error(`The 13F pane draws the performance ranking, not one fund's row. Run the report for ${metadata.fund ?? cik}:
|
|
477
|
+
if (cik) throw new Error(`The 13F pane draws the performance ranking, not one fund's row. Run the report for ${metadata.fund ?? cik}: gloom fn 13F ${cik} --view performance, or gloom shot 13F --view performance for the ranking.`);
|
|
478
478
|
return browser("");
|
|
479
479
|
case "latest":
|
|
480
480
|
return browser("latest");
|
|
@@ -484,7 +484,7 @@ function thirteenFShotState(args: HeadlessPaneLoadArgs, metadata: Record<string,
|
|
|
484
484
|
return browser(query);
|
|
485
485
|
case "byTicker":
|
|
486
486
|
// The pane lists a ticker's holders with their positions, and their whole books only when it cannot.
|
|
487
|
-
if (String(args.options.view) !== "auto") throw new Error(`The 13F pane lists a ticker's holders with their positions. Drop --view ${args.options.view} from shot, or run the report:
|
|
487
|
+
if (String(args.options.view) !== "auto") throw new Error(`The 13F pane lists a ticker's holders with their positions. Drop --view ${args.options.view} from shot, or run the report: gloom fn 13F ${query} --view by-ticker`);
|
|
488
488
|
return browser(query);
|
|
489
489
|
default:
|
|
490
490
|
return {};
|
|
@@ -796,7 +796,7 @@ export function createThirteenFHeadless(
|
|
|
796
796
|
// A fund's own row of the performance list, with the command that copies its basket.
|
|
797
797
|
if (view === "performance" && query && inferBrowserTabFromQuery(query) === "funds") {
|
|
798
798
|
const fund = await resolveFund(query, args, ctx, dependencies, {
|
|
799
|
-
notFound: `No 13F fund matched "${query}". For the performance ranking, run
|
|
799
|
+
notFound: `No 13F fund matched "${query}". For the performance ranking, run gloom fn 13F --view performance; for one fund, give its CIK, as in gloom fn 13F 0001067983 --view performance.`,
|
|
800
800
|
});
|
|
801
801
|
const performance = await dependencies.loadPerformance(fund.cik, fund.name, ctx);
|
|
802
802
|
const row = performance.rows[0]!;
|
|
@@ -832,7 +832,7 @@ export function createThirteenFHeadless(
|
|
|
832
832
|
performance.skipped?.length ? splitUnreadText(performance.skipped, "Left out of Est 13F") : "",
|
|
833
833
|
performance.unavailable ? `No Est 13F${rankingText ? ` (${rankingText})` : ""}: ${performance.unavailable}` : "",
|
|
834
834
|
...filingGapNotes(performance.period ?? null, performance.filingGap ?? null),
|
|
835
|
-
`Copy this basket:
|
|
835
|
+
`Copy this basket: gloom portfolio import --13f ${row.cik}`,
|
|
836
836
|
].filter(Boolean),
|
|
837
837
|
},
|
|
838
838
|
};
|
|
@@ -11,6 +11,8 @@ export interface TickerHolderRow {
|
|
|
11
11
|
type: string;
|
|
12
12
|
value: number | null;
|
|
13
13
|
shares: number | null;
|
|
14
|
+
/** Shares at the prior period end when the two reports compare: 0 for a new position, null when unknown. Absent from an older service. */
|
|
15
|
+
previousShares?: number | null;
|
|
14
16
|
weight: number | null;
|
|
15
17
|
previousWeight: number | null;
|
|
16
18
|
weightChange: number | null;
|
|
@@ -55,7 +57,7 @@ export interface Crowding extends SignalsBase {
|
|
|
55
57
|
}
|
|
56
58
|
export async function loadTickerHoldings(ticker: string, offset = 0, signal?: AbortSignal): Promise<TickerHoldings> {
|
|
57
59
|
signal?.throwIfAborted();
|
|
58
|
-
const result = await apiClient.getCloudSec13F("ticker-holdings", { tickers: ticker, offset, limit: 25 }) as TickerHoldings;
|
|
60
|
+
const result = await apiClient.getCloudSec13F("ticker-holdings", { tickers: ticker, offset, limit: 25 }, { signal }) as TickerHoldings;
|
|
59
61
|
signal?.throwIfAborted();
|
|
60
62
|
return result;
|
|
61
63
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { HeadlessPaneDefinition } from "../../../../types/headless";
|
|
2
|
+
import type { Quote } from "../../../../types/financials";
|
|
3
|
+
import { dollarPairLabel, spotFromUsdValue, spotRateKind } from "../../../../market-data/depositary-pair";
|
|
4
|
+
import { loadHeadlessFinancials, resolveHeadlessInstrument } from "../../shared/headless-market-data";
|
|
5
|
+
import { quoteObservation } from "../../shared/report-freshness";
|
|
6
|
+
import { heldCurrencyUnit } from "../../../../utils/currency-units";
|
|
7
|
+
import { adrPairComparison, adrPairFigures, adrPairInputRows, adrPairLegs, ADR_PAIR_TEMPLATE_ID } from "./model";
|
|
8
|
+
|
|
9
|
+
/** Words that ask for this report's figures without being its code: `fn CCL` answers with ADR. */
|
|
10
|
+
export const ADR_PAIR_KEYWORDS = [
|
|
11
|
+
"adr", "adrs", "adr vs home", "adr ratio", "adr premium", "adr discount", "depositary receipt", "depositary receipts",
|
|
12
|
+
"home listing", "home line", "implied fx", "implied exchange rate", "implied dollar", "ccl", "contado con liquidacion",
|
|
13
|
+
"dolar ccl", "mep", "dolar mep", "dolar bolsa", "blue chip swap", "cross listing", "dual listing",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
type LoadContext = Parameters<HeadlessPaneDefinition["load"]>[1];
|
|
17
|
+
|
|
18
|
+
/** The currency's dollar rate, dated when the cached query says when it was observed (as `fx` dates it). */
|
|
19
|
+
async function readSpot(currency: string, ctx: LoadContext) {
|
|
20
|
+
if (currency === "USD") return { rate: 1, observedAt: null };
|
|
21
|
+
const { marketData } = ctx;
|
|
22
|
+
if (marketData.getCachedQuery) {
|
|
23
|
+
const entry = await marketData.getCachedQuery("getExchangeRate", [currency]).load({ background: marketData.revalidatesInBackground });
|
|
24
|
+
return spotFromUsdValue(entry.value, entry.asOf ?? null);
|
|
25
|
+
}
|
|
26
|
+
return spotFromUsdValue(await marketData.getExchangeRate(currency));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A leg's quote through the standard quote path, so both legs are read alike. */
|
|
30
|
+
async function readQuote(key: string, ctx: LoadContext, failed: (error: unknown) => null): Promise<Quote | null> {
|
|
31
|
+
const instrument = await resolveHeadlessInstrument(ctx, key);
|
|
32
|
+
return ctx.marketData.getQuote(instrument.symbol, instrument.exchange ?? "").catch(failed);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const adrPairHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
36
|
+
shape: "bundle",
|
|
37
|
+
argument: { kind: "ticker", description: "A depositary receipt (GGAL, TSM) or its home listing (GGAL.BA, 2330.TW)" },
|
|
38
|
+
options: [],
|
|
39
|
+
discovery: {
|
|
40
|
+
// CCL is also a ticker (Carnival), so neither word opens ADR: `fn CCL` and `catalog ccl` point to it.
|
|
41
|
+
suggestFor: ["CCL", "MEP"],
|
|
42
|
+
screenshotReadiness: "ready",
|
|
43
|
+
limitations: [
|
|
44
|
+
"Listings Gloom Cloud pairs with a receipt only; the ratio is the depositary's, checked against both lines' prices.",
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
description: "A depositary receipt beside its home listing: the ratio, both regular-session prices with when each was set, the dollar rate they imply (home × ratio / ADR, the CCL rate for an Argentine pair), spot, and the receipt's premium or discount at spot.",
|
|
48
|
+
describe: ({ symbols }) => `ADR vs Home | ${symbols[0] ?? ""}`,
|
|
49
|
+
async load({ symbols }, ctx) {
|
|
50
|
+
const key = symbols[0]!;
|
|
51
|
+
const financials = await loadHeadlessFinancials(ctx, key);
|
|
52
|
+
ctx.signal.throwIfAborted();
|
|
53
|
+
const legs = adrPairLegs(financials, null, key);
|
|
54
|
+
if (!legs) {
|
|
55
|
+
return {
|
|
56
|
+
sections: [],
|
|
57
|
+
empty: `${key} has no depositary receipt pair on record. ADR takes a receipt (GGAL, TSM) or its home listing (GGAL.BA, 2330.TW).`,
|
|
58
|
+
unavailableSymbols: [key],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const errors: string[] = [];
|
|
62
|
+
const failed = (label: string) => (error: unknown) => {
|
|
63
|
+
errors.push(`${label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const [receipt, home] = await Promise.all([
|
|
67
|
+
readQuote(legs.receiptKey, ctx, failed(legs.receiptKey)),
|
|
68
|
+
readQuote(legs.homeKey, ctx, failed(legs.homeKey)),
|
|
69
|
+
]);
|
|
70
|
+
ctx.signal.throwIfAborted();
|
|
71
|
+
const quotes = { receipt, home };
|
|
72
|
+
// A minor unit (GBp) is read as its currency, as the comparison reads the price.
|
|
73
|
+
const homeCurrency = quotes.home?.currency ? heldCurrencyUnit(quotes.home.currency).currency : "";
|
|
74
|
+
const spot = homeCurrency ? await readSpot(homeCurrency, ctx).catch(failed(dollarPairLabel(homeCurrency))) : null;
|
|
75
|
+
const comparison = adrPairComparison(legs, quotes, spot);
|
|
76
|
+
if (!comparison) {
|
|
77
|
+
const missing = !quotes.receipt ? legs.receiptKey : legs.homeKey;
|
|
78
|
+
return { sections: [], empty: `No price for ${missing}, so the pair cannot be compared.`, unavailableSymbols: [missing], errors };
|
|
79
|
+
}
|
|
80
|
+
const figures = adrPairFigures(comparison);
|
|
81
|
+
const rows = adrPairInputRows(comparison);
|
|
82
|
+
const kind = spotRateKind(homeCurrency);
|
|
83
|
+
return {
|
|
84
|
+
sections: [
|
|
85
|
+
{
|
|
86
|
+
title: `${legs.receiptKey} vs ${legs.homeKey}`,
|
|
87
|
+
entries: figures.map((figure) => ({
|
|
88
|
+
key: figure.id, label: figure.label,
|
|
89
|
+
value: figure.id === "implied" ? comparison.impliedFx
|
|
90
|
+
: figure.id === "spot" ? comparison.spot?.rate ?? null
|
|
91
|
+
: figure.id === "premium" ? comparison.premiumPercent
|
|
92
|
+
: comparison.ratio,
|
|
93
|
+
formatted: figure.detail ? `${figure.value} (${figure.detail})` : figure.value,
|
|
94
|
+
})),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: "Inputs",
|
|
98
|
+
columns: [
|
|
99
|
+
{ key: "listing", header: "Listing" },
|
|
100
|
+
{ key: "role", header: "Role" },
|
|
101
|
+
{ key: "price", header: "Price", align: "right" },
|
|
102
|
+
{ key: "asOf", header: "As of (UTC)" },
|
|
103
|
+
{ key: "session", header: "Session" },
|
|
104
|
+
],
|
|
105
|
+
rows: rows.map(({ opens: _opens, ...row }) => row),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
...(comparison.timingNote ? { notes: [comparison.timingNote] } : {}),
|
|
109
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
110
|
+
freshness: {
|
|
111
|
+
observations: [quotes.receipt, quotes.home].filter((quote): quote is Quote => !!quote).map((quote) => ({ ...quoteObservation(quote) })),
|
|
112
|
+
},
|
|
113
|
+
metadata: {
|
|
114
|
+
receipt: legs.receiptKey, home: legs.homeKey, ratio: comparison.ratio, currency: homeCurrency,
|
|
115
|
+
impliedFx: comparison.impliedFx, spot: comparison.spot?.rate ?? null, ...(kind ? { spotKind: kind } : {}),
|
|
116
|
+
premiumPercent: comparison.premiumPercent,
|
|
117
|
+
receiptPrice: comparison.receipt.price, receiptObservedAt: comparison.receipt.observedAt,
|
|
118
|
+
homePrice: comparison.home.price, homeObservedAt: comparison.home.observedAt,
|
|
119
|
+
spotObservedAt: comparison.spot?.observedAt ?? null, template: ADR_PAIR_TEMPLATE_ID,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
};
|