gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -2,6 +2,7 @@ import type { HeadlessPaneColumn, HeadlessPaneRow } from "../../../types/headles
|
|
|
2
2
|
import { fxCloseOnOrBefore, loadDailyFxCloses, type FxCloses, type FxHistoryClient } from "../../../market-data/fx-closes";
|
|
3
3
|
import { logFailure } from "../../../utils/log-failure";
|
|
4
4
|
import { formatCompact, formatNumber } from "../../../utils/format";
|
|
5
|
+
import { quotedFxPair } from "../../../utils/currency-pair";
|
|
5
6
|
|
|
6
7
|
/** A Form 4 states its prices and values in US dollars. */
|
|
7
8
|
export const FORM4_CURRENCY = "USD";
|
|
@@ -21,8 +22,9 @@ const dash = (value: unknown, format: (value: number) => string) => (typeof valu
|
|
|
21
22
|
* states them). With another base currency (CAD), each value is also given
|
|
22
23
|
* in it at the daily close of USD/CAD on its transaction day, or the last
|
|
23
24
|
* close before a weekend or holiday (`fxCloseOnOrBefore` over the history
|
|
24
|
-
* PORT and PEB read), with the rate and that close's date beside it.
|
|
25
|
-
*
|
|
25
|
+
* PORT and PEB read), with the rate and that close's date beside it. The rate
|
|
26
|
+
* reads as markets quote the pair (USD/CAD, EUR/USD), named by `fxPair`. When
|
|
27
|
+
* the closes cannot be read the values stay in USD and the note says why.
|
|
26
28
|
*/
|
|
27
29
|
export async function withInsiderBaseValues(
|
|
28
30
|
rows: readonly HeadlessPaneRow[],
|
|
@@ -33,7 +35,8 @@ export async function withInsiderBaseValues(
|
|
|
33
35
|
const labelled: HeadlessPaneRow[] = rows.map((row) => ({ ...row, currency: FORM4_CURRENCY }));
|
|
34
36
|
const base = baseCurrency.trim().toUpperCase();
|
|
35
37
|
if (!base || base === FORM4_CURRENCY) return { rows: labelled, columns: null, note: null };
|
|
36
|
-
|
|
38
|
+
// The pair as markets quote it: USD/CAD, but EUR/USD for a euro base.
|
|
39
|
+
const pair = quotedFxPair(FORM4_CURRENCY, base, 1).pair;
|
|
37
40
|
const days = labelled.flatMap((row) => typeof row.transactionDate === "string" && typeof row.totalValue === "number"
|
|
38
41
|
? [row.transactionDate.slice(0, 10)] : []).sort();
|
|
39
42
|
let closes: FxCloses | null = null;
|
|
@@ -47,13 +50,14 @@ export async function withInsiderBaseValues(
|
|
|
47
50
|
const converted = labelled.map((row) => {
|
|
48
51
|
const day = typeof row.transactionDate === "string" ? row.transactionDate.slice(0, 10) : null;
|
|
49
52
|
const reading = closes && day && typeof row.totalValue === "number" ? fxCloseOnOrBefore(closes, day) : null;
|
|
50
|
-
// The close is USD per unit of the base currency
|
|
51
|
-
const
|
|
53
|
+
// The close is USD per unit of the base currency: the base currency per dollar is its inverse.
|
|
54
|
+
const perDollar = reading ? 1 / reading.rate : null;
|
|
52
55
|
return {
|
|
53
56
|
...row,
|
|
54
57
|
baseCurrency: base,
|
|
55
|
-
valueBase:
|
|
56
|
-
|
|
58
|
+
valueBase: perDollar != null ? (row.totalValue as number) * perDollar : null,
|
|
59
|
+
fxPair: pair,
|
|
60
|
+
fxRate: perDollar != null ? quotedFxPair(FORM4_CURRENCY, base, perDollar).rate : null,
|
|
57
61
|
fxDate: reading?.date ?? null,
|
|
58
62
|
};
|
|
59
63
|
});
|
|
@@ -7,6 +7,9 @@ import { filesAsForeignPrivateIssuer } from "./issuer";
|
|
|
7
7
|
// this many filings or the company's history ends.
|
|
8
8
|
const SEC_FILING_SCAN_LIMIT = 20_000;
|
|
9
9
|
|
|
10
|
+
/** The company's own filings `fn INS` reads by default, and `insider` sums up as it does. */
|
|
11
|
+
export const INSIDER_REPORT_FILINGS = 20;
|
|
12
|
+
|
|
10
13
|
export interface InsiderFilingsLoad {
|
|
11
14
|
/** The rows of the company's own Form 4 filings, newest first. */
|
|
12
15
|
parsed: ParsedInsiderFiling[];
|
|
@@ -6,8 +6,8 @@ import type {
|
|
|
6
6
|
HeadlessPaneRow,
|
|
7
7
|
} from "../../../types/plugin";
|
|
8
8
|
import { formatCompact, formatCurrency } from "../../../utils/format";
|
|
9
|
-
import { loadParsedInsiderFilings, type InsiderFilingsLoad } from "./client";
|
|
10
|
-
import { insiderEmptyNotice } from "./issuer";
|
|
9
|
+
import { INSIDER_REPORT_FILINGS, loadParsedInsiderFilings, type InsiderFilingsLoad } from "./client";
|
|
10
|
+
import { insiderEmptyNotice, loadHomeInsiderReportsNote } from "./issuer";
|
|
11
11
|
import { FORM4_CURRENCY, withInsiderBaseValues } from "./base-values";
|
|
12
12
|
import {
|
|
13
13
|
buildInsiderRows,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
import { isAmendedInsiderFiling, relevantInsiderAmendments } from "./amendments";
|
|
22
22
|
import { formatInsiderName } from "./display";
|
|
23
23
|
import { SEC_FILINGS } from "../shared/report-freshness";
|
|
24
|
-
import { resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
24
|
+
import { resolveHeadlessInstrument, resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
25
25
|
import { noSecReportsNotice } from "../../../utils/sec";
|
|
26
26
|
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
27
27
|
import type { InsiderSignalRoleGroup, InsiderSignalSide, InsiderSignalsPayload } from "../../../api-client/insider-signals";
|
|
@@ -310,6 +310,20 @@ async function noSecReportsEmpty(ctx: HeadlessPaneContext, key: string): Promise
|
|
|
310
310
|
return noSecReportsNotice({ symbol: parsePublicTickerKey(key).symbol, exchange: listing.exchange, name: listing.name ?? null });
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
/**
|
|
314
|
+
* What INS says for a company with no Form 4 of its own: why there is none,
|
|
315
|
+
* and for a company from abroad, that its home market's insider reports are
|
|
316
|
+
* not covered either ("Canadian insider reports (SEDI) not covered.").
|
|
317
|
+
*/
|
|
318
|
+
async function insiderEmpty(ctx: HeadlessPaneContext, key: string, foreignPrivateIssuer: boolean, noFilings: boolean): Promise<string> {
|
|
319
|
+
const [noReports, { exchange }] = await Promise.all([
|
|
320
|
+
noFilings ? noSecReportsEmpty(ctx, key) : null,
|
|
321
|
+
resolveHeadlessInstrument(ctx, key),
|
|
322
|
+
]);
|
|
323
|
+
const home = await loadHomeInsiderReportsNote(ctx.marketData, key, exchange, foreignPrivateIssuer);
|
|
324
|
+
return noReports ? [noReports, home].filter(Boolean).join(" ") : insiderEmptyNotice(foreignPrivateIssuer, home);
|
|
325
|
+
}
|
|
326
|
+
|
|
313
327
|
export function createInsiderHeadless(
|
|
314
328
|
dependencies: InsiderHeadlessDependencies = defaultDependencies,
|
|
315
329
|
): HeadlessPaneDefinition<"rows"> {
|
|
@@ -346,7 +360,7 @@ export function createInsiderHeadless(
|
|
|
346
360
|
aliases: ["count", "rows"],
|
|
347
361
|
description: "Maximum of the company's own Form 4 and Form 4/A filings to parse; without a ticker, companies to rank.",
|
|
348
362
|
type: "integer",
|
|
349
|
-
defaultValue:
|
|
363
|
+
defaultValue: INSIDER_REPORT_FILINGS,
|
|
350
364
|
minimum: 1,
|
|
351
365
|
maximum: 100,
|
|
352
366
|
},
|
|
@@ -445,7 +459,7 @@ export function createInsiderHeadless(
|
|
|
445
459
|
if (!symbol || args.options.view === "insiders") {
|
|
446
460
|
throw new Error(symbol
|
|
447
461
|
? `--name filters ${symbol}'s trades, not its insiders. Drop --view insiders or --name from shot.`
|
|
448
|
-
: `--name filters one company's trades:
|
|
462
|
+
: `--name filters one company's trades: gloom shot INS <ticker> --name ${JSON.stringify(name)}`);
|
|
449
463
|
}
|
|
450
464
|
return { pluginState: { "ticker-research": { [`insider:nameFilter:${parsePublicTickerKey(symbol).symbol}`]: name } } };
|
|
451
465
|
},
|
|
@@ -510,8 +524,7 @@ export function createInsiderHeadless(
|
|
|
510
524
|
}
|
|
511
525
|
const limit = Number(args.options.limit);
|
|
512
526
|
const { parsed, foreignPrivateIssuer, noFilings } = await dependencies.loadParsed(symbol, limit, args, ctx);
|
|
513
|
-
const empty = parsed.length > 0 ? null
|
|
514
|
-
: (noFilings ? await noSecReportsEmpty(ctx, symbol) : null) ?? insiderEmptyNotice(foreignPrivateIssuer);
|
|
527
|
+
const empty = parsed.length > 0 ? null : await insiderEmpty(ctx, symbol, foreignPrivateIssuer, noFilings);
|
|
515
528
|
const name = String(args.options.name ?? "").trim().toLocaleLowerCase();
|
|
516
529
|
const type = isInsiderTypeFilter(args.options.type) ? args.options.type : "all";
|
|
517
530
|
const owned = name
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
type StatItem,
|
|
31
31
|
} from "../../../components";
|
|
32
32
|
import { useDebouncedPluginPaneState, usePluginPaneState } from "../../runtime";
|
|
33
|
-
import { mayBeSecEquityListing, mayBeUsEquityTicker, noSecReportsNotice, nonUsSecListingVenue } from "../../../utils/sec";
|
|
33
|
+
import { homeInsiderReportsNote, mayBeSecEquityListing, mayBeUsEquityTicker, noSecReportsNotice, nonUsSecListingVenue } from "../../../utils/sec";
|
|
34
34
|
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
35
35
|
import { formatCompact } from "../../../utils/format";
|
|
36
36
|
import { nextHeaderSort } from "../../../utils/sort-values";
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
} from "./model";
|
|
57
57
|
import { formatInsiderName } from "./display";
|
|
58
58
|
import { insiderHeadless } from "./headless";
|
|
59
|
+
import { FORM4_CURRENCY } from "./base-values";
|
|
59
60
|
import { isInsiderForm } from "./insider-data";
|
|
60
61
|
import { filesAsForeignPrivateIssuer, insiderEmptyNotice, isOtherIssuerFiling } from "./issuer";
|
|
61
62
|
import { relevantInsiderAmendments } from "./amendments";
|
|
@@ -116,9 +117,10 @@ const TYPE_FILTER_LABELS: Record<InsiderTypeFilter, string> = {
|
|
|
116
117
|
* security when there are several. A side with no trades shows 0 shares,
|
|
117
118
|
* muted. Buys read in the gain colour and sales in the loss colour, as in
|
|
118
119
|
* the table; when the Type filter hides open-market trades the figures dim
|
|
119
|
-
* and say so.
|
|
120
|
+
* and say so. With `currency` the dollars read with its code (1.2M USD), as
|
|
121
|
+
* the table's CCY column names them.
|
|
120
122
|
*/
|
|
121
|
-
function summaryItems(figures: InsiderSummaryFigures, typeFilter: InsiderTypeFilter): StatItem[] {
|
|
123
|
+
function summaryItems(figures: InsiderSummaryFigures, typeFilter: InsiderTypeFilter, currency?: string): StatItem[] {
|
|
122
124
|
const securities = new Set(figures.totals.map((total) => total.security));
|
|
123
125
|
const hidden = typeFilter === "other";
|
|
124
126
|
const items: StatItem[] = [];
|
|
@@ -132,7 +134,8 @@ function summaryItems(figures: InsiderSummaryFigures, typeFilter: InsiderTypeFil
|
|
|
132
134
|
label,
|
|
133
135
|
value: total.unreconciled ? "Unavailable" : `${formatCompact(total.shares)} shares`,
|
|
134
136
|
detail: [
|
|
135
|
-
total.unreconciled ? "amended" : total.knownValue ?
|
|
137
|
+
total.unreconciled ? "amended" : !total.knownValue ? "value unavailable"
|
|
138
|
+
: currency ? `${formatCompact(total.value)} ${currency}` : `$${formatCompact(total.value)}`,
|
|
136
139
|
securities.size > 1 ? total.security : null,
|
|
137
140
|
hidden ? "not in this view" : null,
|
|
138
141
|
].filter(Boolean).join(" · "),
|
|
@@ -337,7 +340,10 @@ function InsiderTradesView({ ticker, viewBar, state, width, height, focused, sta
|
|
|
337
340
|
const order = new Map(rows.map((row, index) => [row.id, index]));
|
|
338
341
|
return sortStackItems(rows, sort, compareInsiderRows, (a, b) => order.get(a.id)! - order.get(b.id)!);
|
|
339
342
|
}, [rows, sort]);
|
|
340
|
-
|
|
343
|
+
// Form 4 amounts are dollars: a reader whose base currency is another one gets them named, as PF names a holding's.
|
|
344
|
+
const baseCurrency = useAppSelector((state) => state.config.baseCurrency);
|
|
345
|
+
const amountCurrency = baseCurrency.trim().toUpperCase() === FORM4_CURRENCY ? undefined : FORM4_CURRENCY;
|
|
346
|
+
const columns = useMemo(() => buildInsiderColumns(width, rows, amountCurrency), [amountCurrency, rows, width]);
|
|
341
347
|
|
|
342
348
|
// A narrowed list that cannot scroll cannot ask for older filings, so they
|
|
343
349
|
// load here until it fills a page, back to a year at most.
|
|
@@ -358,7 +364,7 @@ function InsiderTradesView({ ticker, viewBar, state, width, height, focused, sta
|
|
|
358
364
|
const lastSummaryRef = useRef<{ scope: string; figures: InsiderSummaryFigures } | null>(null);
|
|
359
365
|
if (summary) lastSummaryRef.current = { scope: summaryScope, figures: summary };
|
|
360
366
|
const shownSummary = summary ?? (lastSummaryRef.current?.scope === summaryScope ? lastSummaryRef.current.figures : null);
|
|
361
|
-
const statItems = useMemo(() => shownSummary ? summaryItems(shownSummary, typeFilter) : [], [shownSummary, typeFilter]);
|
|
367
|
+
const statItems = useMemo(() => shownSummary ? summaryItems(shownSummary, typeFilter, amountCurrency) : [], [amountCurrency, shownSummary, typeFilter]);
|
|
362
368
|
// The totals miss window filings only when the window passes the cap.
|
|
363
369
|
const windowPartial = shownCount < windowCount;
|
|
364
370
|
const insiderOptions = useMemo(() => {
|
|
@@ -483,9 +489,12 @@ function InsiderTradesView({ ticker, viewBar, state, width, height, focused, sta
|
|
|
483
489
|
if (loading && allFilings.length === 0) return underBar(<Spinner label="Loading insider filings..." />);
|
|
484
490
|
if (error && allFilings.length === 0) return underBar(<EmptyState title="Insider filings unavailable." message={error} />);
|
|
485
491
|
if (noOwnFilings) {
|
|
492
|
+
// A company from abroad also says its home market's insider reports are not covered (RY:TSX: SEDI).
|
|
493
|
+
const foreignPrivateIssuer = filesAsForeignPrivateIssuer(allFilings);
|
|
494
|
+
const home = homeInsiderReportsNote({ exchange: abroadVenue, foreignPrivateIssuer });
|
|
486
495
|
return underBar(renderFilingNotice(abroadVenue && allFilings.length === 0
|
|
487
|
-
? noSecReportsNotice({ symbol: parsePublicTickerKey(ticker.metadata.ticker).symbol, exchange: abroadVenue, name: ticker.metadata.name ?? null })
|
|
488
|
-
: insiderEmptyNotice(
|
|
496
|
+
? [noSecReportsNotice({ symbol: parsePublicTickerKey(ticker.metadata.ticker).symbol, exchange: abroadVenue, name: ticker.metadata.name ?? null }), home].filter(Boolean).join(" ")
|
|
497
|
+
: insiderEmptyNotice(foreignPrivateIssuer, home)));
|
|
489
498
|
}
|
|
490
499
|
|
|
491
500
|
// Until a filing is read there is nothing to say; after that the empty
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { SecFilingItem } from "../../../types/data-provider";
|
|
1
|
+
import type { DataProvider, SecFilingItem } from "../../../types/data-provider";
|
|
2
|
+
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
3
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
4
|
+
import { homeInsiderReportsNote, venueHomeCountry } from "../../../utils/sec";
|
|
2
5
|
import { parseForm4IssuerCik } from "./insider-data";
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -40,10 +43,37 @@ export function filesAsForeignPrivateIssuer(filings: readonly SecFilingItem[]):
|
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
45
|
* What the pane, `fn INS` and `insider` say when a company has no Form 4 of
|
|
43
|
-
* its own
|
|
46
|
+
* its own, and beside it, for a company from abroad, that its insiders'
|
|
47
|
+
* reports at home are not covered either (`homeInsiderReportsNote`). Each
|
|
48
|
+
* already names the company above it.
|
|
44
49
|
*/
|
|
45
|
-
export function insiderEmptyNotice(foreignPrivateIssuer: boolean): string {
|
|
46
|
-
|
|
50
|
+
export function insiderEmptyNotice(foreignPrivateIssuer: boolean, home: string | null = null): string {
|
|
51
|
+
const notice = foreignPrivateIssuer
|
|
47
52
|
? "No Form 4 insiders: foreign private issuers file none."
|
|
48
53
|
: "No Form 4 insider filings.";
|
|
54
|
+
return home ? `${notice} ${home}` : notice;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `homeInsiderReportsNote` for a listing with no Form 4 of its own, placed by
|
|
59
|
+
* its company's country where the source knows the company (RY in New York
|
|
60
|
+
* is Royal Bank of Canada), else by its venue abroad (RY:TSX). A lookup that
|
|
61
|
+
* fails leaves the venue to say. A US listing of a company filing as a
|
|
62
|
+
* domestic one has no home market to name, and costs no lookup.
|
|
63
|
+
*/
|
|
64
|
+
export async function loadHomeInsiderReportsNote(
|
|
65
|
+
provider: Pick<DataProvider, "getIssuerListings">,
|
|
66
|
+
key: string,
|
|
67
|
+
exchange: string | undefined,
|
|
68
|
+
foreignPrivateIssuer: boolean,
|
|
69
|
+
): Promise<string | null> {
|
|
70
|
+
const parsed = parsePublicTickerKey(key);
|
|
71
|
+
const venue = parsed.exchange ?? exchange ?? "";
|
|
72
|
+
if (!foreignPrivateIssuer && !venueHomeCountry(venue)) return null;
|
|
73
|
+
const { getIssuerListings } = provider;
|
|
74
|
+
const issuer = getIssuerListings
|
|
75
|
+
? await Promise.resolve().then(() => getIssuerListings.call(provider, parsed.symbol, venue))
|
|
76
|
+
.catch(logFailure("plugins.insider.issuer", "Reading the company's listings failed", null))
|
|
77
|
+
: null;
|
|
78
|
+
return homeInsiderReportsNote({ country: issuer?.country, exchange: venue, foreignPrivateIssuer });
|
|
49
79
|
}
|
|
@@ -60,7 +60,7 @@ function insiderSignalsParams(query: InsiderSignalsQuery, limit: number): CloudI
|
|
|
60
60
|
export const insiderSignalsCache = createPluginCache<InsiderSignalsPayload>({
|
|
61
61
|
kind: "insider-signals",
|
|
62
62
|
source: "gloom-cloud",
|
|
63
|
-
// 2: sides, filters and structured signals
|
|
63
|
+
// 2: sides, filters and structured signals.
|
|
64
64
|
schemaVersion: 2,
|
|
65
65
|
// Filings arrive through the day; the ranking moves with them, not with the market.
|
|
66
66
|
policy: { staleMs: 5 * 60_000, expireMs: 2 * 86_400_000 },
|
|
@@ -109,7 +109,7 @@ export async function loadInsiderSignals(
|
|
|
109
109
|
if (isAccessDenied(error)) throw new Error(CLOUD_SESSION_REQUIRED, { cause: error });
|
|
110
110
|
throw unavailableOnServer(error, INSIDER_SIGNALS_NOT_AVAILABLE);
|
|
111
111
|
}),
|
|
112
|
-
{ force, validate: validateInsiderSignals },
|
|
112
|
+
{ force, validate: validateInsiderSignals, signal },
|
|
113
113
|
);
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -187,7 +187,7 @@ export async function loadInsiderCompany(
|
|
|
187
187
|
if (isAccessDenied(error)) throw new Error(CLOUD_SESSION_REQUIRED, { cause: error });
|
|
188
188
|
throw unavailableOnServer(error, INSIDERS_NOT_AVAILABLE);
|
|
189
189
|
}),
|
|
190
|
-
{ force, validate: companyValidator(query.ticker) },
|
|
190
|
+
{ force, validate: companyValidator(query.ticker), signal },
|
|
191
191
|
)));
|
|
192
192
|
return bothSides(buy!, sell!);
|
|
193
193
|
}
|
|
@@ -95,7 +95,7 @@ export function InsiderSignalsView({ width, height, focused, renderCompany }: In
|
|
|
95
95
|
const colors = useThemeColors();
|
|
96
96
|
const { nativePaneChrome } = useUiCapabilities();
|
|
97
97
|
const session = useResearchCloudSession();
|
|
98
|
-
// Each part of the query is its own pane state, so `
|
|
98
|
+
// Each part of the query is its own pane state, so `gloom shot INS --side sell` and the CLI's options set them one by one.
|
|
99
99
|
const [storedSide, setSide] = usePluginPaneState<InsiderSignalSide>("insider:signals:side", "buy");
|
|
100
100
|
const [storedWindow, setWindow] = usePluginPaneState<number>("insider:signals:window", DEFAULT_INSIDER_SIGNAL_WINDOW);
|
|
101
101
|
const [storedRole, setRole] = usePluginPaneState<InsiderSignalRoleGroup>("insider:signals:role", "all");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataTableColumn } from "../../../components";
|
|
2
|
-
import { displayWidth, formatCompact, formatCurrency } from "../../../utils/format";
|
|
2
|
+
import { displayWidth, formatCompact, formatCurrency, formatNumber } from "../../../utils/format";
|
|
3
3
|
import { isAmendedInsiderFiling } from "./amendments";
|
|
4
4
|
import { insiderSecurityTag, insiderTypeLabel, insiderTypeTone, isOpenMarketTrade, type InsiderTypeTone } from "./display";
|
|
5
5
|
import {
|
|
@@ -10,12 +10,18 @@ import {
|
|
|
10
10
|
type ParsedInsiderFiling,
|
|
11
11
|
} from "./model";
|
|
12
12
|
|
|
13
|
-
export type InsiderColumnId = "date" | "insider" | "role" | "type" | "security" | "shares" | "price" | "value";
|
|
13
|
+
export type InsiderColumnId = "date" | "insider" | "role" | "type" | "security" | "shares" | "price" | "value" | "ccy";
|
|
14
14
|
|
|
15
15
|
export interface InsiderColumn extends DataTableColumn {
|
|
16
16
|
id: InsiderColumnId;
|
|
17
17
|
/** The type column has room for the 10b5-1 marker. */
|
|
18
18
|
plan?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The currency the CCY column names, and that Price and Value are written
|
|
21
|
+
* in without a sign, as PF writes LAST beside CCY. Unset when the amounts
|
|
22
|
+
* keep their $.
|
|
23
|
+
*/
|
|
24
|
+
currency?: string;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
/** One table row: a Form 4 line, or a filing without one (loading, unread, a disclosure). */
|
|
@@ -102,12 +108,21 @@ export function formatInsiderShares(value: number | null): string {
|
|
|
102
108
|
return value == null ? "—" : formatCompact(value);
|
|
103
109
|
}
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
/** A Form 4 price: $412.50, or 412.50 when a CCY column names its currency. */
|
|
112
|
+
export function formatInsiderPrice(value: number | null, currency?: string): string {
|
|
113
|
+
if (value == null) return "—";
|
|
114
|
+
return currency ? formatNumber(value, 2) : formatCurrency(value);
|
|
107
115
|
}
|
|
108
116
|
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
/** A Form 4 value: $1.2M, or 1.2M when a CCY column names its currency. */
|
|
118
|
+
export function formatInsiderValue(value: number | null, currency?: string): string {
|
|
119
|
+
if (value == null) return "—";
|
|
120
|
+
return currency ? formatCompact(value) : `$${formatCompact(value)}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** What a row's CCY cell says: the currency of its price and value, or a dash for a filing without either. */
|
|
124
|
+
export function insiderCurrencyText(row: Pick<InsiderTableRow, "price" | "value">, currency: string): string {
|
|
125
|
+
return row.price == null && row.value == null ? "—" : currency;
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
/** The quieter words after the type: "4/A" always, "10b5-1" when the column has room. */
|
|
@@ -136,9 +151,11 @@ function fitWidth(texts: readonly string[], label: string, max: number): number
|
|
|
136
151
|
* When the pane runs short, the role goes first, then the price, the
|
|
137
152
|
* 10b5-1 marker, the security and the share count, and only then does the name
|
|
138
153
|
* column shrink below 16 cells, so a narrow pane still reads date, name,
|
|
139
|
-
* type and value.
|
|
154
|
+
* type and value. With `currency` (Form 4 amounts read by someone whose base
|
|
155
|
+
* currency is not the dollar), CCY follows Value and is kept with it, as PF
|
|
156
|
+
* shows CCY once a row is in another currency than the totals.
|
|
140
157
|
*/
|
|
141
|
-
export function buildInsiderColumns(width: number, rows: readonly InsiderTableRow[]): InsiderColumn[] {
|
|
158
|
+
export function buildInsiderColumns(width: number, rows: readonly InsiderTableRow[], currency?: string): InsiderColumn[] {
|
|
142
159
|
const anyPlan = rows.some((row) => row.plan);
|
|
143
160
|
const anySecurity = rows.some((row) => row.security);
|
|
144
161
|
const names = rows.map((row) => row.name);
|
|
@@ -150,8 +167,9 @@ export function buildInsiderColumns(width: number, rows: readonly InsiderTableRo
|
|
|
150
167
|
typePlan: fitWidth(rows.map((row) => insiderTypeText(row, true)), "Type", 19),
|
|
151
168
|
security: fitWidth(rows.map((row) => row.security ?? ""), "Security", 12),
|
|
152
169
|
shares: fitWidth(rows.map((row) => formatInsiderShares(row.shares)), "Shares", 9),
|
|
153
|
-
price: fitWidth(rows.map((row) => formatInsiderPrice(row.price)), "Price", 10),
|
|
154
|
-
value: fitWidth(rows.map((row) => formatInsiderValue(row.value)), "Value", 9),
|
|
170
|
+
price: fitWidth(rows.map((row) => formatInsiderPrice(row.price, currency)), "Price", 10),
|
|
171
|
+
value: fitWidth(rows.map((row) => formatInsiderValue(row.value, currency)), "Value", 9),
|
|
172
|
+
ccy: currency ? fitWidth(rows.map((row) => insiderCurrencyText(row, currency)), "CCY", 4) : 0,
|
|
155
173
|
};
|
|
156
174
|
const show = { role: true, price: true, plan: anyPlan, security: anySecurity, shares: true };
|
|
157
175
|
let insider = widths.insider;
|
|
@@ -165,6 +183,7 @@ export function buildInsiderColumns(width: number, rows: readonly InsiderTableRo
|
|
|
165
183
|
show.shares ? widths.shares : 0,
|
|
166
184
|
show.price ? widths.price : 0,
|
|
167
185
|
widths.value,
|
|
186
|
+
widths.ccy,
|
|
168
187
|
].reduce((sum, columnWidth) => sum + (columnWidth > 0 ? columnWidth + COLUMN_GAP : 0), 0);
|
|
169
188
|
const shrinkInsider = (floor: number) => {
|
|
170
189
|
insider = Math.max(Math.min(insider, floor), insider - Math.max(0, total() - available));
|
|
@@ -187,10 +206,11 @@ export function buildInsiderColumns(width: number, rows: readonly InsiderTableRo
|
|
|
187
206
|
{ id: "type", label: "Type", width: typeWidth, align: "left", plan: show.plan },
|
|
188
207
|
...(show.security ? [{ id: "security" as const, label: "Security", width: widths.security, align: "left" as const }] : []),
|
|
189
208
|
...(show.shares ? [{ id: "shares" as const, label: "Shares", width: widths.shares, align: "right" as const }] : []),
|
|
190
|
-
...(show.price ? [{ id: "price" as const, label: "Price", width: widths.price, align: "right" as const }] : []),
|
|
191
|
-
{ id: "value", label: "Value", width: widths.value, align: "right" },
|
|
209
|
+
...(show.price ? [{ id: "price" as const, label: "Price", width: widths.price, align: "right" as const, currency }] : []),
|
|
210
|
+
{ id: "value", label: "Value", width: widths.value, align: "right", currency },
|
|
211
|
+
...(currency ? [{ id: "ccy" as const, label: "CCY", width: widths.ccy, align: "left" as const, currency }] : []),
|
|
192
212
|
];
|
|
193
|
-
// Spare cells spread over the columns, so the
|
|
213
|
+
// Spare cells spread over the columns, so the last column ends at the
|
|
194
214
|
// pane's edge in the terminal as it does on the desktop.
|
|
195
215
|
const used = columns.reduce((sum, column) => sum + column.width + COLUMN_GAP, 0);
|
|
196
216
|
const spare = Math.max(0, available - used);
|
|
@@ -222,5 +242,7 @@ export function compareInsiderRows(a: InsiderTableRow, b: InsiderTableRow, colum
|
|
|
222
242
|
case "shares": return compareNullable(a.shares, b.shares);
|
|
223
243
|
case "price": return compareNullable(a.price, b.price);
|
|
224
244
|
case "value": return compareNullable(a.value, b.value);
|
|
245
|
+
// Every amount is in one currency: rows with one before filings without, as the CCY cells read.
|
|
246
|
+
case "ccy": return Number(a.price == null && a.value == null) - Number(b.price == null && b.value == null);
|
|
225
247
|
}
|
|
226
248
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
formatInsiderPrice,
|
|
10
10
|
formatInsiderShares,
|
|
11
11
|
formatInsiderValue,
|
|
12
|
+
insiderCurrencyText,
|
|
12
13
|
insiderTypeMarkers,
|
|
13
14
|
insiderTypeText,
|
|
14
15
|
type InsiderColumn,
|
|
@@ -72,8 +73,10 @@ export function renderInsiderCell(
|
|
|
72
73
|
case "shares":
|
|
73
74
|
return { text: formatInsiderShares(row.shares), value: row.shares, color: figureColor };
|
|
74
75
|
case "price":
|
|
75
|
-
return { text: formatInsiderPrice(row.price), value: row.price, color: figureColor };
|
|
76
|
+
return { text: formatInsiderPrice(row.price, column.currency), value: row.price, color: figureColor };
|
|
76
77
|
case "value":
|
|
77
|
-
return { text: formatInsiderValue(row.value), value: row.value, color: figureColor };
|
|
78
|
+
return { text: formatInsiderValue(row.value, column.currency), value: row.value, color: figureColor };
|
|
79
|
+
case "ccy":
|
|
80
|
+
return { text: insiderCurrencyText(row, column.currency ?? ""), color: colors.textMuted };
|
|
78
81
|
}
|
|
79
82
|
}
|
|
@@ -19,7 +19,8 @@ import { priceColor, type ThemeColors } from "../../../theme/colors";
|
|
|
19
19
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
20
20
|
import { TICKER_RESEARCH_PANE_ID } from "../../../types/config";
|
|
21
21
|
import type { PaneProps } from "../../../types/plugin";
|
|
22
|
-
import { Box, TextAttributes } from "../../../ui";
|
|
22
|
+
import { Box, TextAttributes, useUiCapabilities } from "../../../ui";
|
|
23
|
+
import { COUNTRY_FLAG_CELLS, withCountryFlag } from "../../../components/ui/country-flag";
|
|
23
24
|
import { isPlainArrowUp, stopSearchFocusNavigation } from "../../../utils/search-focus-navigation";
|
|
24
25
|
import { nextHeaderSort } from "../../../utils/sort-values";
|
|
25
26
|
import { usePluginTickerActions } from "../../runtime";
|
|
@@ -95,7 +96,9 @@ export function IpoCalendarPane({ focused, width, height }: PaneProps) {
|
|
|
95
96
|
// The cursor starts on the first deal, and moves there when its deal leaves the list.
|
|
96
97
|
const selected = rows.find((deal) => deal.id === selectedId) ?? rows[0] ?? null;
|
|
97
98
|
// Sized on the whole board, so switching tabs does not move the columns.
|
|
98
|
-
|
|
99
|
+
// The desktop and the web lead each venue with its country's flag.
|
|
100
|
+
const flagged = useUiCapabilities().nativePaneChrome === true;
|
|
101
|
+
const marketWidth = useMemo(() => marketColumnWidth(deals) + (flagged ? COUNTRY_FLAG_CELLS : 0), [deals, flagged]);
|
|
99
102
|
const columns = useMemo(() => buildIpoColumns(width, marketWidth), [marketWidth, width]);
|
|
100
103
|
|
|
101
104
|
const openDeal = useCallback((deal: IpoDeal) => {
|
|
@@ -155,7 +158,7 @@ export function IpoCalendarPane({ focused, width, height }: PaneProps) {
|
|
|
155
158
|
case "company":
|
|
156
159
|
return { text: deal.company, color: colors.text };
|
|
157
160
|
case "market":
|
|
158
|
-
return { text: deal.venue || deal.mic, color: colors.textDim };
|
|
161
|
+
return withCountryFlag({ text: deal.venue || deal.mic, color: colors.textDim }, deal.country, flagged);
|
|
159
162
|
case "date": {
|
|
160
163
|
// A target date the venue has not set yet reads quieter than a set
|
|
161
164
|
// one, and so does a book's closing day standing in for a listing
|
|
@@ -186,7 +189,7 @@ export function IpoCalendarPane({ focused, width, height }: PaneProps) {
|
|
|
186
189
|
};
|
|
187
190
|
}
|
|
188
191
|
}
|
|
189
|
-
}, [colors, now]);
|
|
192
|
+
}, [colors, flagged, now]);
|
|
190
193
|
|
|
191
194
|
if (!payload) {
|
|
192
195
|
return (
|
|
@@ -87,6 +87,26 @@ export interface IvScreenRow {
|
|
|
87
87
|
latest: IvReading | null;
|
|
88
88
|
skew: { date: string; put25: number; call25: number; skew: number } | null;
|
|
89
89
|
}
|
|
90
|
+
/** Why a name IV history covers has no rank yet, by where its history stands. */
|
|
91
|
+
const IV_COVERAGE_REASONS: Partial<Record<IvCoverageStatus, string>> = {
|
|
92
|
+
queued: "IV history queued, try again in a few minutes",
|
|
93
|
+
backfilling: "IV history still loading",
|
|
94
|
+
unavailable: "no options history",
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Why a screened name has no IV rank, in words for the reader: the server's
|
|
99
|
+
* note for a history too short to rank, or where its history stands. Null when
|
|
100
|
+
* there is nothing true to add, as for a name demand coverage could not take
|
|
101
|
+
* (the row carries the server's queue wording as a warning): none of its
|
|
102
|
+
* history is being collected, so no reason and no promise of one later.
|
|
103
|
+
*/
|
|
104
|
+
export function ivRankReason(row: IvScreenRow | undefined): string | null {
|
|
105
|
+
if (!row) return "no IV history";
|
|
106
|
+
if (row.iv30?.rankNote) return row.iv30.rankNote;
|
|
107
|
+
if (row.warnings?.length) return null;
|
|
108
|
+
return IV_COVERAGE_REASONS[row.coverageStatus ?? row.status] ?? null;
|
|
109
|
+
}
|
|
90
110
|
export interface IvScreenPayload { version: 1; asOf: string; rows: IvScreenRow[] }
|
|
91
111
|
export interface StoredSurfacePayload {
|
|
92
112
|
version: 1;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { getPublishedUsEquityCalendarDay, getPublishedUsEquitySession } from "../../../market-data/published-us-sessions";
|
|
2
|
+
import { zonedDateKey, zonedWallClockToUtcMs } from "../../../utils/zoned-date-time";
|
|
3
|
+
import type { MacroEventKind, MacroRelease } from "../macro-day/releases";
|
|
4
|
+
import type { DatedValue, IvHistoryModel, IvLookback } from "./model";
|
|
5
|
+
|
|
6
|
+
/** One release and the readings a set number of sessions from it. */
|
|
7
|
+
interface ReleaseOffsetRow {
|
|
8
|
+
kind: MacroEventKind;
|
|
9
|
+
/** The release's New York calendar day. */
|
|
10
|
+
releaseDate: string;
|
|
11
|
+
/** Sessions from the release: 0 is the first session on or after its day, -6 the sixth session before that. */
|
|
12
|
+
offset: number;
|
|
13
|
+
/** The session the readings are of. */
|
|
14
|
+
date: string;
|
|
15
|
+
iv30: number | null;
|
|
16
|
+
iv90: number | null;
|
|
17
|
+
iv365: number | null;
|
|
18
|
+
hv: number | null;
|
|
19
|
+
spread: number | null;
|
|
20
|
+
/** 25-delta put IV minus call IV, and the risk reversal, call minus put. */
|
|
21
|
+
skew25d: number | null;
|
|
22
|
+
rr25d: number | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ReleaseOffsets {
|
|
26
|
+
rows: ReleaseOffsetRow[];
|
|
27
|
+
/** Releases whose session at the offset has not closed or has no closing reading yet, oldest first. */
|
|
28
|
+
pending: string[];
|
|
29
|
+
/** Releases inside the stored history whose session at the offset is before the lookback. */
|
|
30
|
+
beforeLookback: number;
|
|
31
|
+
/** Releases before the IV history starts. */
|
|
32
|
+
beforeHistory: number;
|
|
33
|
+
/** The first session of the IV history read, when there is one. */
|
|
34
|
+
historyStart: string | null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const NEW_YORK = "America/New_York";
|
|
38
|
+
const day = (date: Date) => date.toISOString().slice(0, 10);
|
|
39
|
+
const byDay = (points: readonly DatedValue[]) => new Map(points.map((point) => [day(point.date), point.value]));
|
|
40
|
+
const nextDay = (date: string) => new Date(Date.parse(`${date}T00:00:00Z`) + 86_400_000).toISOString().slice(0, 10);
|
|
41
|
+
|
|
42
|
+
/** Whether `date`'s regular session has closed at `now`: an earlier New York day, or today from its close on. */
|
|
43
|
+
function sessionClosed(date: string, now: number): boolean {
|
|
44
|
+
const today = zonedDateKey(now, NEW_YORK);
|
|
45
|
+
if (date !== today) return date < today;
|
|
46
|
+
const session = getPublishedUsEquitySession("NYSE", date);
|
|
47
|
+
const [year, month, dayOfMonth] = date.split("-").map(Number) as [number, number, number];
|
|
48
|
+
return now >= (session?.kind === "session" ? session.close : zonedWallClockToUtcMs(NEW_YORK, year, month, dayOfMonth, 16, 0, 0));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The US equity sessions after `after` through the first on or after `until`; null where the published calendar ends. */
|
|
52
|
+
function calendarSessions(after: string, until: string): string[] | null {
|
|
53
|
+
const sessions: string[] = [];
|
|
54
|
+
for (let date = nextDay(after); ; date = nextDay(date)) {
|
|
55
|
+
const kind = getPublishedUsEquityCalendarDay("NYSE", date);
|
|
56
|
+
if (kind == null) return null;
|
|
57
|
+
if (kind !== "session") continue;
|
|
58
|
+
sessions.push(date);
|
|
59
|
+
if (date >= until) return sessions;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* One row per release of `kind`, with the readings on the session `offset`
|
|
65
|
+
* sessions from it (the "week before FOMC" is `-5` or `-6`), oldest first.
|
|
66
|
+
* Offset 0 is the first session on or after the release day, so a release on
|
|
67
|
+
* a day with no session counts from the next one. Sessions are the history's
|
|
68
|
+
* own, from the first IV reading in the lookback through the last closed
|
|
69
|
+
* session read (`readThrough`, or the last IV reading), and past that the
|
|
70
|
+
* published exchange calendar: an upcoming release whose session at a
|
|
71
|
+
* negative offset has closed and been read gets its row. A release whose
|
|
72
|
+
* session at the offset has not closed or has no reading yet is pending; one
|
|
73
|
+
* whose session falls before the history read is counted, before the lookback
|
|
74
|
+
* or before the history.
|
|
75
|
+
*/
|
|
76
|
+
export function releaseOffsetRows(
|
|
77
|
+
model: Pick<IvHistoryModel, "iv30" | "iv90" | "iv365" | "hv" | "spread" | "skew" | "since">,
|
|
78
|
+
releases: readonly MacroRelease[],
|
|
79
|
+
kind: MacroEventKind,
|
|
80
|
+
offset: number,
|
|
81
|
+
{ lookback = "ALL", readThrough = null, now = Date.now() }: { lookback?: IvLookback; readThrough?: string | null; now?: number } = {},
|
|
82
|
+
): ReleaseOffsets {
|
|
83
|
+
const result: ReleaseOffsets = { rows: [], pending: [], beforeLookback: 0, beforeHistory: 0, historyStart: null };
|
|
84
|
+
// Sessions from the first IV reading on: realized volatility alone, before it or without it, is no IV row.
|
|
85
|
+
const first = model.iv30[0] ? day(model.iv30[0].date) : null;
|
|
86
|
+
if (!first) return result;
|
|
87
|
+
const lastReading = day(model.iv30.at(-1)!.date);
|
|
88
|
+
const through = readThrough && readThrough > lastReading ? readThrough : lastReading;
|
|
89
|
+
// A session counts once it has closed and been read: today's bar before the close, or a session the IV history has not reached, is no reading.
|
|
90
|
+
const known = [...new Set([...model.iv30, ...model.hv].map((point) => day(point.date)))]
|
|
91
|
+
.filter((session) => session >= first && session <= through && sessionClosed(session, now)).sort();
|
|
92
|
+
if (known.length === 0) return result;
|
|
93
|
+
result.historyStart = known[0]!;
|
|
94
|
+
// The lookback cut a longer stored history: a release before it is outside the lookback, not before the history.
|
|
95
|
+
const trimmed = lookback !== "ALL" && model.since != null && model.since < first;
|
|
96
|
+
const before = (release: MacroRelease) => {
|
|
97
|
+
if (trimmed && release.date >= model.since!) result.beforeLookback += 1;
|
|
98
|
+
else result.beforeHistory += 1;
|
|
99
|
+
};
|
|
100
|
+
const iv30 = byDay(model.iv30), iv90 = byDay(model.iv90), iv365 = byDay(model.iv365);
|
|
101
|
+
const hv = byDay(model.hv), spread = byDay(model.spread), skew = byDay(model.skew);
|
|
102
|
+
for (const release of releases) {
|
|
103
|
+
if (release.kind !== kind) continue;
|
|
104
|
+
if (release.date < known[0]!) {
|
|
105
|
+
before(release);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const anchor = known.findIndex((session) => session >= release.date);
|
|
109
|
+
let index: number;
|
|
110
|
+
if (anchor >= 0) index = anchor + offset;
|
|
111
|
+
else {
|
|
112
|
+
// After the last session read: count on through the exchange calendar to the release's own session.
|
|
113
|
+
const ahead = calendarSessions(known.at(-1)!, release.date);
|
|
114
|
+
if (!ahead) {
|
|
115
|
+
result.pending.push(release.date);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
index = known.length + ahead.length - 1 + offset;
|
|
119
|
+
}
|
|
120
|
+
if (index < 0) {
|
|
121
|
+
before(release);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (index >= known.length) {
|
|
125
|
+
result.pending.push(release.date);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const date = known[index]!;
|
|
129
|
+
const skewValue = skew.get(date) ?? null;
|
|
130
|
+
result.rows.push({
|
|
131
|
+
kind, releaseDate: release.date, offset, date,
|
|
132
|
+
iv30: iv30.get(date) ?? null, iv90: iv90.get(date) ?? null, iv365: iv365.get(date) ?? null,
|
|
133
|
+
hv: hv.get(date) ?? null, spread: spread.get(date) ?? null,
|
|
134
|
+
skew25d: skewValue, rr25d: skewValue == null ? null : -skewValue,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** "6 sessions before", "release day", "1 session after". */
|
|
141
|
+
export function offsetText(offset: number): string {
|
|
142
|
+
if (offset === 0) return "release day";
|
|
143
|
+
const sessions = `${Math.abs(offset)} session${Math.abs(offset) === 1 ? "" : "s"}`;
|
|
144
|
+
return offset < 0 ? `${sessions} before` : `${sessions} after`;
|
|
145
|
+
}
|