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
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { apiClient } from "../../../api-client";
|
|
2
|
+
import type { HolderData, HolderRecord } from "../../../types/financials";
|
|
3
|
+
import type { TickerHoldings } from "../thirteenf/signals";
|
|
4
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
5
|
+
import { nonUsHolderCaveat } from "./report-header";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A US listing's 13F holders from the SEC 13F holder index, the list `fn 13F`
|
|
9
|
+
* pages through: every filer that reported the security for the latest
|
|
10
|
+
* quarter, largest first, 25 to a page. HDS shows them in the units of the
|
|
11
|
+
* source's own short list (each position at the latest price, the stake as a
|
|
12
|
+
* share of the class that list divides by), and keeps that short list for a
|
|
13
|
+
* listing abroad and whenever the index cannot be read.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** The most holder rows `fn HDS` and `holders` print. */
|
|
17
|
+
export const HOLDER_ROWS_MAX = 200;
|
|
18
|
+
|
|
19
|
+
/** One filer's position in the security, summed over the ticker's CUSIPs. */
|
|
20
|
+
export interface IndexedHolder {
|
|
21
|
+
cik: string;
|
|
22
|
+
name: string;
|
|
23
|
+
shares: number;
|
|
24
|
+
/** Shares at the prior quarter end: 0 for a new position, undefined when unknown. */
|
|
25
|
+
previousShares?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The index's holders loaded so far. */
|
|
29
|
+
export interface IndexedHolderList {
|
|
30
|
+
rows: IndexedHolder[];
|
|
31
|
+
/** The report period the positions are as of. */
|
|
32
|
+
period: string;
|
|
33
|
+
/** Every filer that holds the security at the period end. */
|
|
34
|
+
holderCount: number;
|
|
35
|
+
hasMore: boolean;
|
|
36
|
+
nextOffset: number;
|
|
37
|
+
/** A later page failed: the rows are the ones loaded before it, short of the limit asked. */
|
|
38
|
+
partial?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const usTicker = /^[A-Z0-9]{1,10}(\.[A-Z]{1,2})?$/;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The ticker to ask the index for, or null when the listing is not a US
|
|
45
|
+
* line: a venue abroad (typed `SAN:EPA` or given apart), another currency,
|
|
46
|
+
* or a home line whose list the service priced from the filings.
|
|
47
|
+
*/
|
|
48
|
+
export function indexHolderTicker(
|
|
49
|
+
symbol: string | null | undefined,
|
|
50
|
+
exchange = "",
|
|
51
|
+
data?: Pick<HolderData, "exchange" | "currency" | "valueBasis"> | null,
|
|
52
|
+
): string | null {
|
|
53
|
+
const [bare = "", typed = ""] = (symbol ?? "").trim().toUpperCase().split(":");
|
|
54
|
+
const ticker = bare.replace(/[/-]/g, ".");
|
|
55
|
+
if (!usTicker.test(ticker)) return null;
|
|
56
|
+
if (nonUsHolderCaveat(typed || exchange, null) != null) return null;
|
|
57
|
+
if (data && (data.valueBasis === "period_end_price" || nonUsHolderCaveat(data.exchange, data.currency ?? "USD") != null)) return null;
|
|
58
|
+
return ticker;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* One page of the index's holders. Rows that exited during the quarter, and
|
|
63
|
+
* option or principal positions, are not holders of the shares; the pages
|
|
64
|
+
* list the period's holders before its exits, so the list ends where the
|
|
65
|
+
* holder count does.
|
|
66
|
+
*/
|
|
67
|
+
export function indexedHolderPage(holdings: TickerHoldings): IndexedHolderList {
|
|
68
|
+
const byCik = new Map<string, IndexedHolder & { previousKnown: boolean }>();
|
|
69
|
+
for (const row of holdings.rows) {
|
|
70
|
+
const type = row.type.trim().toUpperCase();
|
|
71
|
+
if (row.action === "exit" || (type && type !== "SH")) continue;
|
|
72
|
+
if (row.shares == null || !(row.shares > 0)) continue;
|
|
73
|
+
const previous = typeof row.previousShares === "number" ? row.previousShares : null;
|
|
74
|
+
const current = byCik.get(row.cik);
|
|
75
|
+
if (!current) {
|
|
76
|
+
byCik.set(row.cik, {
|
|
77
|
+
cik: row.cik,
|
|
78
|
+
name: row.fund,
|
|
79
|
+
shares: row.shares,
|
|
80
|
+
previousShares: previous ?? undefined,
|
|
81
|
+
previousKnown: previous != null,
|
|
82
|
+
});
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Two CUSIPs under one ticker (a re-issued one) are one position.
|
|
86
|
+
current.shares += row.shares;
|
|
87
|
+
current.previousKnown &&= previous != null;
|
|
88
|
+
current.previousShares = current.previousKnown ? (current.previousShares ?? 0) + previous! : undefined;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
rows: [...byCik.values()].map(({ previousKnown: _known, ...row }) => row),
|
|
92
|
+
period: holdings.period,
|
|
93
|
+
holderCount: holdings.holderCount,
|
|
94
|
+
hasMore: holdings.hasMore && holdings.nextOffset < holdings.holderCount,
|
|
95
|
+
nextOffset: holdings.nextOffset,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Rows the service gives a page, as `fn 13F` asks for them. */
|
|
100
|
+
const INDEX_PAGE_ROWS = 25;
|
|
101
|
+
/**
|
|
102
|
+
* Pages one list reads at most: twice what the most rows take, for pages
|
|
103
|
+
* whose options and exits leave fewer holders, and never without end.
|
|
104
|
+
*/
|
|
105
|
+
const INDEX_PAGES_MAX = Math.ceil(HOLDER_ROWS_MAX / INDEX_PAGE_ROWS) * 2;
|
|
106
|
+
|
|
107
|
+
/** The client the pages come through; headless reports pass their own. */
|
|
108
|
+
export type IndexedHolderClient = Pick<typeof apiClient, "getCloudSec13F">;
|
|
109
|
+
|
|
110
|
+
/** One page of 25, as `fn 13F` asks for it, so the two share the service's copy. */
|
|
111
|
+
export async function loadIndexedHolderPage(
|
|
112
|
+
ticker: string,
|
|
113
|
+
offset: number,
|
|
114
|
+
signal?: AbortSignal,
|
|
115
|
+
client: IndexedHolderClient = apiClient,
|
|
116
|
+
): Promise<IndexedHolderList> {
|
|
117
|
+
signal?.throwIfAborted();
|
|
118
|
+
const holdings = await client.getCloudSec13F("ticker-holdings", { tickers: ticker, offset, limit: INDEX_PAGE_ROWS }, { signal }) as TickerHoldings;
|
|
119
|
+
signal?.throwIfAborted();
|
|
120
|
+
if (!Array.isArray(holdings?.rows) || typeof holdings.period !== "string") throw new Error(`13F holders of ${ticker} are unreadable`);
|
|
121
|
+
const page = indexedHolderPage(holdings);
|
|
122
|
+
// A page that does not move the offset on ends the list, or it would be asked for again and again.
|
|
123
|
+
return page.nextOffset > offset ? page : { ...page, hasMore: false };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Later pages after the first; a page of another period starts the list over. */
|
|
127
|
+
function appendIndexedHolders(current: IndexedHolderList, page: IndexedHolderList): IndexedHolderList {
|
|
128
|
+
if (current.period !== page.period) return page;
|
|
129
|
+
const seen = new Set(current.rows.map((row) => row.cik));
|
|
130
|
+
return { ...page, rows: [...current.rows, ...page.rows.filter((row) => !seen.has(row.cik))] };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The largest `limit` holders, paging as far as that takes, never more than
|
|
135
|
+
* `INDEX_PAGES_MAX` pages. A later page that fails keeps the holders already
|
|
136
|
+
* loaded, marked partial; only a first page that fails leaves the source's list.
|
|
137
|
+
*/
|
|
138
|
+
export async function loadIndexedHolders(
|
|
139
|
+
ticker: string,
|
|
140
|
+
limit: number,
|
|
141
|
+
signal?: AbortSignal,
|
|
142
|
+
client: IndexedHolderClient = apiClient,
|
|
143
|
+
): Promise<IndexedHolderList> {
|
|
144
|
+
let list = await loadIndexedHolderPage(ticker, 0, signal, client);
|
|
145
|
+
for (let pages = 1; list.hasMore && list.rows.length < limit && pages < INDEX_PAGES_MAX; pages += 1) {
|
|
146
|
+
const offset = list.nextOffset;
|
|
147
|
+
let page: IndexedHolderList;
|
|
148
|
+
try {
|
|
149
|
+
page = await loadIndexedHolderPage(ticker, offset, signal, client);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (signal?.aborted) throw error;
|
|
152
|
+
logFailure("holders.index", "Read a later page of the 13F holder index failed", null)(error);
|
|
153
|
+
return { ...list, partial: true };
|
|
154
|
+
}
|
|
155
|
+
list = appendIndexedHolders(list, page);
|
|
156
|
+
}
|
|
157
|
+
return list;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** What a list cut short by a failed page says, when it holds fewer rows than were asked for. */
|
|
161
|
+
export function indexedHoldersPartialNote(list: IndexedHolderList | null | undefined, limit: number): string | null {
|
|
162
|
+
if (!list?.partial || list.rows.length >= limit) return null;
|
|
163
|
+
return `13F holders past the largest ${list.rows.length} could not be read this time.`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** How the source's own rows value and divide a position, which the index's rows take on. */
|
|
167
|
+
export interface IndexedHolderUnits {
|
|
168
|
+
/** The price a position's shares are valued at. */
|
|
169
|
+
price?: number;
|
|
170
|
+
/**
|
|
171
|
+
* The share count a stake is a share of. The source divides by the class
|
|
172
|
+
* the line trades (PBR's receipts stand for the common shares alone), not
|
|
173
|
+
* by every share the company has.
|
|
174
|
+
*/
|
|
175
|
+
classShares?: number;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function median(values: number[]): number | undefined {
|
|
179
|
+
if (values.length === 0) return undefined;
|
|
180
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
181
|
+
const middle = Math.floor(sorted.length / 2);
|
|
182
|
+
return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1]! + sorted[middle]!) / 2;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The units of the source's list: its rows' price (shares times the latest
|
|
187
|
+
* price), else the quote's, and the count its stakes divide by. The stakes
|
|
188
|
+
* are rounded to four places, so the count is taken over all of them, where
|
|
189
|
+
* the largest weigh most.
|
|
190
|
+
*/
|
|
191
|
+
export function indexedHolderUnits(data: HolderData | null | undefined, quotePrice?: number | null): IndexedHolderUnits {
|
|
192
|
+
const rows = (data?.holders ?? []).filter((row) => row.ownerType === "institution" && row.shares != null && row.shares > 0);
|
|
193
|
+
const price = median(rows.flatMap((row) => (row.value != null && row.value > 0 ? [row.value / row.shares!] : [])))
|
|
194
|
+
?? (quotePrice != null && Number.isFinite(quotePrice) && quotePrice > 0 ? quotePrice : undefined);
|
|
195
|
+
const staked = rows.filter((row) => row.percentHeld != null && row.percentHeld > 0);
|
|
196
|
+
const held = staked.reduce((sum, row) => sum + row.percentHeld!, 0);
|
|
197
|
+
const classShares = held > 0 ? staked.reduce((sum, row) => sum + row.shares!, 0) / held : undefined;
|
|
198
|
+
return {
|
|
199
|
+
...(price != null ? { price } : {}),
|
|
200
|
+
...(classShares != null && Number.isFinite(classShares) ? { classShares } : {}),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** The source's rows of the period by their shares, where only one row has that many. */
|
|
205
|
+
function sourceRowsByShares(source: readonly HolderRecord[], period: string): Map<number, HolderRecord> {
|
|
206
|
+
const counts = new Map<number, number>();
|
|
207
|
+
for (const row of source) if (row.reportDate === period && row.shares != null) counts.set(row.shares, (counts.get(row.shares) ?? 0) + 1);
|
|
208
|
+
return new Map(source.flatMap((row) => row.reportDate === period && row.shares != null && counts.get(row.shares) === 1 ? [[row.shares, row]] : []));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The index's filers as holder rows. A filer whose position is exactly one of
|
|
213
|
+
* the source's rows keeps that row's value and stake, so the largest holders
|
|
214
|
+
* read as they did; the others are valued and divided in the same units.
|
|
215
|
+
*/
|
|
216
|
+
function indexedHolderRecords(
|
|
217
|
+
rows: readonly IndexedHolder[],
|
|
218
|
+
period: string,
|
|
219
|
+
units: IndexedHolderUnits,
|
|
220
|
+
source: readonly HolderRecord[] = [],
|
|
221
|
+
): HolderRecord[] {
|
|
222
|
+
const known = sourceRowsByShares(source, period);
|
|
223
|
+
return rows.map((row) => {
|
|
224
|
+
const change = row.previousShares == null ? undefined : row.shares - row.previousShares;
|
|
225
|
+
const same = known.get(row.shares);
|
|
226
|
+
const value = same?.value ?? (units.price != null ? Math.round(row.shares * units.price) : undefined);
|
|
227
|
+
const percentHeld = same?.percentHeld ?? (units.classShares != null ? row.shares / units.classShares : undefined);
|
|
228
|
+
return {
|
|
229
|
+
ownerType: "institution",
|
|
230
|
+
// The source's spelling of the same holder, not the filer's capitals.
|
|
231
|
+
name: same?.name ?? row.name,
|
|
232
|
+
cik: row.cik,
|
|
233
|
+
reportDate: period,
|
|
234
|
+
shares: row.shares,
|
|
235
|
+
...(value != null ? { value } : {}),
|
|
236
|
+
...(percentHeld != null ? { percentHeld } : {}),
|
|
237
|
+
...(change != null ? { changeShares: change } : {}),
|
|
238
|
+
// A fraction of the prior position, as every holder record carries it; a new one has none.
|
|
239
|
+
...(change != null && row.previousShares! > 0
|
|
240
|
+
? { changePercent: Math.round((change / row.previousShares!) * 1e6) / 1e6 }
|
|
241
|
+
: {}),
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* The holder list with the index's filers in place of the source's few: the
|
|
248
|
+
* listing's facts and units as the source gave them, the index's period and
|
|
249
|
+
* count.
|
|
250
|
+
*/
|
|
251
|
+
export function withIndexedHolders(
|
|
252
|
+
data: HolderData | null | undefined,
|
|
253
|
+
symbol: string,
|
|
254
|
+
list: IndexedHolderList,
|
|
255
|
+
units: IndexedHolderUnits,
|
|
256
|
+
): HolderData {
|
|
257
|
+
return {
|
|
258
|
+
...(data ?? { symbol, currency: "USD" }),
|
|
259
|
+
asOf: list.period,
|
|
260
|
+
holders: indexedHolderRecords(list.rows, list.period, units, data?.holders),
|
|
261
|
+
summary: { ...data?.summary, institutionsCount: list.holderCount },
|
|
262
|
+
...(units.price != null ? { valueBasis: "latest_price" as const } : {}),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import { Box, Text, TextAttributes, useUiCapabilities } from "../../../ui";
|
|
2
|
+
import { Box, Text, TextAttributes, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
|
|
3
3
|
import {
|
|
4
4
|
Badge,
|
|
5
5
|
DataTableView,
|
|
6
|
+
usePagedRows,
|
|
6
7
|
usePaneFooter,
|
|
7
8
|
usePaneTabs,
|
|
8
9
|
usePaneTicker,
|
|
10
|
+
useTableLoadMore,
|
|
9
11
|
type DataTableCell,
|
|
10
12
|
type DataTableKeyEvent,
|
|
13
|
+
type PageRequest,
|
|
11
14
|
} from "../../../components";
|
|
12
15
|
import { handleRefreshKey, loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
13
16
|
import { useAsyncResource } from "../../../react/async-resource";
|
|
@@ -22,8 +25,8 @@ import { THIRTEENF_TEMPLATE_ID } from "../thirteenf/model";
|
|
|
22
25
|
import { useInResearchTab } from "../ticker-detail/research-tab-keys";
|
|
23
26
|
import {
|
|
24
27
|
displayDate,
|
|
28
|
+
formatHolderChangePercent,
|
|
25
29
|
formatHolderOwnershipPercent,
|
|
26
|
-
formatMaybePercent,
|
|
27
30
|
formatMoneyCompact,
|
|
28
31
|
formatSignedCompact,
|
|
29
32
|
holderStakeMarketCap,
|
|
@@ -40,15 +43,23 @@ import {
|
|
|
40
43
|
sortRows,
|
|
41
44
|
VIEW_TABS,
|
|
42
45
|
} from "./table-model";
|
|
43
|
-
import { classSharesToday, loadHolderData } from "./client";
|
|
46
|
+
import { classSharesAsOf, classSharesToday, loadHolderData } from "./client";
|
|
44
47
|
import { HoldersTreemap } from "./treemap";
|
|
45
48
|
import { BeneficialOwnersView } from "./beneficial-view";
|
|
46
49
|
import { useIssuerListing } from "../shared/ticker-request";
|
|
47
50
|
import type { HolderColumn, HolderColumnId, HolderRow, SortPreference, ViewMode } from "./types";
|
|
48
51
|
import { loadHolder13FMatches, type Holder13FMatch } from "./thirteenf-match";
|
|
52
|
+
import { indexedHolderUnits, indexHolderTicker, loadIndexedHolderPage, withIndexedHolders } from "./index-holders";
|
|
49
53
|
import { useSampledValue, useTickerQuoteStream } from "../../../state/hooks/live-ticker-financials";
|
|
50
54
|
|
|
51
55
|
const HOLDER_MARKET_CAP_SAMPLE_MS = 5_000;
|
|
56
|
+
/** Rows past the end of the table that a scroll loads the next page within, as `useTableLoadMore` does. */
|
|
57
|
+
const LOAD_MORE_ROWS = 8;
|
|
58
|
+
|
|
59
|
+
/** Index rows have their CIK, so their 13F filing needs no name search. */
|
|
60
|
+
function cikMatches(rows: readonly HolderRow[]): Map<string, Holder13FMatch> {
|
|
61
|
+
return new Map(rows.flatMap((row) => row.cik ? [[row.id, { cik: row.cik, fundName: row.name, periodOfReport: row.reportDate }]] : []));
|
|
62
|
+
}
|
|
52
63
|
|
|
53
64
|
/** The width of a three-letter badge ("13F", "ADR"): the label and its padding. */
|
|
54
65
|
const BADGE_WIDTH = 5;
|
|
@@ -64,6 +75,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
64
75
|
const [fundMatching, setFundMatching] = useState(false);
|
|
65
76
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
66
77
|
const fundMatchAbortRef = useRef<AbortController | null>(null);
|
|
78
|
+
const tableScrollRef = useRef<ScrollBoxRenderable | null>(null);
|
|
67
79
|
|
|
68
80
|
const exchange = ticker?.metadata.exchange ?? "";
|
|
69
81
|
const issuerListing = useIssuerListing(ticker);
|
|
@@ -80,8 +92,33 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
80
92
|
keepPreviousData: true,
|
|
81
93
|
});
|
|
82
94
|
|
|
95
|
+
// A US line's 13F holders are every filer in the SEC holder index, paged
|
|
96
|
+
// as fn 13F pages them and asked beside the source's short list, which
|
|
97
|
+
// stands until the first page answers and whenever the index cannot be read.
|
|
98
|
+
const indexTicker = indexHolderTicker(symbol, exchange);
|
|
99
|
+
const loadIndexPage = useMemo(() => indexTicker
|
|
100
|
+
? ({ offset, signal }: PageRequest) => loadIndexedHolderPage(indexTicker, offset, signal)
|
|
101
|
+
: null, [indexTicker]);
|
|
102
|
+
const index = usePagedRows(loadIndexPage, { getId: (row) => row.cik });
|
|
103
|
+
// The source's list kept from the previous ticker must not price this one's filers: they wait for its own.
|
|
104
|
+
const base = data && indexHolderTicker(data.symbol) === indexTicker ? data : null;
|
|
105
|
+
const indexed = index.rows.length > 0 && (!!base || !loading) && indexHolderTicker(symbol, exchange, base) != null;
|
|
106
|
+
const indexPending = !!indexTicker && index.loading && index.rows.length === 0;
|
|
107
|
+
// Index rows take the source's price; the quote's only when the source gave none, sampled so ticks do not re-sort.
|
|
108
|
+
// The rows follow the units in use, so a quote that is not the price used leaves them as they are.
|
|
109
|
+
const quotePrice = useSampledValue(financials?.quote?.price, HOLDER_MARKET_CAP_SAMPLE_MS, symbol ?? "");
|
|
110
|
+
const { price: unitPrice, classShares: unitClassShares } = indexedHolderUnits(base, quotePrice);
|
|
111
|
+
const listData = useMemo(() => {
|
|
112
|
+
const first = index.pages[0];
|
|
113
|
+
if (!indexed || !first || !indexTicker) return data;
|
|
114
|
+
return withIndexedHolders(base, indexTicker, { ...first, rows: index.rows }, {
|
|
115
|
+
...(unitPrice != null ? { price: unitPrice } : {}),
|
|
116
|
+
...(unitClassShares != null ? { classShares: unitClassShares } : {}),
|
|
117
|
+
});
|
|
118
|
+
}, [base, data, index.pages, index.rows, indexTicker, indexed, unitClassShares, unitPrice]);
|
|
119
|
+
|
|
83
120
|
// The values' own currency: dollars from the 13F filings on a London line, not its pence.
|
|
84
|
-
const currency = holderValueCurrency(
|
|
121
|
+
const currency = holderValueCurrency(listData, ticker?.metadata.currency || "USD")!;
|
|
85
122
|
// A stake without a reported percentage is the holding's value over the
|
|
86
123
|
// market cap, when both are in one currency. The stream keeps the cap
|
|
87
124
|
// current, about once a second; the stakes follow it at most every few
|
|
@@ -91,10 +128,11 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
91
128
|
const marketCap = useSampledValue(liveMarketCap, HOLDER_MARKET_CAP_SAMPLE_MS, `${symbol ?? ""}:${currency}`);
|
|
92
129
|
// Today's share count, which a 13D/13G report's own base is checked against.
|
|
93
130
|
const sharesOutstanding = classSharesToday(financials);
|
|
94
|
-
const
|
|
131
|
+
const sharesOutstandingAsOf = classSharesAsOf(financials);
|
|
132
|
+
const rows = useMemo(() => buildRows(listData), [listData]);
|
|
95
133
|
const periodsDiffer = useMemo(() => holderPeriodsDiffer(rows), [rows]);
|
|
96
134
|
const sortedRows = useMemo(() => sortRows(rows, sortPreference, marketCap), [marketCap, rows, sortPreference]);
|
|
97
|
-
// Change columns only when the source reports a change; otherwise
|
|
135
|
+
// Change columns only when the source reports a change; otherwise every row would read as missing.
|
|
98
136
|
const showChange = useMemo(() => hasHolderChanges(rows), [rows]);
|
|
99
137
|
const columns = useMemo(() => buildColumns(width, showChange), [showChange, width]);
|
|
100
138
|
const selectedIdx = selectedId
|
|
@@ -114,8 +152,14 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
114
152
|
// restart 25 two-request 13F lookups.
|
|
115
153
|
useEffect(() => {
|
|
116
154
|
fundMatchAbortRef.current?.abort();
|
|
155
|
+
if (rows.length > 0 && rows.every((row) => row.cik)) {
|
|
156
|
+
setFundMatches(cikMatches(rows));
|
|
157
|
+
setFundMatching(false);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
117
160
|
setFundMatches(new Map());
|
|
118
|
-
|
|
161
|
+
// The source's rows are not matched while the index's may replace them.
|
|
162
|
+
if (rows.length === 0 || indexPending) {
|
|
119
163
|
setFundMatching(false);
|
|
120
164
|
return;
|
|
121
165
|
}
|
|
@@ -138,7 +182,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
138
182
|
fundMatchAbortRef.current = null;
|
|
139
183
|
}
|
|
140
184
|
};
|
|
141
|
-
}, [rows]);
|
|
185
|
+
}, [indexPending, rows]);
|
|
142
186
|
|
|
143
187
|
const selectedRow = activeIdx >= 0 ? sortedRows[activeIdx] ?? null : null;
|
|
144
188
|
const selectedFundMatch = selectedRow ? fundMatches.get(selectedRow.id) ?? null : null;
|
|
@@ -167,9 +211,12 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
167
211
|
setViewMode(nextViewMode);
|
|
168
212
|
}, [setViewMode]);
|
|
169
213
|
|
|
214
|
+
const reloadIndex = index.reload;
|
|
170
215
|
const refresh = useCallback(() => {
|
|
171
216
|
void reload();
|
|
172
|
-
|
|
217
|
+
reloadIndex();
|
|
218
|
+
}, [reload, reloadIndex]);
|
|
219
|
+
const loadMoreFromScroll = useTableLoadMore(tableScrollRef, indexed && index.hasMore, index.loadMore);
|
|
173
220
|
|
|
174
221
|
// Plain keys only: Cmd/Ctrl+Shift+R, S and O resize, share and pop out the pane.
|
|
175
222
|
const handleKeyDown = useCallback((event: DataTableKeyEvent) => {
|
|
@@ -261,7 +308,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
261
308
|
};
|
|
262
309
|
case "changePercent":
|
|
263
310
|
return {
|
|
264
|
-
text:
|
|
311
|
+
text: formatHolderChangePercent(row.changePercent),
|
|
265
312
|
color: row.changePercent != null ? priceColor(row.changePercent) : colors.textDim,
|
|
266
313
|
};
|
|
267
314
|
case "percentHeld":
|
|
@@ -282,8 +329,14 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
282
329
|
// One date only when every holder's row is of it; the PERIOD column dates each row.
|
|
283
330
|
...(periodsDiffer
|
|
284
331
|
? [{ id: "as-of", parts: [{ text: "latest period per holder", tone: "muted" as const }] }]
|
|
285
|
-
:
|
|
286
|
-
|
|
332
|
+
: listData?.asOf ? [{ id: "as-of", parts: [{ text: listData.asOf, tone: "value" as const }] }] : []),
|
|
333
|
+
// The index's first page replaces the source's list, so it is loading too; a failed one leaves that list.
|
|
334
|
+
...loadingErrorFooterInfo(loading || (indexPending && !!data), listData ? error : null),
|
|
335
|
+
...(index.loadingMore ? [{ id: "loading-more", parts: [{ text: "loading more", tone: "muted" as const }] }] : []),
|
|
336
|
+
// A later page that failed keeps the rows loaded; scrolling asks for it again.
|
|
337
|
+
...(indexed && index.moreError && !index.loadingMore
|
|
338
|
+
? [{ id: "more-error", parts: [{ text: "more holders could not be read", tone: "warning" as const }] }]
|
|
339
|
+
: []),
|
|
287
340
|
...(fundMatching ? [{ id: "fund-matching", parts: [{ text: "13F matching", tone: "muted" as const }] }] : []),
|
|
288
341
|
],
|
|
289
342
|
// The title-bar tabs (or the query bar inside Ticker Research) switch
|
|
@@ -293,7 +346,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
293
346
|
...(selectedFundMatch ? [{ id: "fund", key: "o", label: "pen 13F", onPress: () => openFundDetail(selectedRow) }] : []),
|
|
294
347
|
],
|
|
295
348
|
};
|
|
296
|
-
}, [data, error, fundMatching, loading, openFundDetail, periodsDiffer, selectedFundMatch, selectedRow, viewMode]);
|
|
349
|
+
}, [data, error, fundMatching, index.loadingMore, index.moreError, indexed, indexPending, listData, loading, openFundDetail, periodsDiffer, selectedFundMatch, selectedRow, viewMode]);
|
|
297
350
|
|
|
298
351
|
const selectView = useCallback((value: string) => setViewMode(value as ViewMode), [setViewMode]);
|
|
299
352
|
// As a research tab, h/l move between research tabs; `s` switches the view.
|
|
@@ -313,11 +366,19 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
313
366
|
// values" while the request is still in flight or the pane has no ticker.
|
|
314
367
|
const statusTitle = !symbol
|
|
315
368
|
? "No ticker selected."
|
|
316
|
-
: loading && !
|
|
369
|
+
: (loading || indexPending) && !listData
|
|
317
370
|
? "Loading holders..."
|
|
318
|
-
: !
|
|
371
|
+
: !listData && error ? error : sortedRows.length === 0 ? "No holders available" : null;
|
|
319
372
|
const chartHeight = Math.max(1, height - tabRows - (nativePaneChrome ? 1 : 0));
|
|
320
373
|
|
|
374
|
+
// A list shorter than the table cannot scroll to load more, so it pages on
|
|
375
|
+
// until it fills the table, as a scroll would; a failed page waits for one.
|
|
376
|
+
const { hasMore: indexHasMore, loading: indexLoading, loadingMore: indexLoadingMore, moreError: indexMoreError, loadMore: loadMoreIndex } = index;
|
|
377
|
+
useEffect(() => {
|
|
378
|
+
if (viewMode !== "table" || !indexed || !indexHasMore || indexLoading || indexLoadingMore || indexMoreError) return;
|
|
379
|
+
if (sortedRows.length < chartHeight + LOAD_MORE_ROWS) loadMoreIndex();
|
|
380
|
+
}, [chartHeight, indexHasMore, indexLoading, indexLoadingMore, indexMoreError, indexed, loadMoreIndex, sortedRows.length, viewMode]);
|
|
381
|
+
|
|
321
382
|
return (
|
|
322
383
|
<Box flexDirection="column" width={width} height={height}>
|
|
323
384
|
{nativePaneChrome ? tabStrip : tabStrip && <Box height={1} paddingX={1}>{tabStrip}</Box>}
|
|
@@ -333,6 +394,8 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
333
394
|
}}
|
|
334
395
|
onActivate={openFundDetail}
|
|
335
396
|
onRootKeyDown={handleKeyDown}
|
|
397
|
+
scrollRef={tableScrollRef}
|
|
398
|
+
onBodyScrollActivity={loadMoreFromScroll}
|
|
336
399
|
resetScrollKey={data?.symbol}
|
|
337
400
|
rootWidth={width}
|
|
338
401
|
columns={columns}
|
|
@@ -354,6 +417,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
354
417
|
holderRows={rows}
|
|
355
418
|
fundMatches={fundMatches}
|
|
356
419
|
sharesOutstanding={sharesOutstanding}
|
|
420
|
+
sharesOutstandingAsOf={sharesOutstandingAsOf}
|
|
357
421
|
onCycleView={toggleView}
|
|
358
422
|
onRefreshHolders={refresh}
|
|
359
423
|
/>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { HeadlessPaneColumn } from "../../../types/plugin";
|
|
2
2
|
import type { HolderData, ShareBasis } from "../../../types/financials";
|
|
3
|
-
import { formatCompact,
|
|
3
|
+
import { formatCompact, MISSING_VALUE } from "../../../utils/format";
|
|
4
4
|
import {
|
|
5
5
|
displayDate,
|
|
6
|
+
formatChangePercent,
|
|
6
7
|
formatMoneyCompact,
|
|
7
8
|
formatPercentHeld,
|
|
8
9
|
formatSignedCompact,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
nonUsHolderCaveat,
|
|
22
23
|
sharedReportDate,
|
|
23
24
|
} from "./report-header";
|
|
25
|
+
import { HOLDER_ROWS_MAX } from "./index-holders";
|
|
24
26
|
import { buildRows, DEFAULT_SORT, sortRows } from "./table-model";
|
|
25
27
|
import type { HolderColumnId, SortPreference } from "./types";
|
|
26
28
|
|
|
@@ -28,7 +30,8 @@ import type { HolderColumnId, SortPreference } from "./types";
|
|
|
28
30
|
* A holder as `holders` and `fn HDS` report it; the keys are the JSON
|
|
29
31
|
* contract. `value` is in `currency`, the values' own currency; the percents
|
|
30
32
|
* are in percent (0.59 is 0.59% of the shares outstanding, 13.15 a 13.15%
|
|
31
|
-
* change on the quarter
|
|
33
|
+
* change on the quarter, 108.6 a position that more than doubled), from the
|
|
34
|
+
* record's fractions. A figure the source did not give is null.
|
|
32
35
|
*/
|
|
33
36
|
export interface HolderReportRow {
|
|
34
37
|
name: string;
|
|
@@ -63,14 +66,14 @@ export const HOLDER_REPORT_COLUMNS: HeadlessPaneColumn[] = [
|
|
|
63
66
|
key: "value",
|
|
64
67
|
header: "Mkt value",
|
|
65
68
|
align: "right",
|
|
66
|
-
format: (value) => num(value) == null ?
|
|
69
|
+
format: (value) => num(value) == null ? MISSING_VALUE : formatCompact(num(value)!),
|
|
67
70
|
textFormat: (value, row) => formatMoneyCompact(num(value) ?? undefined, String(row.currency ?? "USD")),
|
|
68
71
|
},
|
|
69
72
|
{
|
|
70
73
|
key: "shares",
|
|
71
74
|
header: "Amount",
|
|
72
75
|
align: "right",
|
|
73
|
-
format: (value) => num(value) == null ?
|
|
76
|
+
format: (value) => num(value) == null ? MISSING_VALUE : formatCompact(num(value)!),
|
|
74
77
|
},
|
|
75
78
|
{
|
|
76
79
|
key: BASIS_COLUMN_KEY,
|
|
@@ -87,13 +90,13 @@ export const HOLDER_REPORT_COLUMNS: HeadlessPaneColumn[] = [
|
|
|
87
90
|
key: "changePercent",
|
|
88
91
|
header: "Chg%",
|
|
89
92
|
align: "right",
|
|
90
|
-
format: (value) =>
|
|
93
|
+
format: (value) => formatChangePercent(num(value)),
|
|
91
94
|
},
|
|
92
95
|
{
|
|
93
96
|
key: "percentHeld",
|
|
94
97
|
header: "Held",
|
|
95
98
|
align: "right",
|
|
96
|
-
format: (value) => num(value) == null ?
|
|
99
|
+
format: (value) => num(value) == null ? MISSING_VALUE : `${num(value)!.toFixed(2)}%`,
|
|
97
100
|
textFormat: (value) => formatPercentHeld(num(value)),
|
|
98
101
|
},
|
|
99
102
|
{
|
|
@@ -186,10 +189,13 @@ export function holderReportNotices({
|
|
|
186
189
|
reported,
|
|
187
190
|
total,
|
|
188
191
|
sort = DEFAULT_SORT,
|
|
192
|
+
indexed = false,
|
|
189
193
|
}: {
|
|
190
194
|
data: HolderData;
|
|
191
195
|
/** The symbol as asked for, which `fn 13F` takes. */
|
|
192
196
|
requested: string;
|
|
197
|
+
/** The rows are the SEC 13F holder index's, largest first, not the source's short list. */
|
|
198
|
+
indexed?: boolean;
|
|
193
199
|
shown: readonly HolderReportRow[];
|
|
194
200
|
/** Holders on the list before a limit. */
|
|
195
201
|
reported: number;
|
|
@@ -218,8 +224,14 @@ export function holderReportNotices({
|
|
|
218
224
|
`Mkt value = ${valueBasis}.`,
|
|
219
225
|
changeReported ? "" : `Change vs prior quarter: not reported by this source; see fn 13F ${requested}`,
|
|
220
226
|
].filter(Boolean).join(" ");
|
|
227
|
+
const cut = indexed
|
|
228
|
+
? indexedListCut(requested, shown.length, total, sort)
|
|
229
|
+
// The source names only its largest holders, so a higher limit shows no more of them.
|
|
230
|
+
: shown.length > 0 && shown.length === reported && total != null && total > reported
|
|
231
|
+
? `The source lists its ${reported} largest holders; fn 13F ${requested} lists all ${total.toLocaleString("en-US")}.`
|
|
232
|
+
: null;
|
|
221
233
|
return {
|
|
222
|
-
notices: [header, basis, positionsBasis, holderShareBasisNote(data, shown), unvaluedHoldersNote(shown, sort)]
|
|
234
|
+
notices: [header, basis, cut, positionsBasis, holderShareBasisNote(data, shown), unvaluedHoldersNote(shown, sort)]
|
|
223
235
|
.filter((line): line is string => !!line),
|
|
224
236
|
valueBasis,
|
|
225
237
|
positionsBasis,
|
|
@@ -227,6 +239,22 @@ export function holderReportNotices({
|
|
|
227
239
|
};
|
|
228
240
|
}
|
|
229
241
|
|
|
242
|
+
/**
|
|
243
|
+
* What a cut index list leaves out: the rows are its largest holders, so
|
|
244
|
+
* another order ranks only those, and `--limit` or `fn 13F` shows the rest.
|
|
245
|
+
*/
|
|
246
|
+
function indexedListCut(requested: string, shown: number, total: number | null, sort: SortPreference): string | null {
|
|
247
|
+
if (shown === 0 || total == null || shown >= total) return null;
|
|
248
|
+
const within = sort.columnId === "value" || sort.columnId === "shares" ? "" : `Sorted among the ${shown} largest. `;
|
|
249
|
+
const all = total.toLocaleString("en-US");
|
|
250
|
+
const more = total <= HOLDER_ROWS_MAX
|
|
251
|
+
? `--limit ${total} lists them all.`
|
|
252
|
+
: shown < HOLDER_ROWS_MAX
|
|
253
|
+
? `--limit lists up to ${HOLDER_ROWS_MAX}; fn 13F ${requested} lists all ${all}.`
|
|
254
|
+
: `fn 13F ${requested} lists all ${all}.`;
|
|
255
|
+
return within + more;
|
|
256
|
+
}
|
|
257
|
+
|
|
230
258
|
/**
|
|
231
259
|
* Holders the list gives no value for (a home line's position its filing
|
|
232
260
|
* could not tie to a priced security) sort after every valued one, and a
|
|
@@ -23,7 +23,8 @@ export function nextViewMode(current: ViewMode): ViewMode {
|
|
|
23
23
|
export function buildRows(data: HolderData | null): HolderRow[] {
|
|
24
24
|
return (data?.holders ?? []).map((holder, index) => ({
|
|
25
25
|
...holder,
|
|
26
|
-
|
|
26
|
+
// A filer's CIK names its row across pages; the source's rows have none.
|
|
27
|
+
id: holder.cik ? `cik:${holder.cik}` : `${holder.ownerType}:${holder.name}:${holder.reportDate ?? ""}:${index}`,
|
|
27
28
|
}));
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -2,6 +2,7 @@ import { listThirteenFForms, normalizeCik, searchThirteenFFunds } from "../thirt
|
|
|
2
2
|
import { isoDateToday, isoDateYearsAgo } from "../../../utils/calendar-date";
|
|
3
3
|
import { buildPeriodReports } from "../thirteenf/model";
|
|
4
4
|
import type { HolderRow } from "./types";
|
|
5
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
5
6
|
|
|
6
7
|
export interface Holder13FMatch {
|
|
7
8
|
cik: string;
|
|
@@ -100,8 +101,9 @@ export async function loadHolder13FMatches(
|
|
|
100
101
|
filedAsOfDate: form?.filedAsOfDate,
|
|
101
102
|
tableValueTotal: report?.complete && forms.length < 100 ? report.tableValueTotal : null,
|
|
102
103
|
});
|
|
103
|
-
} catch {
|
|
104
|
+
} catch (error) {
|
|
104
105
|
// Matching 13F metadata is an enhancement; holder rows should remain usable.
|
|
106
|
+
if (!signal.aborted) logFailure("holders.thirteenf-match", "Match holder fund filings failed")(error);
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
}
|
|
@@ -2,8 +2,8 @@ import { useMemo } from "react";
|
|
|
2
2
|
import { MetricTreemapSurface, type MetricTreemapItem } from "../../../components/metric-treemap";
|
|
3
3
|
import { formatCompact } from "../../../utils/format";
|
|
4
4
|
import {
|
|
5
|
+
formatHolderChangePercent,
|
|
5
6
|
formatHolderOwnershipLine,
|
|
6
|
-
formatMaybePercent,
|
|
7
7
|
formatMoneyCompact,
|
|
8
8
|
} from "./format";
|
|
9
9
|
import type { HolderRow } from "./types";
|
|
@@ -22,7 +22,7 @@ export function HoldersTreemap({ rows, width, height, selectedId, onSelect, onAc
|
|
|
22
22
|
}) {
|
|
23
23
|
const items = useMemo<Array<MetricTreemapItem<HolderRow>>>(() => rows.map((row) => {
|
|
24
24
|
const ownership = formatHolderOwnershipLine(row, marketCap);
|
|
25
|
-
const change = row.changePercent != null ?
|
|
25
|
+
const change = row.changePercent != null ? formatHolderChangePercent(row.changePercent) : "No change";
|
|
26
26
|
return {
|
|
27
27
|
id: row.id,
|
|
28
28
|
label: row.name,
|