gloomberb 0.17.5 → 0.18.0
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 +2 -0
- package/README.zh-CN.md +2 -0
- package/package.json +8 -1
- package/patches/electrobun@1.18.1.patch +74 -0
- package/src/account/auth-model.ts +3 -2
- package/src/account/device-signin-dialog.tsx +38 -13
- package/src/account/device-signin.ts +2 -1
- package/src/account/upgrade-dialog.tsx +6 -2
- package/src/api-client/askg.ts +5 -3
- package/src/api-client/bank-figures.ts +73 -0
- package/src/api-client/chat.ts +9 -0
- package/src/api-client/commodity-balances.ts +77 -0
- package/src/api-client/credit-boards.ts +21 -1
- package/src/api-client/crypto-markets.ts +88 -1
- package/src/api-client/data.ts +135 -6
- package/src/api-client/debt-maturities.ts +18 -0
- package/src/api-client/earnings.ts +10 -0
- package/src/api-client/equity-screener.ts +3 -0
- package/src/api-client/errors.ts +13 -0
- package/src/api-client/fund-facts.ts +72 -0
- package/src/api-client/futures-curve.ts +26 -3
- package/src/api-client/geo.ts +11 -1
- package/src/api-client/index.ts +30 -2
- package/src/api-client/insider-signals.ts +159 -0
- package/src/api-client/market-discovery.ts +1 -1
- package/src/api-client/normalizers.ts +2 -0
- package/src/api-client/paths.ts +28 -0
- package/src/api-client/request.ts +11 -3
- package/src/api-client/research-activity.ts +15 -8
- package/src/api-client/socket.ts +16 -3
- package/src/api-client/supply-chain-graph.ts +2 -2
- package/src/api-client/supply-chain.ts +8 -0
- package/src/api-client/tape.ts +12 -0
- package/src/api-client/types.ts +91 -3
- package/src/api-client/upgrade-experiment.ts +4 -3
- package/src/api-client/wall-experiments.ts +5 -3
- package/src/api-client/wall-summary.ts +3 -1
- package/src/api-client/web-experiments.ts +5 -2
- package/src/api-client/yield-curves.ts +17 -0
- package/src/app/command-bar-intro.ts +38 -0
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
- package/src/app/pane-runtime/plugin-bindings.ts +4 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
- package/src/app/pane-runtime/ticker-open-target.ts +31 -0
- package/src/app/runtime/broker-import.ts +23 -21
- package/src/app/runtime/desktop-deeplink.ts +3 -4
- package/src/app/runtime/plugin-bindings.ts +16 -9
- package/src/app/runtime/startup.ts +3 -4
- package/src/app/runtime/ticker-refresh.ts +13 -12
- package/src/app/runtime/update.ts +17 -3
- package/src/architecture/core-builtin-allowlist.json +2 -13
- package/src/architecture/silent-catch-allowlist.json +3 -0
- package/src/architecture/ui-literals-allowlist.json +186 -0
- package/src/architecture/ui-tokens-allowlist.json +40 -0
- package/src/ask-gloom/pane-context.ts +3 -1
- package/src/brokers/broker-portfolio-sync.ts +66 -0
- package/src/brokers/signed-in/catalog.ts +2 -1
- package/src/brokers/signed-in/client.ts +7 -2
- package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
- package/src/brokers/signed-in/sign-in.ts +22 -20
- package/src/brokers/sync-broker-instance.ts +77 -42
- package/src/capabilities/chart-series.ts +2 -0
- package/src/capabilities/registry.ts +1 -3
- package/src/cli/bank-section.ts +147 -0
- package/src/cli/base-converter.ts +5 -2
- package/src/cli/board-coins.ts +70 -0
- package/src/cli/commands/fred-series.ts +90 -0
- package/src/cli/commands/market.ts +434 -96
- package/src/cli/commands/news-search.ts +35 -2
- package/src/cli/commands/options-chain.ts +25 -9
- package/src/cli/commands/options-leaps.ts +3 -3
- package/src/cli/commands/overview.ts +130 -40
- package/src/cli/commands/plugins.ts +1 -0
- package/src/cli/commands/search.ts +87 -24
- package/src/cli/commands/system.ts +5 -2
- package/src/cli/commands/ticker.ts +361 -64
- package/src/cli/context.ts +15 -1
- package/src/cli/desktop-pane-shot.ts +11 -3
- package/src/cli/earnings-calendar.ts +2 -1
- package/src/cli/errors.ts +25 -2
- package/src/cli/export-source.ts +18 -3
- package/src/cli/fx-pair.ts +77 -0
- package/src/cli/glossary.ts +196 -14
- package/src/cli/history-rows.ts +84 -19
- package/src/cli/index-roots.ts +26 -0
- package/src/cli/index.ts +57 -20
- package/src/cli/known-gaps.ts +156 -22
- package/src/cli/listing-arg.ts +217 -150
- package/src/cli/listing-suggestion.ts +7 -23
- package/src/cli/name-entries.ts +76 -0
- package/src/cli/not-a-ticker.ts +15 -6
- package/src/cli/pane-functions/access-gate.ts +22 -0
- package/src/cli/pane-functions/capabilities.ts +62 -4
- package/src/cli/pane-functions/catalog.ts +144 -39
- package/src/cli/pane-functions/data.ts +6 -5
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +3 -3
- package/src/cli/pane-functions/freshness.ts +93 -17
- package/src/cli/pane-functions/function-help.ts +20 -17
- package/src/cli/pane-functions/headless.ts +187 -40
- package/src/cli/pane-functions/index.ts +126 -12
- package/src/cli/pane-functions/options.ts +17 -3
- package/src/cli/pane-functions/report-notices.ts +17 -3
- package/src/cli/pane-functions/resolver.ts +74 -18
- package/src/cli/pane-functions/screenshot.ts +126 -23
- package/src/cli/pane-functions/shot-options.ts +68 -0
- package/src/cli/perpetual-contract.ts +3 -1
- package/src/cli/report-tables.ts +21 -6
- package/src/cli/result.ts +2 -0
- package/src/cli/series-search.ts +6 -1
- package/src/cli/staged-tickers.ts +5 -0
- package/src/cli/statement-filings.ts +261 -0
- package/src/cli/symbol-args.ts +47 -8
- package/src/cli/symbol-list.ts +9 -2
- package/src/cli/symbol-rows.ts +269 -29
- package/src/cli/ticker-resolution.ts +148 -35
- package/src/cli/treasury-yields.ts +86 -0
- package/src/cli/types.ts +3 -0
- package/src/cli/uncovered-instrument.ts +20 -0
- package/src/cli/unknown-command.ts +18 -0
- package/src/components/chart/composite/axis-overlays.tsx +16 -9
- package/src/components/chart/composite/composite-chart.tsx +163 -23
- package/src/components/chart/composite/downsample.ts +19 -3
- package/src/components/chart/composite/format.ts +13 -0
- package/src/components/chart/composite/legend.tsx +161 -68
- package/src/components/chart/composite/panel-bitmap.ts +8 -2
- package/src/components/chart/composite/panel-labels.ts +38 -0
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +28 -10
- package/src/components/chart/composite/price-axis-labels.tsx +16 -3
- package/src/components/chart/composite/scene.ts +60 -2
- package/src/components/chart/composite/series-axis-tags.tsx +67 -0
- package/src/components/chart/composite/toolbar.tsx +12 -7
- package/src/components/chart/composite/tools.ts +2 -2
- package/src/components/chart/composite/types.ts +34 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
- package/src/components/chart/core/view-reset.ts +46 -0
- package/src/components/chart/curve/curve-surface.tsx +1 -1
- package/src/components/chart/static/series.ts +39 -0
- package/src/components/chart/static/trail-chart-surface.tsx +2 -1
- package/src/components/command-bar/commands/collection-list.ts +45 -15
- package/src/components/command-bar/commands/collection.ts +11 -4
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/registry.ts +2 -2
- package/src/components/command-bar/list/badge.ts +4 -3
- package/src/components/command-bar/list/model.ts +12 -0
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/panel/index.tsx +19 -8
- package/src/components/command-bar/panel/native-surface.ts +6 -4
- package/src/components/command-bar/panel/prompt-example.ts +22 -0
- package/src/components/command-bar/routes/root/command-items.ts +1 -1
- package/src/components/command-bar/routes/root/pick-prefetch.ts +38 -0
- package/src/components/command-bar/routes/root/provider-search.ts +9 -9
- package/src/components/command-bar/routes/root/results.ts +13 -0
- package/src/components/command-bar/routes/root/runtime.ts +3 -0
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +3 -1
- package/src/components/command-bar/routes/root/shortcut-items.ts +1 -1
- package/src/components/command-bar/routes/root/start-here.ts +90 -0
- package/src/components/command-bar/routes/ticker-search/actions.ts +34 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
- package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
- package/src/components/command-bar/surface/index.tsx +5 -0
- package/src/components/command-bar/theme-picker.tsx +3 -1
- package/src/components/command-bar/workflow/builtin.ts +5 -1
- package/src/components/command-bar/workflow/collection-actions.ts +23 -13
- package/src/components/command-bar/workflow/ops.ts +25 -3
- package/src/components/command-bar/workflow/pane-reuse.ts +3 -2
- package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
- package/src/components/command-bar/workflow/tickers.ts +7 -5
- package/src/components/feedback-dialog.tsx +1 -1
- package/src/components/form-modal/broker-step.tsx +7 -63
- package/src/components/form-modal/content.tsx +7 -2
- package/src/components/form-modal/field-row.tsx +6 -8
- package/src/components/form-modal/host.tsx +3 -3
- package/src/components/form-modal/model.ts +3 -0
- package/src/components/form-modal/routes.ts +17 -2
- package/src/components/index.ts +6 -6
- package/src/components/input-search-bar.tsx +43 -6
- package/src/components/layout/detached-pane-shell.tsx +0 -1
- package/src/components/layout/floating-pane.tsx +0 -1
- package/src/components/layout/header.tsx +8 -7
- package/src/components/layout/pane/content.tsx +11 -8
- package/src/components/layout/pane/footer/index.tsx +7 -4
- package/src/components/layout/pane/footer/model.ts +28 -2
- package/src/components/layout/pane/header.tsx +9 -19
- package/src/components/layout/pane/index.tsx +0 -1
- package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
- package/src/components/layout/pane/pane-tabs.tsx +4 -3
- package/src/components/layout/pane/sizing.ts +9 -0
- package/src/components/layout/pane/ticker-fate-gate.tsx +62 -0
- package/src/components/layout/shell/pane/capture.ts +44 -20
- package/src/components/layout/status-bar.tsx +3 -6
- package/src/components/markdown-text.tsx +17 -2
- package/src/components/market-board/index.tsx +19 -8
- package/src/components/metric-treemap/heat-surface.tsx +2 -7
- package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
- package/src/components/onboarding/onboarding-frame.tsx +24 -21
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
- package/src/components/onboarding/wizard-model.ts +1 -1
- package/src/components/onboarding/wizard-positions.ts +56 -19
- package/src/components/pane-settings-dialog/desktop.tsx +12 -50
- package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
- package/src/components/price-performance.tsx +18 -2
- package/src/components/reader/article-reader.tsx +11 -10
- package/src/components/reader/detail-reader.tsx +9 -5
- package/src/components/reader/reader-text.tsx +51 -24
- package/src/components/sign-in-code-panel.tsx +129 -75
- package/src/components/ticker/badge/format.ts +64 -15
- package/src/components/ticker/badge/index.tsx +33 -11
- package/src/components/ticker/badge/list.tsx +4 -3
- package/src/components/ticker/badge/text.tsx +2 -2
- package/src/components/ticker/list-table-view.tsx +8 -1
- package/src/components/ui/action-row.tsx +5 -2
- package/src/components/ui/audio-player.tsx +70 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/data-table/index.tsx +4 -2
- package/src/components/ui/data-table/opentui/index.tsx +61 -20
- package/src/components/ui/data-table/opentui/model.ts +104 -0
- package/src/components/ui/data-table/types.ts +11 -0
- package/src/components/ui/detail-scroll-body.tsx +1 -1
- package/src/components/ui/dialog-actions.tsx +1 -21
- package/src/components/ui/display.tsx +13 -5
- package/src/components/ui/external-link.tsx +4 -2
- package/src/components/ui/fields.tsx +12 -0
- package/src/components/ui/figure.tsx +5 -3
- package/src/components/ui/frame.tsx +40 -6
- package/src/components/ui/icon.tsx +4 -0
- package/src/components/ui/index.ts +4 -1
- package/src/components/ui/inline-quick-add.tsx +4 -1
- package/src/components/ui/list-view.tsx +8 -0
- package/src/components/ui/prose.tsx +97 -25
- package/src/components/ui/query-bar-keys.tsx +32 -6
- package/src/components/ui/query-bar.tsx +35 -4
- package/src/components/ui/quote.ts +42 -0
- package/src/components/ui/range-track.tsx +15 -2
- package/src/components/ui/reveal-in-scroll-box.ts +21 -3
- package/src/components/ui/select-button.tsx +38 -3
- package/src/components/ui/status.tsx +73 -4
- package/src/components/ui/table-layout.ts +20 -0
- package/src/components/ui/windowed-list.tsx +27 -0
- package/src/components/use-pinned-moment.ts +19 -0
- package/src/core/app-runtime.ts +2 -2
- package/src/core/state/app/instrument.ts +18 -1
- package/src/core/state/app/layout.ts +6 -0
- package/src/core/state/app/state.ts +14 -2
- package/src/data/cached-query.ts +1 -1
- package/src/data/config/chart-settings.ts +3 -1
- package/src/data/config/home.ts +4 -1
- package/src/data/config/store/node.ts +9 -4
- package/src/data/config/store/normalize.ts +9 -0
- package/src/data/json-storage.ts +6 -3
- package/src/data/json-ticker-repository.ts +3 -1
- package/src/data/plugin-cache.ts +5 -1
- package/src/data/sqlite/json.ts +3 -1
- package/src/data/ticker-repository.ts +5 -2
- package/src/docs/snapshot.json +248 -5
- package/src/feedback/diagnostics.ts +2 -6
- package/src/i18n/es.ts +86 -6
- package/src/i18n/index.ts +3 -9
- package/src/i18n/ja.ts +86 -6
- package/src/i18n/ko.ts +86 -6
- package/src/i18n/zh-cn.ts +86 -6
- package/src/i18n/zh-tw.ts +86 -6
- package/src/layout-marketplace/cloud.ts +16 -5
- package/src/layout-marketplace/gallery-desktop.tsx +8 -4
- package/src/layout-marketplace/gallery.tsx +4 -4
- package/src/layout-marketplace/linked-sync.ts +9 -3
- package/src/layout-marketplace/linked.ts +24 -3
- package/src/layout-marketplace/model.ts +39 -4
- package/src/market-data/bars-per-year.ts +43 -0
- package/src/market-data/bond-funds.ts +85 -0
- package/src/market-data/coordinator/auxiliary.ts +5 -2
- package/src/market-data/coordinator/index.ts +39 -5
- package/src/market-data/futures-contract.ts +155 -5
- package/src/market-data/hooks.tsx +77 -12
- package/src/market-data/market/bar-period.ts +107 -0
- package/src/market-data/market/format.ts +18 -14
- package/src/market-data/market/freshness.ts +29 -4
- package/src/market-data/market/index-level.ts +51 -0
- package/src/market-data/market/status.ts +152 -13
- package/src/market-data/model-dividend-yield.ts +117 -0
- package/src/market-data/quotes/freshness.ts +30 -1
- package/src/{plugins/builtin/portfolio-list → market-data/quotes}/live-valuation.ts +52 -6
- package/src/market-data/quotes/regular-session-valuation.ts +32 -1
- package/src/market-data/realized-volatility.ts +16 -7
- package/src/market-data/tax-equivalent.ts +344 -0
- package/src/news/aggregator.ts +4 -2
- package/src/notifications/notification-log.ts +5 -3
- package/src/plugins/auto-update-node.ts +1 -0
- package/src/plugins/builtin/account-management/footer.ts +1 -1
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +71 -19
- package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
- package/src/plugins/builtin/alerts/cli.ts +7 -18
- package/src/plugins/builtin/alerts/constants.ts +8 -0
- package/src/plugins/builtin/alerts/event-rows.ts +16 -0
- package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
- package/src/plugins/builtin/alerts/headless.ts +182 -0
- package/src/plugins/builtin/alerts/index.tsx +3 -0
- package/src/plugins/builtin/alerts/pane.tsx +1 -7
- package/src/plugins/builtin/alerts/storage.ts +17 -1
- package/src/plugins/builtin/analytics/index.tsx +6 -1
- package/src/plugins/builtin/analytics/metrics.ts +55 -13
- package/src/plugins/builtin/analytics/risk-headless.ts +26 -7
- package/src/plugins/builtin/analytics/risk-math.ts +83 -0
- package/src/plugins/builtin/analytics/risk-model.ts +171 -19
- package/src/plugins/builtin/analytics/risk-pane.tsx +17 -12
- package/src/plugins/builtin/analytics/sector-model.ts +14 -3
- package/src/plugins/builtin/awards/headless.ts +6 -5
- package/src/plugins/builtin/awards/index.tsx +1 -1
- package/src/plugins/builtin/backtest/client.ts +38 -8
- package/src/plugins/builtin/backtest/engine.ts +25 -13
- package/src/plugins/builtin/backtest/export.ts +27 -0
- package/src/plugins/builtin/backtest/format.ts +19 -3
- package/src/plugins/builtin/backtest/headless.ts +42 -28
- package/src/plugins/builtin/backtest/index.tsx +3 -0
- package/src/plugins/builtin/backtest/pane.tsx +39 -10
- package/src/plugins/builtin/backtest/report.ts +160 -0
- package/src/plugins/builtin/backtest/rules.ts +2 -0
- package/src/plugins/builtin/backtest/window.ts +112 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
- package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +0 -1
- package/src/plugins/builtin/catalysts/headless.ts +24 -13
- package/src/plugins/builtin/catalysts/index.tsx +4 -2
- package/src/plugins/builtin/catalysts/model.ts +18 -1
- package/src/plugins/builtin/catalysts/pane.tsx +2 -2
- package/src/plugins/builtin/cds/client.ts +28 -5
- package/src/plugins/builtin/cds/headless.ts +183 -31
- package/src/plugins/builtin/cds/index.tsx +1 -1
- package/src/plugins/builtin/cds/model.ts +229 -53
- package/src/plugins/builtin/cds/pane.tsx +82 -26
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
- package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +14 -10
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
- package/src/plugins/builtin/chart-composer/formula.ts +233 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
- package/src/plugins/builtin/chart-composer/headless.ts +117 -15
- package/src/plugins/builtin/chart-composer/index.tsx +73 -15
- package/src/plugins/builtin/chart-composer/pane.tsx +86 -23
- package/src/plugins/builtin/chart-composer/presets.ts +165 -8
- package/src/plugins/builtin/chart-composer/quick-add.tsx +9 -2
- package/src/plugins/builtin/chart-composer/series-catalog.ts +85 -16
- package/src/plugins/builtin/chart-composer/series-expression.ts +10 -8
- package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
- package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
- package/src/plugins/builtin/chart-composer/settings.ts +16 -4
- package/src/plugins/builtin/chart-composer/studies.ts +1 -1
- package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
- package/src/plugins/builtin/chat/content/channel-navigation.ts +17 -6
- package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
- package/src/plugins/builtin/chat/content/composer.tsx +22 -1
- package/src/plugins/builtin/chat/content/index.tsx +47 -10
- package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
- package/src/plugins/builtin/chat/content/mentions.ts +50 -21
- package/src/plugins/builtin/chat/content/scroll.ts +12 -5
- package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
- package/src/plugins/builtin/chat/content/snapshot.ts +40 -6
- package/src/plugins/builtin/chat/content/transcript.tsx +48 -37
- package/src/plugins/builtin/chat/content/whole-message-copy.ts +44 -2
- package/src/plugins/builtin/chat/controller/index.ts +68 -17
- package/src/plugins/builtin/chat/controller/mention-candidates.ts +104 -0
- package/src/plugins/builtin/chat/controller/realtime.ts +9 -0
- package/src/plugins/builtin/chat/controller/state.ts +10 -0
- package/src/plugins/builtin/chat/controller/view.ts +2 -0
- package/src/plugins/builtin/chat/conversation-recency.ts +73 -0
- package/src/plugins/builtin/chat/conversations.ts +12 -5
- package/src/plugins/builtin/chat/ghost-user.ts +11 -3
- package/src/plugins/builtin/chat/layout.ts +25 -5
- package/src/plugins/builtin/chat/message/desktop.tsx +15 -5
- package/src/plugins/builtin/chat/message/header.tsx +26 -4
- package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
- package/src/plugins/builtin/chat/message/render-state.ts +28 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
- package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
- package/src/plugins/builtin/chat/share/flow.tsx +9 -73
- package/src/plugins/builtin/chat/sidebar-rows.ts +18 -5
- package/src/plugins/builtin/chat/sidebar.tsx +6 -1
- package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
- package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
- package/src/plugins/builtin/cloud/askg/manifest.ts +4 -3
- package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
- package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
- package/src/plugins/builtin/cloud/plugin.tsx +2 -0
- package/src/plugins/builtin/cloud/team/module.tsx +5 -1
- package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
- package/src/plugins/builtin/cloud/team/views.ts +11 -4
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +16 -5
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
- package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
- package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
- package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
- package/src/plugins/builtin/commodities-energy/index.tsx +31 -9
- package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
- package/src/plugins/builtin/commodity-balances/client.ts +51 -193
- package/src/plugins/builtin/commodity-balances/headless.ts +10 -3
- package/src/plugins/builtin/commodity-balances/model.ts +5 -180
- package/src/plugins/builtin/commodity-balances/pane.tsx +3 -0
- package/src/plugins/builtin/company-attention/headless.ts +15 -7
- package/src/plugins/builtin/company-attention/index.tsx +1 -1
- package/src/plugins/builtin/company-attention/model.ts +49 -4
- package/src/plugins/builtin/company-attention/pane.tsx +11 -9
- package/src/plugins/builtin/company-kpis/headless.ts +4 -3
- package/src/plugins/builtin/company-kpis/index.tsx +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
- package/src/plugins/builtin/congress-trades/headless.ts +23 -2
- package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
- package/src/plugins/builtin/cot/headless.ts +5 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
- package/src/plugins/builtin/credit-boards/client.ts +9 -2
- package/src/plugins/builtin/credit-boards/headless.ts +93 -27
- package/src/plugins/builtin/credit-boards/index.tsx +15 -4
- package/src/plugins/builtin/credit-boards/model.ts +105 -6
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
- package/src/plugins/builtin/credit-documents/index.tsx +3 -0
- package/src/plugins/builtin/credit-documents/model.ts +3 -10
- package/src/plugins/builtin/crypto-board/client.ts +152 -2
- package/src/plugins/builtin/crypto-board/headless.ts +138 -19
- package/src/plugins/builtin/crypto-board/index.tsx +5 -3
- package/src/plugins/builtin/crypto-board/model.ts +210 -12
- package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
- package/src/plugins/builtin/crypto-board/series.ts +52 -1
- package/src/plugins/builtin/crypto-board/supply.ts +123 -0
- package/src/plugins/builtin/custom-view/index.tsx +1 -1
- package/src/plugins/builtin/custom-view/loader.ts +57 -7
- package/src/plugins/builtin/custom-view/sources.ts +146 -0
- package/src/plugins/builtin/custom-view/view-spec.ts +37 -1
- package/src/plugins/builtin/debt-maturities/client.ts +54 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/model.ts +58 -13
- package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
- package/src/plugins/builtin/dividend-yield/client.ts +42 -36
- package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
- package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
- package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
- package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
- package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
- package/src/plugins/builtin/dividend-yield/types.ts +6 -1
- package/src/plugins/builtin/dividend-yield/view.ts +1 -1
- package/src/plugins/builtin/docs/blocks.tsx +54 -8
- package/src/plugins/builtin/docs/pane.tsx +8 -13
- package/src/plugins/builtin/earnings/board-model.ts +33 -3
- package/src/plugins/builtin/earnings/board-table.ts +59 -14
- package/src/plugins/builtin/earnings/board.tsx +36 -3
- package/src/plugins/builtin/earnings/headless.ts +27 -7
- package/src/plugins/builtin/earnings/history-model.ts +9 -1
- package/src/plugins/builtin/earnings/history-table.ts +16 -5
- package/src/plugins/builtin/earnings/history.tsx +40 -10
- package/src/plugins/builtin/earnings/index.tsx +3 -1
- package/src/plugins/builtin/earnings/no-earnings.ts +52 -0
- package/src/plugins/builtin/earnings-calls/data.ts +51 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
- package/src/plugins/builtin/earnings-calls/model.ts +97 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
- package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
- package/src/plugins/builtin/econ/calendar-model.ts +22 -0
- package/src/plugins/builtin/econ/calendar-source.ts +35 -0
- package/src/plugins/builtin/econ/index.tsx +40 -8
- package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +11 -1
- package/src/plugins/builtin/econ-statistics/headless.ts +31 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +5 -3
- package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
- package/src/plugins/builtin/econ-statistics/view.ts +23 -0
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +46 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
- package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
- package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/editor.tsx +3 -3
- package/src/plugins/builtin/fear-greed/index.tsx +9 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures/index.tsx +2 -2
- package/src/plugins/builtin/futures/model.ts +39 -25
- package/src/plugins/builtin/futures/series.ts +38 -1
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
- package/src/plugins/builtin/futures-curve/client.ts +4 -4
- package/src/plugins/builtin/futures-curve/headless.ts +24 -4
- package/src/plugins/builtin/futures-curve/index.tsx +2 -2
- package/src/plugins/builtin/futures-curve/model.ts +50 -9
- package/src/plugins/builtin/futures-curve/pane.tsx +14 -10
- package/src/plugins/builtin/help/index.tsx +55 -8
- package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
- package/src/plugins/builtin/holders/headless.ts +12 -0
- package/src/plugins/builtin/insider/headless.ts +345 -5
- package/src/plugins/builtin/insider/index.tsx +304 -36
- package/src/plugins/builtin/insider/insiders.tsx +224 -0
- package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
- package/src/plugins/builtin/insider/signals-client.ts +193 -0
- package/src/plugins/builtin/insider/signals-model.ts +718 -0
- package/src/plugins/builtin/insider/signals.tsx +376 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
- package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
- package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
- package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
- package/src/plugins/builtin/iv-history/client.ts +41 -2
- package/src/plugins/builtin/iv-history/headless.ts +26 -16
- package/src/plugins/builtin/iv-history/screen-pane.tsx +25 -7
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jodi/client.ts +42 -205
- package/src/plugins/builtin/jodi/headless.ts +15 -4
- package/src/plugins/builtin/jodi/model.ts +18 -43
- package/src/plugins/builtin/jodi/pane.tsx +5 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
- package/src/plugins/builtin/market-movers/client.ts +32 -6
- package/src/plugins/builtin/market-movers/headless.ts +7 -2
- package/src/plugins/builtin/market-movers/model.ts +64 -3
- package/src/plugins/builtin/market-movers/screener.ts +20 -9
- package/src/plugins/builtin/market-valuation/detail.tsx +7 -2
- package/src/plugins/builtin/market-valuation/headless.ts +17 -4
- package/src/plugins/builtin/market-valuation/pane.tsx +8 -4
- package/src/plugins/builtin/market-valuation/view.ts +10 -0
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
- package/src/plugins/builtin/mna/distress/headless.ts +2 -1
- package/src/plugins/builtin/mna/headless.ts +14 -2
- package/src/plugins/builtin/mna/index.tsx +1 -0
- package/src/plugins/builtin/news/headless.ts +4 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
- package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
- package/src/plugins/builtin/notes/cli.ts +8 -4
- package/src/plugins/builtin/notes/files.ts +66 -20
- package/src/plugins/builtin/notes/migration.ts +18 -6
- package/src/plugins/builtin/notes/owner.tsx +3 -2
- package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/client.ts +10 -0
- package/src/plugins/builtin/options-positioning/headless.ts +88 -13
- package/src/plugins/builtin/options-positioning/index.tsx +2 -2
- package/src/plugins/builtin/options-positioning/model.ts +33 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +38 -16
- package/src/plugins/builtin/options-scenario/charts.tsx +13 -4
- package/src/plugins/builtin/options-scenario/client.ts +114 -17
- package/src/plugins/builtin/options-scenario/collar.ts +141 -0
- package/src/plugins/builtin/options-scenario/csp.ts +1 -1
- package/src/plugins/builtin/options-scenario/freshness.ts +27 -0
- package/src/plugins/builtin/options-scenario/headless.ts +30 -12
- package/src/plugins/builtin/options-scenario/index.tsx +1 -1
- package/src/plugins/builtin/options-scenario/model.ts +55 -5
- package/src/plugins/builtin/options-scenario/pane.tsx +24 -5
- package/src/plugins/builtin/pe-band/index.tsx +1 -1
- package/src/plugins/builtin/pe-band/model.ts +1 -15
- package/src/plugins/builtin/perps/headless.ts +30 -13
- package/src/plugins/builtin/perps/model.ts +45 -3
- package/src/plugins/builtin/perps/pane.tsx +7 -7
- package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +144 -63
- package/src/plugins/builtin/portfolio-list/cli/render.ts +373 -48
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +23 -9
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +25 -35
- package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +161 -32
- package/src/plugins/builtin/portfolio-list/income.ts +296 -0
- package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
- package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +63 -14
- package/src/plugins/builtin/portfolio-list/pane/remove-ticker.ts +1 -1
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +38 -8
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +12 -4
- package/src/plugins/builtin/portfolio-list/settings.ts +22 -0
- package/src/plugins/builtin/portfolio-list/since-last-seen.ts +197 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +32 -4
- package/src/plugins/builtin/portfolio-list/table.tsx +39 -7
- package/src/plugins/builtin/power/prices-headless.ts +2 -1
- package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
- package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
- package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +6 -4
- package/src/plugins/builtin/realized-vol/model.ts +5 -1
- package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
- package/src/plugins/builtin/realized-vol/settings.ts +1 -1
- package/src/plugins/builtin/research/analyst-headless.ts +4 -0
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +16 -5
- package/src/plugins/builtin/research/event-model.ts +63 -51
- package/src/plugins/builtin/research/headless-schema.ts +1 -0
- package/src/plugins/builtin/research/headless.ts +4 -1
- package/src/plugins/builtin/research/index.tsx +3 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
- package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +28 -9
- package/src/plugins/builtin/reverse-dcf/index.tsx +5 -2
- package/src/plugins/builtin/reverse-dcf/model.ts +87 -6
- package/src/plugins/builtin/reverse-dcf/pane.tsx +30 -7
- package/src/plugins/builtin/risk-factors/headless.ts +7 -0
- package/src/plugins/builtin/risk-factors/index.tsx +1 -0
- package/src/plugins/builtin/scanner/feed.ts +5 -3
- package/src/plugins/builtin/scanner/headless.ts +9 -57
- package/src/plugins/builtin/scanner/index.ts +1 -2
- package/src/plugins/builtin/sec/forms.ts +2 -6
- package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
- package/src/plugins/builtin/sec/fund-facts.ts +328 -0
- package/src/plugins/builtin/sec/headless.ts +140 -44
- package/src/plugins/builtin/sec/index.tsx +95 -30
- package/src/plugins/builtin/sec/model.ts +2 -44
- package/src/plugins/builtin/shared/earnings-report.ts +48 -1
- package/src/plugins/builtin/shared/headless-options.ts +10 -0
- package/src/plugins/builtin/shared/history-span.ts +55 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
- package/src/plugins/builtin/shared/move-rank.ts +108 -0
- package/src/plugins/builtin/shared/report-freshness.ts +45 -20
- package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
- package/src/plugins/builtin/shared/series-detail-chart.tsx +5 -2
- package/src/plugins/builtin/shared/series-list-detail.tsx +7 -3
- package/src/plugins/builtin/shared/ticker-surface.ts +16 -2
- package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +13 -5
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
- package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
- package/src/plugins/builtin/short-interest/headless.ts +3 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
- package/src/plugins/builtin/social-mentions/client.ts +8 -1
- package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
- package/src/plugins/builtin/supply-chain/client.ts +12 -3
- package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
- package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
- package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
- package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
- package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
- package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
- package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
- package/src/plugins/builtin/supply-chain/headless.ts +69 -27
- package/src/plugins/builtin/supply-chain/index.tsx +1 -1
- package/src/plugins/builtin/supply-chain/model.ts +76 -15
- package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
- package/src/plugins/builtin/themes/headless.ts +15 -2
- package/src/plugins/builtin/themes/model.ts +2 -5
- package/src/plugins/builtin/thirteenf/api.ts +50 -2
- package/src/plugins/builtin/thirteenf/data.ts +250 -11
- package/src/plugins/builtin/thirteenf/headless.ts +311 -28
- package/src/plugins/builtin/thirteenf/index.tsx +4 -1
- package/src/plugins/builtin/thirteenf/model.ts +244 -19
- package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
- package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
- package/src/plugins/builtin/thirteenf/types.ts +49 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +106 -24
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +108 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +26 -8
- package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +4 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +109 -23
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
- package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +37 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
- package/src/plugins/builtin/time-sales/client.ts +7 -4
- package/src/plugins/builtin/time-sales/headless.ts +71 -22
- package/src/plugins/builtin/time-sales/model.ts +12 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -7
- package/src/plugins/builtin/time-sales/window.ts +128 -0
- package/src/plugins/builtin/trace-bonds/client.ts +351 -33
- package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
- package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
- package/src/plugins/builtin/trace-bonds/model.ts +27 -25
- package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
- package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
- package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
- package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
- package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
- package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
- package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
- package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
- package/src/plugins/builtin/vol-surface/headless.ts +3 -2
- package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
- package/src/plugins/builtin/vol-surface/stored.ts +4 -7
- package/src/plugins/builtin/volatility/chart-model.ts +16 -15
- package/src/plugins/builtin/volatility/charts.tsx +5 -5
- package/src/plugins/builtin/volatility/client.ts +73 -2
- package/src/plugins/builtin/volatility/evidence.ts +13 -14
- package/src/plugins/builtin/volatility/headless.ts +13 -7
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/volatility/model.ts +104 -38
- package/src/plugins/builtin/volatility/pane.tsx +42 -24
- package/src/plugins/builtin/volatility/series.ts +22 -13
- package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +25 -8
- package/src/plugins/builtin/world-venue-map/index.ts +16 -2
- package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
- package/src/plugins/builtin/yield-curve/curves.ts +29 -5
- package/src/plugins/builtin/yield-curve/headless.ts +41 -8
- package/src/plugins/builtin/yield-curve/history.ts +5 -5
- package/src/plugins/builtin/yield-curve/index.tsx +30 -13
- package/src/plugins/compat.ts +3 -1
- package/src/plugins/dependencies.ts +8 -2
- package/src/plugins/host-link.ts +12 -5
- package/src/plugins/installer.ts +16 -7
- package/src/plugins/loader.ts +9 -2
- package/src/plugins/marketplace/activation.ts +10 -4
- package/src/plugins/registry/host-actions.ts +3 -0
- package/src/plugins/registry/index.ts +3 -1
- package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +82 -15
- package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +143 -55
- package/src/portfolio/futures-positions.ts +213 -0
- package/src/portfolio/futures-terms.ts +75 -0
- package/src/portfolio/manual-lots.ts +78 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/mutations.ts +59 -15
- package/src/portfolio/position-metrics.ts +44 -10
- package/src/portfolio/valuation-basis.ts +34 -24
- package/src/public/__snapshots__/public-api.test.ts.snap +6 -0
- package/src/public/time-series.ts +2 -1
- package/src/remote/confirm-change.tsx +2 -1
- package/src/remote/controller.ts +27 -7
- package/src/remote/schema.ts +25 -9
- package/src/remote/server.ts +1 -1
- package/src/remote/watchlist.ts +9 -1
- package/src/renderers/cloudflare/http-proxy.ts +21 -13
- package/src/renderers/dom/data-table/row.tsx +1 -1
- package/src/renderers/dom/desktop/audio-player.tsx +312 -0
- package/src/renderers/dom/desktop/control-styles.ts +17 -82
- package/src/renderers/dom/desktop/controls.tsx +39 -63
- package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
- package/src/renderers/dom/desktop/icons.tsx +8 -0
- package/src/renderers/dom/desktop/list-view.tsx +6 -6
- package/src/renderers/dom/desktop/popover.tsx +0 -3
- package/src/renderers/dom/desktop/query-bar.tsx +7 -5
- package/src/renderers/dom/desktop/select-field.tsx +9 -8
- package/src/renderers/dom/desktop/stack-header.ts +3 -0
- package/src/renderers/dom/dom-ui-host.tsx +5 -2
- package/src/renderers/dom/host/chart-surface.tsx +3 -3
- package/src/renderers/dom/host/size-observer.ts +33 -4
- package/src/renderers/dom/host/surface-3d.tsx +3 -2
- package/src/renderers/dom/host/surface-fit.ts +4 -1
- package/src/renderers/dom/host/tabs.tsx +22 -132
- package/src/renderers/dom/styles.css +358 -160
- package/src/renderers/dom/windowed-list.tsx +201 -0
- package/src/renderers/dom/windowed-rows.ts +65 -0
- package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +2 -9
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/http-stream.ts +21 -6
- package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
- package/src/renderers/electrobun/bun/desktop/update.ts +21 -6
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
- package/src/renderers/electrobun/shared/protocol.ts +4 -2
- package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
- package/src/renderers/electrobun/view/http-fetch.ts +12 -1
- package/src/series/capability.ts +1 -0
- package/src/series/files.ts +9 -3
- package/src/series/registry.ts +40 -14
- package/src/series/resolve.ts +121 -18
- package/src/series/standalone.ts +3 -2
- package/src/series/types.ts +55 -1
- package/src/series/validate.ts +39 -0
- package/src/shares/api.ts +26 -7
- package/src/shares/bug-report-dialog.tsx +2 -2
- package/src/shares/bug-report-flow.tsx +4 -7
- package/src/shares/capture-flow.ts +5 -4
- package/src/shares/capture-preview.tsx +2 -2
- package/src/shares/chat.ts +7 -27
- package/src/shares/flow.tsx +86 -40
- package/src/shares/location.ts +1 -3
- package/src/shares/pane-image.ts +11 -9
- package/src/shares/pane.ts +5 -2
- package/src/shares/payload.ts +1 -1
- package/src/shares/personal-pane.ts +3 -3
- package/src/shares/portable-layout.ts +9 -2
- package/src/shares/ready.ts +42 -0
- package/src/shares/test-harness.ts +62 -0
- package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
- package/src/sources/gloomberb-cloud/index.ts +64 -12
- package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
- package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
- package/src/sources/history-omitted.ts +34 -0
- package/src/sources/history-result.ts +3 -0
- package/src/sources/history-retention.ts +1 -1
- package/src/sources/listing-symbols.ts +8 -4
- package/src/sources/provider-errors.ts +43 -1
- package/src/sources/provider-router/batches.ts +3 -2
- package/src/sources/provider-router/cache.ts +2 -1
- package/src/sources/provider-router/cached-routes.ts +9 -3
- package/src/sources/provider-router/history.ts +9 -8
- package/src/sources/provider-router/index.ts +18 -3
- package/src/sources/provider-router/primary.ts +5 -4
- package/src/sources/provider-router/quote-route.ts +3 -1
- package/src/sources/provider-router/routing.ts +2 -1
- package/src/sources/provider-router/search.ts +47 -13
- package/src/sources/provider-router/streaming.ts +7 -4
- package/src/sources/sec-edgar.ts +1 -3
- package/src/state/app/context/index.tsx +9 -0
- package/src/state/app/tab-cursor.ts +222 -0
- package/src/state/hooks/quote-streaming.ts +3 -2
- package/src/state/hooks/session-snapshot.ts +3 -2
- package/src/state/persist-scheduler.ts +12 -4
- package/src/sync/controller.ts +22 -1
- package/src/sync/core-contributors.ts +264 -74
- package/src/team/collections-sync.ts +14 -4
- package/src/team/collections.ts +40 -11
- package/src/team/store.ts +5 -4
- package/src/telemetry/attention-counts.ts +8 -2
- package/src/telemetry/crash-reports-dom.ts +3 -0
- package/src/telemetry/crash-reports-node.ts +7 -4
- package/src/telemetry/crash-reports.ts +11 -11
- package/src/telemetry/usage-counts.ts +16 -12
- package/src/test-support/config-store.ts +31 -0
- package/src/test-support/moved-symbols.ts +64 -0
- package/src/theme/colors.ts +32 -0
- package/src/theme/font-scale.ts +2 -0
- package/src/theme/ui-tokens.ts +71 -0
- package/src/tickers/batched-lookups.ts +186 -0
- package/src/tickers/company-name-listing.ts +97 -0
- package/src/tickers/company-name.ts +13 -0
- package/src/tickers/instrument-coverage.ts +112 -0
- package/src/tickers/listing-fate.ts +282 -0
- package/src/tickers/listing-venues.ts +24 -5
- package/src/tickers/open-target.ts +13 -5
- package/src/tickers/search/index.ts +156 -37
- package/src/tickers/search/ranking.ts +68 -3
- package/src/tickers/search/types.ts +3 -0
- package/src/tickers/search/upsert.ts +22 -7
- package/src/tickers/terminal-codes.ts +79 -0
- package/src/tickers/ticker-changes.ts +100 -12
- package/src/tickers/us-listing.ts +2 -1
- package/src/time-series/bar-spacing.ts +19 -0
- package/src/time-series/chart-data.ts +116 -21
- package/src/time-series/field-catalog.ts +5 -2
- package/src/time-series/forward-valuation.ts +10 -7
- package/src/time-series/fundamentals.ts +103 -17
- package/src/time-series/hooks.ts +2 -0
- package/src/time-series/ice-credit.ts +17 -2
- package/src/time-series/live-bars.ts +24 -9
- package/src/time-series/live-quotes.ts +2 -3
- package/src/time-series/parsed-history-cache.ts +2 -0
- package/src/time-series/price-comparison.ts +6 -1
- package/src/time-series/price-units.ts +69 -0
- package/src/time-series/resolve.ts +114 -14
- package/src/time-series/session-bar.ts +138 -0
- package/src/time-series/spec.ts +14 -4
- package/src/time-series/studies.ts +214 -15
- package/src/time-series/transforms.ts +2 -0
- package/src/time-series/types.ts +33 -1
- package/src/time-series/use-chart-resolution.ts +2 -1
- package/src/time-series/valuation-price.ts +13 -0
- package/src/types/config.ts +17 -1
- package/src/types/data-provider.ts +20 -0
- package/src/types/financials.ts +2 -0
- package/src/types/headless.ts +169 -1
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +39 -9
- package/src/types/price-history.ts +5 -0
- package/src/types/ticker-changes.ts +19 -0
- package/src/types/ticker.ts +10 -2
- package/src/ui/context-menu.tsx +2 -0
- package/src/ui/host.tsx +45 -4
- package/src/ui/measured-cells.ts +13 -7
- package/src/ui/qr.ts +7 -5
- package/src/updater/index.ts +8 -6
- package/src/utils/asset-category.ts +20 -0
- package/src/utils/calendar-date.ts +86 -27
- package/src/utils/currency-units.ts +17 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +83 -3
- package/src/utils/dividend-cash.ts +48 -0
- package/src/utils/dom-screenshot-rasters.ts +3 -1
- package/src/utils/dom-screenshot.ts +14 -10
- package/src/utils/exchange-rate-snapshot.ts +9 -4
- package/src/utils/external-url.ts +1 -0
- package/src/utils/fiscal-period.ts +47 -0
- package/src/utils/format.ts +5 -2
- package/src/utils/forward-dividend.ts +160 -11
- package/src/utils/fundamentals.ts +7 -2
- package/src/utils/futures-generic.ts +34 -8
- package/src/utils/http-proxy-response.ts +67 -9
- package/src/utils/local-utc-offset.ts +2 -0
- package/src/utils/log-failure.ts +31 -0
- package/src/utils/option-expiry.ts +12 -12
- package/src/utils/plugin-proxy-hosts.json +1 -5
- package/src/utils/price-history-integrity.ts +56 -0
- package/src/utils/price-history.ts +13 -1
- package/src/utils/sec-filings.ts +245 -0
- package/src/utils/selection-clipboard.ts +5 -2
- package/src/utils/throttled-fetch.ts +1 -0
- package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
- package/src/utils/typo-distance.ts +22 -0
- package/src/utils/url.ts +1 -0
- package/src/utils/utc-time.ts +11 -0
- package/src/plugins/builtin/chat/share/targets.ts +0 -27
- package/src/plugins/builtin/shared/zip-text.ts +0 -46
- package/src/renderers/dom/host/top-surface.ts +0 -119
- package/src/shares/dialog.tsx +0 -221
- package/src/shares/live.ts +0 -19
|
@@ -19,10 +19,10 @@ import { isDetailBackNavigationKey } from "../../../utils/back-navigation";
|
|
|
19
19
|
import { isPlainKey } from "../../../utils/keyboard";
|
|
20
20
|
import { isPlainArrowUp, stopSearchFocusNavigation } from "../../../utils/search-focus-navigation";
|
|
21
21
|
import { nextHeaderSort } from "../../../utils/sort-values";
|
|
22
|
-
import { usePluginPaneState, usePluginTickerActions } from "../../runtime";
|
|
22
|
+
import { useAssetData, usePluginPaneState, usePluginTickerActions } from "../../runtime";
|
|
23
23
|
import { useMineTickers } from "../shared/mine-tickers";
|
|
24
24
|
import { usePaneStatusFooter, usePaneStatusLinkFooter } from "../../../components/layout/pane/status-footer";
|
|
25
|
-
import { loadBrowserRows, loadFilingPositions, loadFundDetail } from "./data";
|
|
25
|
+
import { corporateSplitFactor, loadBrowserRows, loadFilingPositions, loadFundDetail, loadSplitFactors } from "./data";
|
|
26
26
|
import { FundOverlapView } from "./overlap-pane";
|
|
27
27
|
import { ThirteenFCrowdingPane, ThirteenFTickerHoldingsView } from "./signals-pane";
|
|
28
28
|
import { PaneFooterScope } from "../../../components/layout/pane/footer";
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
sortHoldingRows,
|
|
54
54
|
sortTimelineRows,
|
|
55
55
|
} from "./model";
|
|
56
|
-
import { isOptionType, isStaleFiling, quartersOldText } from "./report-notes";
|
|
56
|
+
import { filingGapText, holdingUnreadNotes, isOptionType, isStaleFiling, quartersOldText } from "./report-notes";
|
|
57
57
|
import {
|
|
58
58
|
renderBrowserCell,
|
|
59
59
|
renderFilingPositionCell,
|
|
@@ -345,9 +345,14 @@ export function FundDetailView({
|
|
|
345
345
|
const [openFilingId, setOpenFilingId] = usePluginPaneState<string | null>("openFilingId", null);
|
|
346
346
|
const [filingReturnTab, setFilingReturnTab] = useState<ThirteenFDetailTab | null>(null);
|
|
347
347
|
const [data, setData] = useState<FundDetailData | null>(null);
|
|
348
|
+
// The split factors of the lines that moved as across a split; null until their corporate actions answer.
|
|
349
|
+
const [splitFactors, setSplitFactors] = useState<ReadonlyMap<string, number | null> | null>(null);
|
|
348
350
|
const [status, setStatus] = useState<LoadStatus>("loading");
|
|
349
351
|
const [error, setError] = useState<string | null>(null);
|
|
350
352
|
const abortRef = useRef<AbortController | null>(null);
|
|
353
|
+
const marketData = useAssetData();
|
|
354
|
+
const marketDataRef = useRef(marketData);
|
|
355
|
+
marketDataRef.current = marketData;
|
|
351
356
|
// In the Research pane's 13F tab, h/l move between these sections while the
|
|
352
357
|
// fund is open, as they do in the 13F pane.
|
|
353
358
|
useClaimResearchTabKeys(focused);
|
|
@@ -362,7 +367,16 @@ export function FundDetailView({
|
|
|
362
367
|
.then((nextData) => {
|
|
363
368
|
if (abortRef.current !== controller) return;
|
|
364
369
|
setData(nextData);
|
|
370
|
+
setSplitFactors(null);
|
|
365
371
|
setStatus("loaded");
|
|
372
|
+
// The table is up already: a line that moved as across a split has no Est P&L until its corporate actions say whether one happened.
|
|
373
|
+
const provider = marketDataRef.current;
|
|
374
|
+
void (provider
|
|
375
|
+
? loadSplitFactors(nextData, (ticker, after, through) => corporateSplitFactor(provider, ticker, after, through), controller.signal)
|
|
376
|
+
: Promise.resolve(new Map<string, number | null>())
|
|
377
|
+
).then((factors) => {
|
|
378
|
+
if (abortRef.current === controller) setSplitFactors(factors);
|
|
379
|
+
}, () => {});
|
|
366
380
|
})
|
|
367
381
|
.catch((loadError) => {
|
|
368
382
|
if (abortRef.current !== controller) return;
|
|
@@ -380,7 +394,7 @@ export function FundDetailView({
|
|
|
380
394
|
};
|
|
381
395
|
}, [load]);
|
|
382
396
|
|
|
383
|
-
const holdingRows = useMemo(() => buildFundHoldingRows(data), [data]);
|
|
397
|
+
const holdingRows = useMemo(() => buildFundHoldingRows(data, splitFactors ?? undefined), [data, splitFactors]);
|
|
384
398
|
const visibleHoldingRows = useMemo(() => (
|
|
385
399
|
sortHoldingRows(holdingRows.filter(row => !mineOnly || mine.has(row.ticker)).map(row => ({ ...row, mine: mine.has(row.ticker) })), holdingSort)
|
|
386
400
|
), [holdingRows, holdingSort, mineOnly, mine]);
|
|
@@ -507,9 +521,14 @@ export function FundDetailView({
|
|
|
507
521
|
: []),
|
|
508
522
|
];
|
|
509
523
|
|
|
524
|
+
// A 13F-NT, or no 13F, for the newest quarter past its deadline; a stale filing's age is in the stats already.
|
|
525
|
+
const filingGap = data?.filingGap && (data.filingGap.filing || !staleFiling) ? filingGapText(data.filingGap, { command: false }) : null;
|
|
526
|
+
// Lines left without an Est P&L because their split could not be confirmed, said once their corporate actions have answered; a confirmed split is method, not a warning.
|
|
527
|
+
const splitNotices = useMemo(() => (activeTab === "holdings" && splitFactors ? holdingUnreadNotes(visibleHoldingRows) : []), [activeTab, splitFactors, visibleHoldingRows]);
|
|
528
|
+
const holdingNotices = useMemo(() => [...(filingGap ? [filingGap] : []), ...splitNotices, ...(data?.warnings ?? [])], [filingGap, splitNotices, data?.warnings]);
|
|
510
529
|
usePaneNoticeFooter({
|
|
511
530
|
registrationId: "thirteenf-holdings-notices",
|
|
512
|
-
notices:
|
|
531
|
+
notices: holdingNotices,
|
|
513
532
|
focused,
|
|
514
533
|
enabled: !openFiling && activeTab !== "overlap",
|
|
515
534
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { CrowdingRow, TickerHolderRow } from "./signals";
|
|
2
2
|
import { formatMoneyCompact } from "./format";
|
|
3
|
+
import { formatSplitRatio } from "./model";
|
|
4
|
+
import type { ThirteenFFilingGap, ThirteenFOtherManager } from "./types";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Summary lines for the 13F text reports. Each says which quarters the rows
|
|
@@ -121,6 +123,82 @@ export function staleFundsText(funds: readonly { name: string; quarters: number
|
|
|
121
123
|
return `Latest filing 2+ quarters old: ${named}${funds.length > shown ? ` and ${count(funds.length - shown)} more` : ""}`;
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
interface SplitLine {
|
|
127
|
+
ticker: string;
|
|
128
|
+
issuer: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const lineName = (line: SplitLine) => line.ticker || line.issuer;
|
|
132
|
+
|
|
133
|
+
/** The first few lines as `text` gives them, then a count of the rest. */
|
|
134
|
+
function listedLines<T>(lines: readonly T[], text: (line: T) => string, shown = 5): string {
|
|
135
|
+
return `${lines.slice(0, shown).map(text).join(", ")}${lines.length > shown ? ` and ${count(lines.length - shown)} more` : ""}`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** "Split-adjusted: NVDA 10:1, Odd Co 1:10 (split between the filings, as the corporate actions show)": lines priced on split-adjusted shares. */
|
|
139
|
+
export function splitAdjustedText(lines: readonly (SplitLine & { ratio: number })[], prefix = "Split-adjusted"): string {
|
|
140
|
+
return `${prefix}: ${listedLines(lines, (line) => `${lineName(line)} ${formatSplitRatio(line.ratio)}`)} (split between the filings, as the corporate actions show)`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** "No Est P&L: XYZ (shares and value per share moved as across a split, and the corporate actions could not be read to tell)": lines left without a figure, `leftOut` opening it. */
|
|
144
|
+
export function splitUnreadText(lines: readonly SplitLine[], leftOut: string): string {
|
|
145
|
+
return `${leftOut}: ${listedLines(lines, lineName)} (shares and value per share moved as across a split, and the corporate actions could not be read to tell)`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** The note for the lines of a Holdings table left without an Est P&L because their split could not be confirmed: a data limitation, the pane's notice as well as the report's. */
|
|
149
|
+
export function holdingUnreadNotes(rows: readonly (SplitLine & { splitUnread?: boolean })[]): string[] {
|
|
150
|
+
const unread = rows.filter((row) => row.splitUnread);
|
|
151
|
+
return unread.length ? [splitUnreadText(unread, "No Est P&L")] : [];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** What a Holdings report says of its lines that moved as across a split: the ones priced split-adjusted (method, so a report's note only), and the ones left without a figure. */
|
|
155
|
+
export function holdingSplitNotes(rows: readonly (SplitLine & { splitRatio?: number; splitUnread?: boolean })[]): string[] {
|
|
156
|
+
const adjusted = rows.flatMap((row) => row.splitRatio ? [{ ...row, ratio: row.splitRatio }] : []);
|
|
157
|
+
return [...(adjusted.length ? [splitAdjustedText(adjusted, "Est P&L split-adjusted")] : []), ...holdingUnreadNotes(rows)];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** "Q2 2026" for the quarter ending 30 Jun 2026. */
|
|
161
|
+
function quarterText(period: string): string {
|
|
162
|
+
const day = calendarDay(period);
|
|
163
|
+
return day ? `Q${Math.floor(day.getUTCMonth() / 3) + 1} ${day.getUTCFullYear()}` : period;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The fund to open for a manager: its CIK, else its quoted name. */
|
|
167
|
+
function openCommand(manager: ThirteenFOtherManager): string {
|
|
168
|
+
return manager.cik ? `fn 13F ${manager.cik}` : `fn 13F "${manager.name}"`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* What a fund filed for the newest quarter past its deadline instead of a
|
|
173
|
+
* holdings report: "13F-NT for Q2 2026, filed 14 Aug; holdings reported by
|
|
174
|
+
* PERSHING SQUARE INC. | open: fn 13F 0002026053", or "No 13F for Q2 2026,
|
|
175
|
+
* due 14 Aug" once EDGAR shows nothing. `command: false` names the CIK instead
|
|
176
|
+
* of the command, for the pane.
|
|
177
|
+
*/
|
|
178
|
+
export function filingGapText(gap: ThirteenFFilingGap, { command = true }: { command?: boolean } = {}): string {
|
|
179
|
+
const quarter = quarterText(gap.period);
|
|
180
|
+
const year = Number(gap.due.slice(0, 4));
|
|
181
|
+
const filing = gap.filing;
|
|
182
|
+
if (filing?.form.startsWith("13F-NT")) {
|
|
183
|
+
const [first, ...others] = filing.otherManagers ?? [];
|
|
184
|
+
const filed = `13F-NT for ${quarter}, filed ${filingDayText(filing.filed, year)}`;
|
|
185
|
+
if (!first) return `${filed}; another manager reported its holdings`;
|
|
186
|
+
const more = others.length ? ` and ${count(others.length)} more` : "";
|
|
187
|
+
return command
|
|
188
|
+
? `${filed}; holdings reported by ${first.name}${more} | open: ${openCommand(first)}`
|
|
189
|
+
: `${filed}; holdings reported by ${first.name}${first.cik ? ` (CIK ${first.cik})` : ""}${more}`;
|
|
190
|
+
}
|
|
191
|
+
if (filing) return `${filing.form} for ${quarter} filed ${filingDayText(filing.filed, year)}; its holdings are not loaded yet`;
|
|
192
|
+
// Unasked, EDGAR may well hold a 13F-NT or a report the source has not loaded: say only what the loaded filings show.
|
|
193
|
+
if (!gap.checked) return `${quarter} 13F (due ${filingDayText(gap.due, year)}) not in the loaded filings; EDGAR not checked`;
|
|
194
|
+
return `No 13F for ${quarter}, due ${filingDayText(gap.due, year)}`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** A search asks EDGAR about a few lagging funds only: "EDGAR checked for the first 10 of 14 funds with no Q2 2026 13F loaded; ...". */
|
|
198
|
+
export function uncheckedFundsText(asked: number, behind: number, period: string): string {
|
|
199
|
+
return `EDGAR checked for the first ${count(asked)} of ${count(behind)} funds with no ${quarterText(period)} 13F loaded; fn 13F <CIK> checks any other`;
|
|
200
|
+
}
|
|
201
|
+
|
|
124
202
|
/** "showing 50 of 374" from the start of the list, "showing 51-100 of 374" past it. */
|
|
125
203
|
function shownRangeText(offset: number, end: number, total: number): string {
|
|
126
204
|
return offset > 0
|
|
@@ -97,6 +97,51 @@ export interface FundDetailData {
|
|
|
97
97
|
latestReport?: ThirteenFPeriodReport;
|
|
98
98
|
previousReport?: ThirteenFPeriodReport;
|
|
99
99
|
warnings?: string[];
|
|
100
|
+
/** Set when the latest report predates the newest quarter past its deadline. */
|
|
101
|
+
filingGap?: ThirteenFFilingGap | null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A manager a 13F-NT names as reporting its holdings. */
|
|
105
|
+
export interface ThirteenFOtherManager {
|
|
106
|
+
/** Null on a cover page that gives only the 028- file number. */
|
|
107
|
+
cik: string | null;
|
|
108
|
+
name: string;
|
|
109
|
+
fileNumber: string | null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** One 13F filing as EDGAR lists it, notices included. */
|
|
113
|
+
export interface ThirteenFEdgarFiling {
|
|
114
|
+
/** 13F-HR, 13F-HR/A, 13F-NT or 13F-NT/A. */
|
|
115
|
+
form: string;
|
|
116
|
+
period: string;
|
|
117
|
+
filed: string;
|
|
118
|
+
accession: string;
|
|
119
|
+
url: string;
|
|
120
|
+
otherManagers?: ThirteenFOtherManager[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** A filer's 13F filings from EDGAR, newest first. */
|
|
124
|
+
export interface ThirteenFFilerStatus {
|
|
125
|
+
cik: string;
|
|
126
|
+
name: string;
|
|
127
|
+
source: string;
|
|
128
|
+
filings: ThirteenFEdgarFiling[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* What a fund filed for the newest quarter past its deadline when no holdings
|
|
133
|
+
* report for it is loaded: a 13F-NT (another manager reported the holdings), a
|
|
134
|
+
* report EDGAR has that is not loaded yet, or nothing EDGAR shows.
|
|
135
|
+
*/
|
|
136
|
+
export interface ThirteenFFilingGap {
|
|
137
|
+
/** The quarter end, YYYY-MM-DD. */
|
|
138
|
+
period: string;
|
|
139
|
+
/** The day the 13F was due, YYYY-MM-DD. */
|
|
140
|
+
due: string;
|
|
141
|
+
/** The fund's own filing for that quarter, when EDGAR lists one. */
|
|
142
|
+
filing: ThirteenFEdgarFiling | null;
|
|
143
|
+
/** False when EDGAR could not be asked; a missing filing is then as far as the loaded reports know. */
|
|
144
|
+
checked: boolean;
|
|
100
145
|
}
|
|
101
146
|
|
|
102
147
|
/** The public report for one period, after applying known amendment types. */
|
|
@@ -126,6 +171,10 @@ export interface FundHoldingRow {
|
|
|
126
171
|
previousShares: number | null;
|
|
127
172
|
valueChange: number | null;
|
|
128
173
|
estimatedPnl: number | null;
|
|
174
|
+
/** New shares per old (10 for 10:1) when the filings straddle a split its corporate actions show: Est P&L is priced, and sharesChange, sharesChangePercent and action measured, on the previous shares carried across it. */
|
|
175
|
+
splitRatio?: number;
|
|
176
|
+
/** The line moved as across a split and its corporate actions could not be read to tell: Est P&L is left empty, not priced as a crash or a surge, and its share change stays as filed. */
|
|
177
|
+
splitUnread?: boolean;
|
|
129
178
|
sharesChange: number | null;
|
|
130
179
|
sharesChangePercent: number | null;
|
|
131
180
|
action: HoldingAction;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type DataTableCell,
|
|
11
11
|
type DataTableColumn,
|
|
12
12
|
type DataTableKeyEvent,
|
|
13
|
+
type PaneFooterSegment,
|
|
13
14
|
} from "../../../../components";
|
|
14
15
|
import { TIME_RANGES, type TimeRange } from "../../../../time-series/range";
|
|
15
16
|
import type { PaneProps } from "../../../../types/plugin";
|
|
@@ -20,7 +21,9 @@ import { isPlainKeyboardEvent } from "../../../../utils/keyboard";
|
|
|
20
21
|
import { publicTickerKey } from "../../../../utils/exchanges";
|
|
21
22
|
import { formatPriceObservation, quoteFormatOptions } from "../../../../market-data/market/format";
|
|
22
23
|
import { cleanFloat32Price, historyPriceDecimals } from "../../../../cli/history-rows";
|
|
23
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
MISSING_VOLUME_TEXT, missingVolumeCount, missingVolumeNotice, pricePointValues, priceHistoryIntegrityNotice,
|
|
26
|
+
} from "../../../../utils/price-history-integrity";
|
|
24
27
|
import {
|
|
25
28
|
useAssetData,
|
|
26
29
|
useDebouncedPluginPaneState,
|
|
@@ -29,6 +32,18 @@ import {
|
|
|
29
32
|
import { usePaneTicker } from "../../../../state/app/context";
|
|
30
33
|
import { handleRefreshKey, useClampSelectedIndex } from "../../../../components/data-table/table-pane";
|
|
31
34
|
import { useBoundTicker, useTickerRequest } from "../../shared/ticker-request";
|
|
35
|
+
import { DAY_SO_FAR_TEXT, withSessionBar } from "../../../../time-series/session-bar";
|
|
36
|
+
import {
|
|
37
|
+
formingHistoryBar,
|
|
38
|
+
formingHistoryBarText,
|
|
39
|
+
HISTORY_DEFAULT_RANGE,
|
|
40
|
+
historyBarDate,
|
|
41
|
+
historyBarSize,
|
|
42
|
+
historyBarSizeText,
|
|
43
|
+
historyBarSizeWord,
|
|
44
|
+
historyDateHeader,
|
|
45
|
+
type HistoryBarSize,
|
|
46
|
+
} from "./history-bars";
|
|
32
47
|
|
|
33
48
|
type HistoryColumnId = "date" | "open" | "high" | "low" | "close" | "change" | "changePercent" | "volume";
|
|
34
49
|
type HistoryColumn = DataTableColumn & { id: HistoryColumnId };
|
|
@@ -36,7 +51,18 @@ type HistoryColumn = DataTableColumn & { id: HistoryColumnId };
|
|
|
36
51
|
export type HistoricalPriceRow = {
|
|
37
52
|
key: string;
|
|
38
53
|
point: ReturnType<typeof pricePointValues>;
|
|
54
|
+
/** The bar's date as the table reads it: `2026-10 MTD` for a month still running, `2026-10-16 DTD` for today's session. */
|
|
39
55
|
date: string;
|
|
56
|
+
/** What a CSV export writes for the date: the bar's own date, whatever the table says of its period. */
|
|
57
|
+
exportDate: string;
|
|
58
|
+
/** The bar carries a time of day, so the table dates it with one. */
|
|
59
|
+
timed: boolean;
|
|
60
|
+
/** When the bar opens, or the time of the latest trade an intraday history can end with (latestTradeIndex). */
|
|
61
|
+
time: number;
|
|
62
|
+
/** The bar's period had not ended: a week or month still running, or the day's session still trading. */
|
|
63
|
+
partial: boolean;
|
|
64
|
+
/** A coin's day Gloom Cloud rebuilt from hourly bars, which has no volume of its own. */
|
|
65
|
+
filled: boolean;
|
|
40
66
|
change: number | null;
|
|
41
67
|
changePercent: number | null;
|
|
42
68
|
};
|
|
@@ -86,29 +112,56 @@ function formatMaybePercent(value: number | null): string {
|
|
|
86
112
|
return value == null ? "-" : formatPercent(value);
|
|
87
113
|
}
|
|
88
114
|
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
/** Volume as the table shows it; missing reads as missing (`volumeMissing`) in a history that reports volume, never 0. */
|
|
116
|
+
function formatVolume(value: number | null | undefined, volumeMissing: boolean): string {
|
|
117
|
+
return value == null ? volumeMissing ? MISSING_VOLUME_TEXT : "-" : formatCompact(value);
|
|
91
118
|
}
|
|
92
119
|
|
|
93
|
-
|
|
120
|
+
interface HistoricalPriceTable {
|
|
121
|
+
/** Newest first. */
|
|
122
|
+
rows: HistoricalPriceRow[];
|
|
123
|
+
size: HistoryBarSize;
|
|
124
|
+
/** The newest bar's week or month had not ended, and how far into it the bar runs. */
|
|
125
|
+
forming: ReturnType<typeof formingHistoryBar>;
|
|
126
|
+
/** The newest bar is a day whose session is still trading. */
|
|
127
|
+
dayToDate: boolean;
|
|
128
|
+
/** The newest bar's day, `YYYY-MM-DD`. */
|
|
129
|
+
newestDate: string | undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function buildHistoricalPriceRows(points: PricePoint[], venue: string | undefined, now: number): HistoricalPriceTable {
|
|
94
133
|
const sorted = points
|
|
95
134
|
.flatMap((point, sourceIndex) => {
|
|
96
135
|
const date = pricePointDate(point);
|
|
97
|
-
return date ? [{ point: pricePointValues(point), date, sourceIndex }] : [];
|
|
136
|
+
return date ? [{ point: pricePointValues(point), date, sourceIndex, partial: point.partial === true, filled: point.filled === true }] : [];
|
|
98
137
|
})
|
|
99
138
|
.sort((left, right) => left.date.getTime() - right.date.getTime());
|
|
100
|
-
|
|
139
|
+
const size = historyBarSize(sorted.map((entry) => entry.date.getTime()));
|
|
140
|
+
const newestDate = sorted.at(-1)?.date.toISOString().slice(0, 10);
|
|
141
|
+
const forming = formingHistoryBar(size, newestDate, venue, now);
|
|
142
|
+
const dayToDate = size === "1d" && sorted.at(-1)?.partial === true;
|
|
143
|
+
const rows = sorted.map((entry, index) => {
|
|
101
144
|
const previous = sorted[index - 1]?.point;
|
|
102
|
-
const { point, date, sourceIndex } = entry;
|
|
145
|
+
const { point, date, sourceIndex, filled } = entry;
|
|
146
|
+
const newest = index === sorted.length - 1;
|
|
147
|
+
const partial = newest && (!!forming || dayToDate);
|
|
103
148
|
const change = previous?.close != null && point.close != null ? point.close - previous.close : null;
|
|
149
|
+
const shown = formatDateTime(date);
|
|
150
|
+
const timed = shown.length > 10;
|
|
104
151
|
return {
|
|
105
152
|
key: `${date.toISOString()}:${sourceIndex}`,
|
|
106
153
|
point,
|
|
107
|
-
date:
|
|
154
|
+
date: timed ? shown : historyBarDate(shown, size, partial),
|
|
155
|
+
exportDate: shown,
|
|
156
|
+
timed,
|
|
157
|
+
time: date.getTime(),
|
|
158
|
+
partial,
|
|
159
|
+
filled,
|
|
108
160
|
change,
|
|
109
161
|
changePercent: previous?.close && change !== null ? change / previous.close : null,
|
|
110
162
|
};
|
|
111
163
|
}).reverse();
|
|
164
|
+
return { rows, size, forming, dayToDate, newestDate };
|
|
112
165
|
}
|
|
113
166
|
|
|
114
167
|
const HISTORY_PRICE_WIDTH = 10;
|
|
@@ -123,8 +176,9 @@ const HISTORY_NUMERIC_IDS = ["open", "high", "low", "close", "change", "changePe
|
|
|
123
176
|
* evenly, and give up cells down to a floor when it is narrow, so the volume
|
|
124
177
|
* stays on screen.
|
|
125
178
|
*/
|
|
126
|
-
function buildHistoryColumns(width: number, intraday: boolean): HistoryColumn[] {
|
|
127
|
-
|
|
179
|
+
function buildHistoryColumns(width: number, intraday: boolean, size: HistoryBarSize, newestDate: string): HistoryColumn[] {
|
|
180
|
+
// A month reads as `2026-10`; the newest bar, when its week or month runs on, adds `MTD` or `WTD`.
|
|
181
|
+
const dateWidth = Math.max(intraday ? 16 : size === "1mo" ? 7 : 10, newestDate.length);
|
|
128
182
|
const numeric: number[] = HISTORY_NUMERIC_IDS.map((id) => id === "changePercent" ? HISTORY_PERCENT_WIDTH : HISTORY_PRICE_WIDTH);
|
|
129
183
|
// One gap per column plus the table's inset on both sides.
|
|
130
184
|
const available = width - dateWidth - HISTORY_VOLUME_WIDTH - 8 - 2;
|
|
@@ -141,7 +195,7 @@ function buildHistoryColumns(width: number, intraday: boolean): HistoryColumn[]
|
|
|
141
195
|
}
|
|
142
196
|
const [open, high, low, close, change, changePercent] = numeric as [number, number, number, number, number, number];
|
|
143
197
|
return [
|
|
144
|
-
{ id: "date", label: intraday ? "DATE/TIME" : "DATE", width: dateWidth, align: "left" },
|
|
198
|
+
{ id: "date", label: intraday ? "DATE/TIME" : historyDateHeader(size)?.toUpperCase() ?? "DATE", width: dateWidth, align: "left" },
|
|
145
199
|
{ id: "open", label: "OPEN", width: open, align: "right", flexGrow: 1 },
|
|
146
200
|
{ id: "high", label: "HIGH", width: high, align: "right", flexGrow: 1 },
|
|
147
201
|
{ id: "low", label: "LOW", width: low, align: "right", flexGrow: 1 },
|
|
@@ -162,7 +216,7 @@ function nextHistoryRange(current: TimeRange): TimeRange {
|
|
|
162
216
|
export function HistoricalPricesPane({ focused, width, height }: PaneProps) {
|
|
163
217
|
const dataProvider = useAssetData();
|
|
164
218
|
const { symbol, exchange, ticker } = useBoundTicker();
|
|
165
|
-
const [range, setRange] = usePluginPaneState<TimeRange>("range",
|
|
219
|
+
const [range, setRange] = usePluginPaneState<TimeRange>("range", HISTORY_DEFAULT_RANGE);
|
|
166
220
|
const [selectedIdx, setSelectedIdx] = useDebouncedPluginPaneState<number>("selectedIdx", 0);
|
|
167
221
|
const loader = useCallback((nextSymbol: string, nextExchange: string, forceRefresh: boolean) => {
|
|
168
222
|
if (!dataProvider) throw new Error("Market data unavailable");
|
|
@@ -174,14 +228,31 @@ export function HistoricalPricesPane({ focused, width, height }: PaneProps) {
|
|
|
174
228
|
);
|
|
175
229
|
}, [dataProvider, range]);
|
|
176
230
|
const { data, loading, error, reload } = useTickerRequest<PricePoint[]>(loader, symbol, exchange);
|
|
177
|
-
const rows = useMemo(() => buildHistoricalPriceRows(data ?? []), [data]);
|
|
178
|
-
const integrityNotice = priceHistoryIntegrityNotice(rows.filter((row) => row.point.integrity).length);
|
|
179
|
-
// Daily and longer bars are dates; only intraday bars carry a time.
|
|
180
|
-
const intraday = rows.length > 0 ? rows.some((row) => row.date.length > 10) : range === "1D" || range === "1W";
|
|
181
|
-
const columns = useMemo(() => buildHistoryColumns(width, intraday), [intraday, width]);
|
|
182
231
|
// The quote knows the instrument type even when the saved ticker does not;
|
|
183
|
-
// resolve it the way every quote display does.
|
|
232
|
+
// resolve it the way every quote display does. It also names the venue
|
|
233
|
+
// whose sessions say whether a week or month is still running.
|
|
184
234
|
const { financials } = usePaneTicker();
|
|
235
|
+
const venue = exchange || financials?.quote?.listingExchangeName || financials?.quote?.exchangeName || undefined;
|
|
236
|
+
// While the session trades the day's bar is the quote's: the history keeps a
|
|
237
|
+
// snapshot of it from whenever it was last fetched (withSessionBar).
|
|
238
|
+
const quote = financials?.quote;
|
|
239
|
+
const points = useMemo(
|
|
240
|
+
() => withSessionBar(data ?? [], quote, { now: Date.now(), venue }),
|
|
241
|
+
[data, quote, venue],
|
|
242
|
+
);
|
|
243
|
+
const { rows, size, forming, dayToDate, newestDate } = useMemo(
|
|
244
|
+
() => buildHistoricalPriceRows(points, venue, Date.now()),
|
|
245
|
+
[points, venue],
|
|
246
|
+
);
|
|
247
|
+
const integrityNotice = priceHistoryIntegrityNotice(rows.filter((row) => row.point.integrity).length);
|
|
248
|
+
const volumeMissing = useMemo(() => missingVolumeCount(rows.map((row) => ({
|
|
249
|
+
...row.point, date: row.time, partial: row.partial, filled: row.filled,
|
|
250
|
+
}))), [rows]);
|
|
251
|
+
const volumeNotice = missingVolumeNotice(volumeMissing, rows.length);
|
|
252
|
+
// Daily and longer bars are dates; only intraday bars carry a time.
|
|
253
|
+
const intraday = rows.length > 0 ? rows.some((row) => row.timed) : range === "1D" || range === "1W";
|
|
254
|
+
const newestRowDate = rows[0]?.date ?? "";
|
|
255
|
+
const columns = useMemo(() => buildHistoryColumns(width, intraday, size, newestRowDate), [intraday, newestRowDate, size, width]);
|
|
185
256
|
const assetCategory = quoteFormatOptions(
|
|
186
257
|
financials?.quote,
|
|
187
258
|
ticker?.metadata.assetCategory,
|
|
@@ -217,7 +288,7 @@ export function HistoricalPricesPane({ focused, width, height }: PaneProps) {
|
|
|
217
288
|
): DataTableCell => {
|
|
218
289
|
switch (column.id) {
|
|
219
290
|
case "date":
|
|
220
|
-
return { text: row.date, color: colors.textDim };
|
|
291
|
+
return { text: row.date, value: row.exportDate, color: colors.textDim };
|
|
221
292
|
case "open":
|
|
222
293
|
case "high":
|
|
223
294
|
case "low":
|
|
@@ -232,16 +303,23 @@ export function HistoricalPricesPane({ focused, width, height }: PaneProps) {
|
|
|
232
303
|
case "changePercent":
|
|
233
304
|
return { text: formatMaybePercent(row.changePercent), value: row.changePercent == null ? null : row.changePercent * 100, color: priceColor(row.changePercent ?? 0) };
|
|
234
305
|
case "volume":
|
|
235
|
-
return { text:
|
|
306
|
+
return { text: formatVolume(row.point.volume, volumeMissing > 0), value: row.point.volume ?? null, color: colors.textDim };
|
|
236
307
|
}
|
|
237
|
-
}, [priceDecimals]);
|
|
308
|
+
}, [priceDecimals, volumeMissing]);
|
|
238
309
|
|
|
239
|
-
// The range is picked in the query bar; t still steps through it.
|
|
240
|
-
|
|
310
|
+
// The range is picked in the query bar; t still steps through it. The range
|
|
311
|
+
// sets the bar size, which the footer says, and a week or month still
|
|
312
|
+
// running says how far the newest bar goes.
|
|
313
|
+
const barInfo = useMemo<PaneFooterSegment[]>(() => [
|
|
314
|
+
...rows.length > 0 ? [{ id: "bars", parts: [{ text: historyBarSizeText(size), tone: "muted" as const }] }] : [],
|
|
315
|
+
...forming && newestDate ? [{ id: "forming", parts: [{ text: formingHistoryBarText(forming, newestDate), tone: "muted" as const }] }] : [],
|
|
316
|
+
...dayToDate ? [{ id: "forming", parts: [{ text: DAY_SO_FAR_TEXT, tone: "muted" as const }] }] : [],
|
|
317
|
+
], [dayToDate, forming, newestDate, rows.length, size]);
|
|
318
|
+
usePaneStatusFooter({ registrationId: "historical-prices", loading, error, info: barInfo });
|
|
241
319
|
|
|
242
320
|
usePaneNoticeFooter({
|
|
243
321
|
registrationId: "historical-prices:integrity",
|
|
244
|
-
notices: integrityNotice
|
|
322
|
+
notices: [integrityNotice, volumeNotice].filter((notice): notice is string => !!notice),
|
|
245
323
|
focused,
|
|
246
324
|
title: "Price history data",
|
|
247
325
|
});
|
|
@@ -280,11 +358,15 @@ export function HistoricalPricesPane({ focused, width, height }: PaneProps) {
|
|
|
280
358
|
getExportMetadata={() => [
|
|
281
359
|
["Ticker", symbol ? publicTickerKey(symbol, exchange) : ""],
|
|
282
360
|
["Requested range", range],
|
|
361
|
+
...(rows.length > 0 ? [["Bar size", historyBarSizeWord(size)]] : []),
|
|
283
362
|
["Time zone", "UTC"],
|
|
363
|
+
...(forming && newestDate ? [["Partial bar", `${newestDate}, ${formingHistoryBarText(forming, newestDate)}`]] : []),
|
|
364
|
+
...(dayToDate && newestDate ? [["Partial bar", `${newestDate}, ${DAY_SO_FAR_TEXT}`]] : []),
|
|
284
365
|
["Price units", "As served in the history; currency and price-basis metadata are unavailable"],
|
|
285
366
|
["Status", error ? (rows.length ? "Retained after refresh failure" : "Unavailable")
|
|
286
367
|
: loading ? (rows.length ? "Refreshing" : "Loading") : rows.length ? "Available" : "Empty"],
|
|
287
368
|
...(integrityNotice ? [["Warning", integrityNotice]] : []),
|
|
369
|
+
...(volumeNotice ? [["Volume note", volumeNotice]] : []),
|
|
288
370
|
...(error ? [["Error", error]] : []),
|
|
289
371
|
]}
|
|
290
372
|
emptyStateTitle={error
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { BAR_INTERVAL_LABELS } from "../../../../cli/history-rows";
|
|
2
|
+
import { periodToDateText } from "../../../../cli/pane-functions/freshness";
|
|
3
|
+
import { barLastSession, barPeriodToDate, type BarPeriod, type BarPeriodToDate } from "../../../../market-data/market/bar-period";
|
|
4
|
+
import { barSizeFromGap, medianBarGap } from "../../../../time-series/bar-spacing";
|
|
5
|
+
import type { TimeRange } from "../../../../time-series/range";
|
|
6
|
+
import { CHART_RESOLUTION_STEP_MS, type ManualChartResolution } from "../../../../time-series/resolution";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The range a price history opens on, in Historical Prices, `fn HP` and
|
|
10
|
+
* `shot HP`: a recent window in daily bars (RANGE_HISTORY_RESOLUTION serves
|
|
11
|
+
* 1M to 1Y daily). 5Y is weekly and ALL monthly, so neither is a place to start.
|
|
12
|
+
*/
|
|
13
|
+
export const HISTORY_DEFAULT_RANGE: TimeRange = "3M";
|
|
14
|
+
|
|
15
|
+
/** The size of one bar of a price history; `intraday` when its minutes are not a size the source serves. */
|
|
16
|
+
export type HistoryBarSize = ManualChartResolution | "intraday";
|
|
17
|
+
|
|
18
|
+
const INTRADAY_SIZES: readonly ManualChartResolution[] = ["1m", "5m", "15m", "30m", "45m", "1h"];
|
|
19
|
+
/** A day's bars can sit a little under a day apart where the clocks change. */
|
|
20
|
+
const INTRADAY_BELOW_MS = 0.8 * CHART_RESOLUTION_STEP_MS["1d"];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The bar size of a history, read from the usual spacing of its bars
|
|
24
|
+
* (medianBarGap), as `history` reads it, so the gap a holiday leaves does not
|
|
25
|
+
* make daily bars weekly. Daily when there is no gap to read.
|
|
26
|
+
*/
|
|
27
|
+
export function historyBarSize(times: readonly number[]): HistoryBarSize {
|
|
28
|
+
const gap = medianBarGap(times);
|
|
29
|
+
if (gap == null) return "1d";
|
|
30
|
+
if (gap < INTRADAY_BELOW_MS) return INTRADAY_SIZES.find((size) => CHART_RESOLUTION_STEP_MS[size] === gap) ?? "intraday";
|
|
31
|
+
return barSizeFromGap(gap);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Whether a bar of this size covers a day or more, so its date is a day and not a time. */
|
|
35
|
+
export function isDailyOrLongerBar(size: HistoryBarSize): size is "1d" | "1wk" | "1mo" {
|
|
36
|
+
return size === "1d" || size === "1wk" || size === "1mo";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** `daily`, `5-minute`, `hourly`, `weekly`, `monthly`; `intraday` when the minutes are not a known size. */
|
|
40
|
+
export function historyBarSizeWord(size: HistoryBarSize): string {
|
|
41
|
+
return size === "intraday" ? size : BAR_INTERVAL_LABELS[size];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** `daily bars`, `monthly bars`: what a history says its bars are, which the range it was asked for sets. */
|
|
45
|
+
export function historyBarSizeText(size: HistoryBarSize): string {
|
|
46
|
+
return `${historyBarSizeWord(size)} bars`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* What a date column heads when its bars cover more than a day: `Week of`
|
|
51
|
+
* (each is dated by the day its week starts) or `Month`. Null for a day's bar,
|
|
52
|
+
* whose column is `Date`, or an intraday one, which is dated with a time.
|
|
53
|
+
*/
|
|
54
|
+
export function historyDateHeader(size: HistoryBarSize): string | null {
|
|
55
|
+
return size === "1wk" ? "Week of" : size === "1mo" ? "Month" : null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The calendar period a weekly or monthly bar covers; null for any other. */
|
|
59
|
+
function historyBarPeriod(size: HistoryBarSize): BarPeriod | null {
|
|
60
|
+
return size === "1mo" ? "month" : size === "1wk" ? "week" : null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether the newest bar, dated `date`, is a week or month that had not ended
|
|
65
|
+
* at `now` on its `venue` (barPeriodToDate), and how far into it the bar runs.
|
|
66
|
+
* Null for a complete bar, and for any bar that is not weekly or monthly.
|
|
67
|
+
*/
|
|
68
|
+
export function formingHistoryBar(
|
|
69
|
+
size: HistoryBarSize,
|
|
70
|
+
date: string | undefined,
|
|
71
|
+
venue: string | undefined,
|
|
72
|
+
now: number,
|
|
73
|
+
): BarPeriodToDate | null {
|
|
74
|
+
const period = historyBarPeriod(size);
|
|
75
|
+
return period && date ? barPeriodToDate(date, period, venue, now) : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The day the newest weekly or monthly bar, dated `date` by the start of its
|
|
80
|
+
* period, closed on once that period has ended (barLastSession): the week of
|
|
81
|
+
* Mon 12 Oct 2026 is Fri 16 Oct, the day its close is from. Null while it
|
|
82
|
+
* forms (formingHistoryBar dates it then), and for any other bar.
|
|
83
|
+
*/
|
|
84
|
+
export function closedHistoryBarDay(
|
|
85
|
+
size: HistoryBarSize,
|
|
86
|
+
date: string | undefined,
|
|
87
|
+
venue: string | undefined,
|
|
88
|
+
now: number,
|
|
89
|
+
): string | null {
|
|
90
|
+
const period = historyBarPeriod(size);
|
|
91
|
+
return period && date && !barPeriodToDate(date, period, venue, now) ? barLastSession(date, period, venue, now) : null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A bar's day as its table dates it: a month's bar as the month (`2026-10`),
|
|
96
|
+
* a week's by the day it starts, and `MTD`, `WTD` or `DTD` after one whose
|
|
97
|
+
* period had not ended, so it never reads as a complete bar dated on its
|
|
98
|
+
* first day. `day` is `YYYY-MM-DD`.
|
|
99
|
+
*/
|
|
100
|
+
export function historyBarDate(day: string, size: HistoryBarSize, partial = false): string {
|
|
101
|
+
const text = size === "1mo" ? day.slice(0, 7) : day;
|
|
102
|
+
return partial ? `${text} ${size === "1mo" ? "MTD" : size === "1wk" ? "WTD" : "DTD"}` : text;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** What the newest bar covers so far: `month to date, through Fri 16 Oct 2026`. */
|
|
106
|
+
export function formingHistoryBarText(forming: BarPeriodToDate, date: string): string {
|
|
107
|
+
return periodToDateText({ period: forming.period, ...(forming.through ? { through: forming.through } : {}) }, date);
|
|
108
|
+
}
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type ReturnRow,
|
|
43
43
|
} from "./returns-model";
|
|
44
44
|
import { loadReturnSeries, type ReturnSeries } from "./returns-history";
|
|
45
|
+
import { formingHistoryBar, formingHistoryBarText, historyBarDate } from "./history-bars";
|
|
45
46
|
|
|
46
47
|
type ReturnColumnId = "time" | "price" | "intervalChange" | "intervalPercent" | "cumulativeChange" | "cumulativePercent";
|
|
47
48
|
type ReturnColumn = DataTableColumn & { id: ReturnColumnId };
|
|
@@ -185,12 +186,21 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
185
186
|
const hints = useMemo<PaneHint[]>(() => (
|
|
186
187
|
table.searchable ? [{ id: "search", key: "/", label: "search", onPress: focusSearch }] : []
|
|
187
188
|
), [focusSearch, table.searchable]);
|
|
189
|
+
// A weekly or monthly interval's newest bar is its week or month so far when that has not ended.
|
|
190
|
+
const newestDate = returnRows[0] ? new Date(returnRows[0].timestamp).toISOString().slice(0, 10) : undefined;
|
|
191
|
+
const forming = useMemo(
|
|
192
|
+
() => data ? formingHistoryBar(data.resolution, newestDate, data.venue || undefined, Date.now()) : null,
|
|
193
|
+
[data, newestDate],
|
|
194
|
+
);
|
|
195
|
+
const formingKey = forming ? returnRows[0]?.key : undefined;
|
|
196
|
+
const barSize = data?.resolution ?? shownResolution;
|
|
188
197
|
// A shut market's window ends at its last session, which the footer names.
|
|
189
|
-
const marketInfo = useMemo<PaneFooterSegment[]>(() =>
|
|
190
|
-
data?.lastSession
|
|
191
|
-
? [{ id: "market", parts: [{ text: closedMarketNote(data.lastSession, data.visibleTo), tone: "muted" }] }]
|
|
192
|
-
: []
|
|
193
|
-
|
|
198
|
+
const marketInfo = useMemo<PaneFooterSegment[]>(() => [
|
|
199
|
+
...data?.lastSession
|
|
200
|
+
? [{ id: "market", parts: [{ text: closedMarketNote(data.lastSession, data.visibleTo), tone: "muted" as const }] }]
|
|
201
|
+
: [],
|
|
202
|
+
...forming && newestDate ? [{ id: "forming", parts: [{ text: formingHistoryBarText(forming, newestDate), tone: "muted" as const }] }] : [],
|
|
203
|
+
], [data, forming, newestDate]);
|
|
194
204
|
usePaneStatusFooter({ registrationId: "returns", loading, error, hints, info: marketInfo });
|
|
195
205
|
|
|
196
206
|
const integrityNotice = priceHistoryIntegrityNotice(returnRows.filter((row) => row.inconsistent).length);
|
|
@@ -208,8 +218,15 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
208
218
|
|
|
209
219
|
const renderCell = useCallback((row: ReturnRow, column: ReturnColumn): DataTableCell => {
|
|
210
220
|
switch (column.id) {
|
|
211
|
-
case "time":
|
|
212
|
-
|
|
221
|
+
case "time": {
|
|
222
|
+
const shown = formatDateTime(new Date(row.timestamp));
|
|
223
|
+
// A daily or longer bar is a date; a month's reads as the month, and one still running says so.
|
|
224
|
+
return {
|
|
225
|
+
text: shown.length > 10 ? shown : historyBarDate(shown, barSize, row.key === formingKey),
|
|
226
|
+
value: new Date(row.timestamp).toISOString(),
|
|
227
|
+
color: colors.textDim,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
213
230
|
case "price":
|
|
214
231
|
return { text: formatMaybePrice(row.price, priceDecimals, column.width), value: exportPrice(row.price, priceDecimals), color: colors.textBright, attributes: TextAttributes.BOLD };
|
|
215
232
|
case "intervalChange":
|
|
@@ -221,7 +238,7 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
221
238
|
case "cumulativePercent":
|
|
222
239
|
return { text: formatMaybePercent(row.cumulativePercent), value: row.cumulativePercent === null ? null : row.cumulativePercent * 100, color: priceColor(row.cumulativePercent ?? 0) };
|
|
223
240
|
}
|
|
224
|
-
}, [priceDecimals]);
|
|
241
|
+
}, [barSize, formingKey, priceDecimals]);
|
|
225
242
|
|
|
226
243
|
return (
|
|
227
244
|
<DataTableView<ReturnRow, ReturnColumn>
|
|
@@ -270,6 +287,7 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
270
287
|
["Ticker", symbol ? publicTickerKey(symbol, exchange) : ""],
|
|
271
288
|
["Range", data?.range ?? range],
|
|
272
289
|
["Interval", getChartResolutionLabel(data?.resolution ?? shownResolution)],
|
|
290
|
+
...(forming && newestDate ? [["Partial bar", `${newestDate}, ${formingHistoryBarText(forming, newestDate)}`]] : []),
|
|
273
291
|
["Window", data ? `after ${new Date(data.visibleFrom).toISOString()} through ${new Date(data.visibleTo).toISOString()}` : ""],
|
|
274
292
|
...(data?.lastSession ? [["Market", closedMarketNote(data.lastSession, data.visibleTo)]] : []),
|
|
275
293
|
["Time zone", "UTC, bar open"],
|