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
|
@@ -7,6 +7,7 @@ import { barSizeFromGap, medianBarGap } from "../../../time-series/bar-spacing";
|
|
|
7
7
|
import { apiClient } from "../../../api-client";
|
|
8
8
|
import { isPerpetualExchange } from "../../../tickers/perpetual-listing";
|
|
9
9
|
import { CLOUD_NEWS_DELAY_HOURS, hasProAccess } from "../../../api-client/plan-rules";
|
|
10
|
+
import { savedCopyMark } from "../../../data/saved-copies";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Freshness declarations shared by built-in reports. Each `fn` report ends
|
|
@@ -97,6 +98,8 @@ export function quoteFreshnessFields(
|
|
|
97
98
|
// A print older than its venue's latest session says nothing of where that market stands now (no "markets open" beside it).
|
|
98
99
|
const session = !isQuoteBeforeLatestSession(quote, now);
|
|
99
100
|
return {
|
|
101
|
+
// A quote served from its saved copy, its refresh having failed, marks the row drawn from it.
|
|
102
|
+
...savedCopyMark(quote),
|
|
100
103
|
...(quote.dataSource === "live" || quote.dataSource === "delayed" ? { dataSource: quote.dataSource } : {}),
|
|
101
104
|
stale: isQuoteStaleForCurrentSession(quote, now),
|
|
102
105
|
...(delayed ? { delayMinutes: delayedFeedLagMs(exchange) / 60_000 } : {}),
|
|
@@ -13,6 +13,20 @@ export interface ResearchTradeProjection {
|
|
|
13
13
|
contract?: BrokerContractRef;
|
|
14
14
|
mode?: "simulation" | "live" | "unknown";
|
|
15
15
|
busy?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Moves one of `levels` to a price: a draft's price changes in the ticket, and a working order's change
|
|
18
|
+
* opens there for review. Nothing reaches the broker before the ticket's review and confirm.
|
|
19
|
+
*/
|
|
20
|
+
moveLevel?(id: string, value: number): void;
|
|
21
|
+
/** The ticket prices a price picked on the chart can set now; the first is the one picked without a choice. */
|
|
22
|
+
priceFields?: readonly ResearchTradePriceField[];
|
|
23
|
+
/** Sets a ticket price to one picked on the chart. */
|
|
24
|
+
setPrice?(field: string, value: number): void;
|
|
25
|
+
}
|
|
26
|
+
interface ResearchTradePriceField {
|
|
27
|
+
field: string;
|
|
28
|
+
/** As the pick's hint says it: "limit", "stop", "take profit", "stop loss". */
|
|
29
|
+
label: string;
|
|
16
30
|
}
|
|
17
31
|
export interface ResearchTrading extends ResearchTradeProjection {
|
|
18
32
|
symbol: string;
|
|
@@ -25,6 +39,15 @@ export interface ResearchTrading extends ResearchTradeProjection {
|
|
|
25
39
|
/** Opens the ticket; without a side it keeps its draft, and Buy or Sell is chosen in it. */
|
|
26
40
|
open(side?: "BUY" | "SELL"): void;
|
|
27
41
|
close(): void;
|
|
42
|
+
/** A press on the chart takes the keyboard back from the ticket, even a field typing in it. */
|
|
43
|
+
focusChart?(): void;
|
|
44
|
+
/** The ticket price the chart beside it is picking, while it is. */
|
|
45
|
+
picking?: ResearchTradePriceField;
|
|
46
|
+
/** Picks a ticket price on the chart beside it, the first of `priceFields` without a field. */
|
|
47
|
+
pickPrice?(field?: string): void;
|
|
48
|
+
/** Hands the picked price to the ticket, which takes the keyboard back. */
|
|
49
|
+
finishPick?(value: number): void;
|
|
50
|
+
cancelPick?(): void;
|
|
28
51
|
/** This ticker's working orders and latest fills, for Overview; absent without a trading profile. */
|
|
29
52
|
orders?(width: number): ReactNode;
|
|
30
53
|
publish(projection: ResearchTradeProjection): void;
|
|
@@ -4,6 +4,8 @@ import type { PluginPersistence } from "../../../types/plugin";
|
|
|
4
4
|
export interface DatedObservation {
|
|
5
5
|
date: string;
|
|
6
6
|
value: number | null;
|
|
7
|
+
/** The day the value was released, when the source says (FRED's newest monthly figure). */
|
|
8
|
+
releasedOn?: string;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
export interface SeriesCacheMetadata {
|
|
@@ -141,8 +141,9 @@ export function SeriesListDetail<Row, Column extends DataTableColumn, R extends
|
|
|
141
141
|
isNavigable,
|
|
142
142
|
renderSectionHeader,
|
|
143
143
|
emptyStateTitle,
|
|
144
|
+
status,
|
|
144
145
|
renderDetail,
|
|
145
|
-
}: Pick<DataTableViewProps<Row, Column>, "renderCell" | "isNavigable" | "renderSectionHeader" | "emptyStateTitle"> & {
|
|
146
|
+
}: Pick<DataTableViewProps<Row, Column>, "renderCell" | "isNavigable" | "renderSectionHeader" | "emptyStateTitle" | "status"> & {
|
|
146
147
|
list: ReturnType<typeof useSeriesList<unknown, R>>;
|
|
147
148
|
width: number;
|
|
148
149
|
height: number;
|
|
@@ -206,6 +207,7 @@ export function SeriesListDetail<Row, Column extends DataTableColumn, R extends
|
|
|
206
207
|
renderCell={renderCell}
|
|
207
208
|
renderSectionHeader={renderSectionHeader}
|
|
208
209
|
emptyStateTitle={emptyStateTitle}
|
|
210
|
+
status={status}
|
|
209
211
|
/>
|
|
210
212
|
</Box>
|
|
211
213
|
</Box>
|
|
@@ -74,7 +74,8 @@ function normalizeInstanceIdPart(value: string): string {
|
|
|
74
74
|
return encodeURIComponent(value.trim().toUpperCase()).replace(/%/g, "~");
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
/** `short-interest:AAPL`, `ticker-research:GGAL:ADR`: the one window a function keeps for a listing. */
|
|
78
|
+
export function buildTickerSurfaceInstanceId(paneId: string, symbol: string, viewKey?: string): string {
|
|
78
79
|
const parts = [paneId, normalizeInstanceIdPart(symbol)];
|
|
79
80
|
if (viewKey) parts.push(normalizeInstanceIdPart(viewKey));
|
|
80
81
|
return parts.join(":");
|
|
@@ -192,10 +192,11 @@ export function expectedMove(
|
|
|
192
192
|
sigmaPercent: sigma != null && Number.isFinite(sigma) ? sigma / spot * 100 : null, strike: atm?.strike ?? null };
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
/** 25-delta and 90/110 skew in decimal annualized IV; OVDV reads them on each expiry's fitted smile. */
|
|
195
|
+
/** 25-delta and 90/110 skew in decimal annualized IV; OVDV reads them on each expiry's fitted smile, from its forward. */
|
|
196
196
|
export interface SkewMetrics {
|
|
197
197
|
put25: number | null;
|
|
198
198
|
call25: number | null;
|
|
199
|
+
/** IV at the forward (ATMF): the butterfly and the term slope are measured from it. */
|
|
199
200
|
atm: number | null;
|
|
200
201
|
putCallSkew: number | null;
|
|
201
202
|
riskReversal: number | null;
|
|
@@ -21,6 +21,8 @@ function normalizeCloudRecords(payload: CloudShortInterestPayload): ShortInteres
|
|
|
21
21
|
// FINRA publishes no float, so percent of float stays unknown rather than
|
|
22
22
|
// being invented from a float measured on a different date.
|
|
23
23
|
shortPercentFloat: point.shortPercentFloat ?? null,
|
|
24
|
+
...(typeof point.sharesOutstanding === "number" && point.sharesOutstanding > 0
|
|
25
|
+
? { sharesOutstanding: point.sharesOutstanding, sharesOutstandingAsOf: point.sharesOutstandingAsOf ?? null } : {}),
|
|
24
26
|
});
|
|
25
27
|
}
|
|
26
28
|
return records;
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
HeadlessPaneDefinition,
|
|
5
5
|
HeadlessPaneLoadArgs,
|
|
6
6
|
} from "../../../types/plugin";
|
|
7
|
+
import { DATE_OPTION_EXAMPLES, isoDateOption } from "../../../utils/calendar-date";
|
|
7
8
|
import { formatCompact, formatNumber } from "../../../utils/format";
|
|
8
9
|
import type { ShortInterestResult } from "./client";
|
|
9
10
|
import {
|
|
@@ -11,13 +12,15 @@ import {
|
|
|
11
12
|
sortRows,
|
|
12
13
|
type SortPreference,
|
|
13
14
|
} from "./model";
|
|
14
|
-
import { shortInterestFreshness } from "./schedule";
|
|
15
|
+
import { shortInterestFreshness, shortInterestPublished } from "./schedule";
|
|
15
16
|
import type { ShortInterestRecord } from "./types";
|
|
16
17
|
import { loadShortInterestWithFloat } from "./watch-client";
|
|
17
18
|
import { REPORT_ROWS, REPORT_SORT } from "../shared/headless-options";
|
|
18
19
|
|
|
19
20
|
const SHORT_INTEREST_COLUMNS: HeadlessPaneColumn[] = [
|
|
20
21
|
{ key: "settlementDate", header: "Date" },
|
|
22
|
+
// When FINRA published the settlement: what a trader could see that day.
|
|
23
|
+
{ key: "publishedDate", header: "Published" },
|
|
21
24
|
{
|
|
22
25
|
key: "sharesShort",
|
|
23
26
|
header: "Shares Short",
|
|
@@ -42,6 +45,8 @@ const SHORT_INTEREST_COLUMNS: HeadlessPaneColumn[] = [
|
|
|
42
45
|
align: "right",
|
|
43
46
|
format: (value) => value == null ? "-" : `${formatNumber(Number(value), 2)}%`,
|
|
44
47
|
},
|
|
48
|
+
// The day of the share count the float is held within.
|
|
49
|
+
{ key: "floatAsOf", header: "Float As Of", align: "right" },
|
|
45
50
|
];
|
|
46
51
|
|
|
47
52
|
export interface ShortInterestHeadlessDependencies {
|
|
@@ -53,7 +58,11 @@ export interface ShortInterestHeadlessDependencies {
|
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
const defaultDependencies: ShortInterestHeadlessDependencies = {
|
|
56
|
-
loadRecords: (symbol,
|
|
61
|
+
loadRecords: (symbol, args, ctx) => loadShortInterestWithFloat(symbol, {
|
|
62
|
+
marketData: ctx.marketData,
|
|
63
|
+
client: ctx.apiClient,
|
|
64
|
+
pointInTime: typeof args.options.asOf === "string" && args.options.asOf !== "",
|
|
65
|
+
}),
|
|
57
66
|
};
|
|
58
67
|
|
|
59
68
|
export function createShortInterestHeadless(
|
|
@@ -71,7 +80,7 @@ export function createShortInterestHeadless(
|
|
|
71
80
|
discovery: {
|
|
72
81
|
limitations: [
|
|
73
82
|
"Borrow fee, utilization and locate availability are not available: FINRA short interest counts shares short, not what they cost to borrow.",
|
|
74
|
-
"Percent of float is
|
|
83
|
+
"Percent of float is each settlement's shares short over the float of its day: the 10-K or 10-Q share count known when FINRA published it, at the part of today's count that floats; the latest is over the current float. A settlement no count was known for stays blank.",
|
|
75
84
|
],
|
|
76
85
|
},
|
|
77
86
|
usListingsOnly: "FINRA short interest",
|
|
@@ -84,6 +93,13 @@ export function createShortInterestHeadless(
|
|
|
84
93
|
values: [{ value: "newest" }, { value: "oldest" }],
|
|
85
94
|
defaultValue: "newest",
|
|
86
95
|
},
|
|
96
|
+
{
|
|
97
|
+
key: "asOf",
|
|
98
|
+
type: "string",
|
|
99
|
+
placeholder: "date",
|
|
100
|
+
description: `Only the settlements FINRA had published by this date, as ${DATE_OPTION_EXAMPLES}, each on the share count known then.`,
|
|
101
|
+
normalize: (value) => isoDateOption(value, "as-of"),
|
|
102
|
+
},
|
|
87
103
|
{
|
|
88
104
|
key: "limit",
|
|
89
105
|
shot: REPORT_ROWS,
|
|
@@ -109,26 +125,39 @@ export function createShortInterestHeadless(
|
|
|
109
125
|
direction: args.options.order === "oldest" ? "asc" : "desc",
|
|
110
126
|
};
|
|
111
127
|
const limit = Number(args.options.limit);
|
|
112
|
-
const
|
|
128
|
+
const asOf = typeof args.options.asOf === "string" && args.options.asOf ? args.options.asOf : null;
|
|
129
|
+
// A settlement published after the date was not known on it.
|
|
130
|
+
const published = asOf ? buildRows(records).filter((row) => row.publishedDate !== "-" && row.publishedDate <= asOf) : buildRows(records);
|
|
131
|
+
const rows = sortRows(published, preference)
|
|
113
132
|
.slice(0, limit)
|
|
114
133
|
.map((row) => ({
|
|
115
134
|
settlementDate: row.settlementDate,
|
|
135
|
+
publishedDate: row.publishedDate === "-" ? null : row.publishedDate,
|
|
116
136
|
sharesShort: row.record.sharesShort,
|
|
117
137
|
daysToCover: row.record.shortRatio,
|
|
118
138
|
averageDailyVolume: row.record.averageDailyVolume,
|
|
119
139
|
shortPercentFloat: row.record.shortPercentFloat,
|
|
140
|
+
floatAsOf: row.floatAsOf === "-" ? null : row.floatAsOf,
|
|
120
141
|
}));
|
|
121
|
-
const
|
|
142
|
+
const schedule = shortInterestFreshness(rows.map((row) => row.settlementDate).sort().at(-1));
|
|
143
|
+
// A cut at a past date is as current as that date allowed, not stale by today's clock.
|
|
144
|
+
const freshness = schedule && asOf ? { ...schedule, maxAgeMinutes: Number.POSITIVE_INFINITY } : schedule;
|
|
145
|
+
// A date before the history held: say where it starts rather than show nothing.
|
|
146
|
+
const first = records.map((record) => record.settlementDate.toISOString().slice(0, 10)).sort()[0];
|
|
147
|
+
const errors = [
|
|
148
|
+
...(asOf && first && rows.length === 0
|
|
149
|
+
? [`No ${symbol} settlement held was published by ${asOf}: the history starts ${first}, published ${shortInterestPublished(first) ?? "later"}.`]
|
|
150
|
+
: []),
|
|
151
|
+
...(latestSettlements ? [cloudSessionRequired
|
|
152
|
+
? "Full history needs a Gloom Cloud sign-in; showing the latest two settlements."
|
|
153
|
+
: "Full history unavailable; showing the latest two settlements."] : []),
|
|
154
|
+
];
|
|
122
155
|
return {
|
|
123
156
|
rows,
|
|
124
157
|
...(freshness ? { freshness } : {}),
|
|
125
|
-
...(latestSettlements ? {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
? "Full history needs a Gloom Cloud sign-in; showing the latest two settlements."
|
|
129
|
-
: "Full history unavailable; showing the latest two settlements."],
|
|
130
|
-
} : {}),
|
|
131
|
-
metadata: { symbol, order: args.options.order, ...(source ? { source } : {}) },
|
|
158
|
+
...(latestSettlements ? { complete: false } : {}),
|
|
159
|
+
...(errors.length ? { errors } : {}),
|
|
160
|
+
metadata: { symbol, order: args.options.order, ...(asOf ? { asOf } : {}), ...(source ? { source } : {}) },
|
|
132
161
|
};
|
|
133
162
|
},
|
|
134
163
|
};
|
|
@@ -13,6 +13,8 @@ import { SHORT_WATCH_SCOPE_OPTIONS, ShortWatchPane } from "./watch-pane";
|
|
|
13
13
|
import { withCommandTab } from "../shared/command-tab";
|
|
14
14
|
import { followsWithoutFinraOverride, shortVolumeSettings } from "../short-volume";
|
|
15
15
|
import { shortVolumeHeadless } from "../short-volume/headless";
|
|
16
|
+
import { publicationCache } from "./publications-client";
|
|
17
|
+
import { publicationHeadless } from "./publications-headless";
|
|
16
18
|
import { isKnownNonUsListing } from "../../../utils/sec";
|
|
17
19
|
|
|
18
20
|
|
|
@@ -21,6 +23,7 @@ let disposeConnection: (() => void) | null = null;
|
|
|
21
23
|
export const shortInterestModule: PluginModule = {
|
|
22
24
|
series: SHORT_INTEREST_SERIES,
|
|
23
25
|
setup(ctx) {
|
|
26
|
+
publicationCache.attach(ctx.persistence);
|
|
24
27
|
attachShortInterestHealth(ctx.connectionHealth);
|
|
25
28
|
disposeConnection = ctx.connectionHealth.registerSource({
|
|
26
29
|
id: SHORT_INTEREST_CONNECTION_ID,
|
|
@@ -42,6 +45,7 @@ export const shortInterestModule: PluginModule = {
|
|
|
42
45
|
},
|
|
43
46
|
|
|
44
47
|
dispose() {
|
|
48
|
+
publicationCache.reset();
|
|
45
49
|
disposeConnection?.();
|
|
46
50
|
disposeConnection = null;
|
|
47
51
|
resetShortInterestHealth();
|
|
@@ -84,7 +88,7 @@ export const shortInterestModule: PluginModule = {
|
|
|
84
88
|
paneId: "short-interest",
|
|
85
89
|
label: "Short Interest",
|
|
86
90
|
// The current snapshot only carries the current and prior settlement dates.
|
|
87
|
-
description: "Bi-monthly short interest settlements from FINRA with days to cover and average daily volume. Daily volume
|
|
91
|
+
description: "Bi-monthly short interest settlements from FINRA with days to cover and average daily volume. Daily volume, fails to deliver and weekly ATS/OTC volume share the pane.",
|
|
88
92
|
keywords: ["short", "interest", "si", "shorts", "days", "cover"],
|
|
89
93
|
shortcut: "SI",
|
|
90
94
|
}), "interest"),
|
|
@@ -103,6 +107,24 @@ export const shortInterestModule: PluginModule = {
|
|
|
103
107
|
}), "volume"),
|
|
104
108
|
headless: shortVolumeHeadless,
|
|
105
109
|
},
|
|
110
|
+
{
|
|
111
|
+
...withCommandTab(createTickerSurfacePaneTemplate({
|
|
112
|
+
id: "fails-to-deliver-pane", paneId: "short-interest", label: "Fails to Deliver",
|
|
113
|
+
description: "The short interest pane on Fails to deliver: outstanding fail shares by settlement date and CUSIP from SEC publications.",
|
|
114
|
+
keywords: ["fails to deliver", "fails-to-deliver", "ftd", "settlement", "failures", "sec"],
|
|
115
|
+
shortcut: "FTD", publicShare: true,
|
|
116
|
+
}), "ftd"),
|
|
117
|
+
headless: publicationHeadless("ftd"),
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
...withCommandTab(createTickerSurfacePaneTemplate({
|
|
121
|
+
id: "otc-volume-pane", paneId: "short-interest", label: "Weekly ATS / OTC Volume",
|
|
122
|
+
description: "The short interest pane on Weekly ATS/OTC: FINRA weekly ATS and non-ATS shares and trades, including dark-pool volume.",
|
|
123
|
+
keywords: ["dark pool", "dark pools", "ats", "non-ats", "otc", "off-exchange", "weekly", "volume", "finra"],
|
|
124
|
+
shortcut: "ATS", publicShare: true,
|
|
125
|
+
}), "ats"),
|
|
126
|
+
headless: publicationHeadless("ats"),
|
|
127
|
+
},
|
|
106
128
|
{
|
|
107
129
|
id: "short-watch-pane",
|
|
108
130
|
paneId: "short-watch",
|
|
@@ -3,10 +3,13 @@ import { spanDigits } from "../../../components/chart-table";
|
|
|
3
3
|
import type { CompositeAxisDomain } from "../../../components/chart/composite/types";
|
|
4
4
|
import { formatCompact, formatNumber } from "../../../utils/format";
|
|
5
5
|
import { compareSortValues } from "../../../utils/sort-values";
|
|
6
|
+
import { shortInterestPublished } from "./schedule";
|
|
6
7
|
import type { ShortInterestRecord } from "./types";
|
|
7
8
|
|
|
8
9
|
export type ShortInterestColumnId =
|
|
9
10
|
| "settlementDate"
|
|
11
|
+
| "publishedDate"
|
|
12
|
+
| "floatAsOf"
|
|
10
13
|
| "sharesShort"
|
|
11
14
|
| "shortRatio"
|
|
12
15
|
| "averageDailyVolume"
|
|
@@ -18,6 +21,10 @@ export interface ShortInterestRow {
|
|
|
18
21
|
key: string;
|
|
19
22
|
record: ShortInterestRecord;
|
|
20
23
|
settlementDate: string;
|
|
24
|
+
/** When FINRA published the settlement, `YYYY-MM-DD`; `-` when the date is not one. */
|
|
25
|
+
publishedDate: string;
|
|
26
|
+
/** The day of the share count the percent of float is read on; `-` when it is undated or there is none. */
|
|
27
|
+
floatAsOf: string;
|
|
21
28
|
sharesShort: string;
|
|
22
29
|
shortRatio: string;
|
|
23
30
|
averageDailyVolume: string;
|
|
@@ -91,24 +98,50 @@ export function settlementPercentFloat(
|
|
|
91
98
|
return record.shortPercentFloat ?? percentOfFloat(record.sharesShort, floatShares);
|
|
92
99
|
}
|
|
93
100
|
|
|
101
|
+
/** The float a percent of float is read against today, and the share count it floats out of. */
|
|
102
|
+
export interface CurrentFloat {
|
|
103
|
+
floatShares: number | null | undefined;
|
|
104
|
+
/** YYYY-MM-DD the float was counted, when it is dated (the statistics' `floatSharesAsOf`); a source's own float is not. */
|
|
105
|
+
floatAsOf?: string | null;
|
|
106
|
+
/** The share count the float is held within (the statistics' shares outstanding). */
|
|
107
|
+
sharesOutstanding?: number | null;
|
|
108
|
+
statistics?: SettlementFloatStatistics | null;
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
/**
|
|
95
|
-
*
|
|
96
|
-
* against the current float as SIW
|
|
97
|
-
*
|
|
98
|
-
*
|
|
112
|
+
* Each settlement's percent of float where the source gives none. The newest
|
|
113
|
+
* is read against the current float, as SIW and the statistics read it
|
|
114
|
+
* (settlementPercentFloat). An earlier one is read against the float of its
|
|
115
|
+
* own day: the 10-K or 10-Q share count known when FINRA published it
|
|
116
|
+
* (`sharesOutstanding` on the record) times the part of today's count that
|
|
117
|
+
* floats. A settlement without such a count stays blank rather than take
|
|
118
|
+
* today's float. `pointInTime` reads the newest the same way, so a report
|
|
119
|
+
* cut at a date (`--as-of`) uses no count filed after its settlements.
|
|
99
120
|
*/
|
|
100
|
-
export function
|
|
121
|
+
export function withPercentFloat(
|
|
101
122
|
records: readonly ShortInterestRecord[],
|
|
102
|
-
|
|
103
|
-
|
|
123
|
+
current: CurrentFloat,
|
|
124
|
+
{ pointInTime = false }: { pointInTime?: boolean } = {},
|
|
104
125
|
): ShortInterestRecord[] {
|
|
105
|
-
const latest = records.reduce<ShortInterestRecord | null>(
|
|
126
|
+
const latest = pointInTime ? null : records.reduce<ShortInterestRecord | null>(
|
|
106
127
|
(best, record) => (!best || record.settlementDate.getTime() > best.settlementDate.getTime() ? record : best),
|
|
107
128
|
null,
|
|
108
129
|
);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
:
|
|
130
|
+
const { floatShares, sharesOutstanding } = current;
|
|
131
|
+
const floating = finiteNumber(floatShares) && finiteNumber(sharesOutstanding) && floatShares > 0 && sharesOutstanding > 0
|
|
132
|
+
? Math.min(1, floatShares / sharesOutstanding) : null;
|
|
133
|
+
return records.map((record) => {
|
|
134
|
+
if (record === latest) {
|
|
135
|
+
const percent = settlementPercentFloat(record, floatShares, current.statistics);
|
|
136
|
+
return { ...record, shortPercentFloat: percent, floatAsOf: percent != null ? current.floatAsOf ?? null : null };
|
|
137
|
+
}
|
|
138
|
+
if (record.shortPercentFloat != null || floating == null || !finiteNumber(record.sharesOutstanding)) return record;
|
|
139
|
+
return {
|
|
140
|
+
...record,
|
|
141
|
+
shortPercentFloat: percentOfFloat(record.sharesShort, record.sharesOutstanding * floating),
|
|
142
|
+
floatAsOf: record.sharesOutstandingAsOf ?? null,
|
|
143
|
+
};
|
|
144
|
+
});
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
export function buildRows(records: ShortInterestRecord[]): ShortInterestRow[] {
|
|
@@ -116,6 +149,8 @@ export function buildRows(records: ShortInterestRecord[]): ShortInterestRow[] {
|
|
|
116
149
|
key: `${record.settlementDate.toISOString()}:${index}`,
|
|
117
150
|
record,
|
|
118
151
|
settlementDate: formatDate(record.settlementDate),
|
|
152
|
+
publishedDate: shortInterestPublished(formatDate(record.settlementDate)) ?? "-",
|
|
153
|
+
floatAsOf: record.shortPercentFloat != null && record.floatAsOf ? record.floatAsOf : "-",
|
|
119
154
|
sharesShort: formatMaybeCompact(record.sharesShort),
|
|
120
155
|
shortRatio: formatRatio(record.shortRatio),
|
|
121
156
|
averageDailyVolume: formatMaybeCompact(record.averageDailyVolume),
|
|
@@ -127,6 +162,10 @@ function sortValue(row: ShortInterestRow, columnId: ShortInterestColumnId): stri
|
|
|
127
162
|
switch (columnId) {
|
|
128
163
|
case "settlementDate":
|
|
129
164
|
return row.record.settlementDate.getTime();
|
|
165
|
+
case "publishedDate":
|
|
166
|
+
return row.publishedDate === "-" ? null : row.publishedDate;
|
|
167
|
+
case "floatAsOf":
|
|
168
|
+
return row.floatAsOf === "-" ? null : row.floatAsOf;
|
|
130
169
|
case "sharesShort":
|
|
131
170
|
return row.record.sharesShort;
|
|
132
171
|
case "shortRatio":
|
|
@@ -146,28 +185,35 @@ export function sortRows(rows: ShortInterestRow[], preference: SortPreference):
|
|
|
146
185
|
|
|
147
186
|
/**
|
|
148
187
|
* The columns sit together rather than spread across the pane, so the figures
|
|
149
|
-
* of one settlement read as a row
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
188
|
+
* of one settlement read as a row: when it settled, when FINRA published it
|
|
189
|
+
* (what a trader could see that day), then its figures. FINRA settlement
|
|
190
|
+
* history carries no float, so percent of float is null for every row unless
|
|
191
|
+
* it is read against a float (`withPercentFloat`), dated where that float is:
|
|
192
|
+
* an earlier settlement's by the count it is read on. Keeping the column with nothing in it drew a
|
|
193
|
+
* header over a column of dashes, which reads as missing data rather than
|
|
194
|
+
* data the source never had.
|
|
154
195
|
*/
|
|
155
196
|
export function buildColumns(
|
|
156
197
|
records: readonly ShortInterestRecord[] = [],
|
|
157
198
|
): ShortInterestColumn[] {
|
|
158
199
|
const hasPercentFloat = records.some((record) => record.shortPercentFloat != null);
|
|
159
|
-
const
|
|
200
|
+
const hasFloatDate = records.some((record) => record.shortPercentFloat != null && !!record.floatAsOf);
|
|
201
|
+
const dateWidth = 11;
|
|
160
202
|
const sharesWidth = 12;
|
|
161
203
|
const ratioWidth = 12;
|
|
162
|
-
const percentWidth =
|
|
204
|
+
const percentWidth = 9;
|
|
163
205
|
return [
|
|
164
206
|
{ id: "settlementDate", label: "DATE", width: dateWidth, align: "left" },
|
|
207
|
+
{ id: "publishedDate", label: "PUBLISHED", width: dateWidth, align: "left" },
|
|
165
208
|
{ id: "sharesShort", label: "SHARES SHORT", width: sharesWidth, align: "right" },
|
|
166
209
|
{ id: "shortRatio", label: "DAYS TO COVER", width: ratioWidth, align: "right" },
|
|
167
210
|
{ id: "averageDailyVolume", label: "AVG VOL", width: 11, align: "right" },
|
|
168
211
|
...(hasPercentFloat
|
|
169
212
|
? [{ id: "shortPercentFloat" as const, label: "% FLOAT", width: percentWidth, align: "right" as const }]
|
|
170
213
|
: []),
|
|
214
|
+
...(hasFloatDate
|
|
215
|
+
? [{ id: "floatAsOf" as const, label: "FLOAT AS OF", width: dateWidth + 1, align: "right" as const }]
|
|
216
|
+
: []),
|
|
171
217
|
];
|
|
172
218
|
}
|
|
173
219
|
|
|
@@ -202,7 +248,12 @@ export function shortInterestFigures(records: readonly ShortInterestRecord[]): S
|
|
|
202
248
|
return [
|
|
203
249
|
{ id: "shares", label: "Shares short", value: formatMaybeCompact(latest.sharesShort), detail: formatDate(latest.settlementDate) },
|
|
204
250
|
...(latest.shortRatio != null ? [{ id: "days", label: "Days to cover", value: formatRatio(latest.shortRatio) }] : []),
|
|
205
|
-
...(latest.shortPercentFloat != null ? [{
|
|
251
|
+
...(latest.shortPercentFloat != null ? [{
|
|
252
|
+
id: "float",
|
|
253
|
+
label: "% float",
|
|
254
|
+
value: formatPercent(latest.shortPercentFloat),
|
|
255
|
+
...(latest.floatAsOf ? { detail: `as of ${latest.floatAsOf}` } : {}),
|
|
256
|
+
}] : []),
|
|
206
257
|
...(change != null && prior ? [{
|
|
207
258
|
id: "change",
|
|
208
259
|
label: "Change",
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
usePaneFooter,
|
|
13
13
|
type DataTableCell,
|
|
14
14
|
} from "../../../components";
|
|
15
|
+
import { createDataTableCsv } from "../../../components/data-table/export";
|
|
15
16
|
import { loadingErrorFooterInfo, usePaneRefreshKey } from "../../../components/data-table/table-pane";
|
|
17
|
+
import { dropColumnsToFit } from "../../../components/ui/table-layout";
|
|
16
18
|
import { useAsyncResource } from "../../../react/async-resource";
|
|
17
19
|
import { colors } from "../../../theme/colors";
|
|
18
20
|
import { Box, TextAttributes } from "../../../ui";
|
|
@@ -32,11 +34,17 @@ import {
|
|
|
32
34
|
type ShortInterestRow,
|
|
33
35
|
type SortPreference,
|
|
34
36
|
} from "./model";
|
|
37
|
+
import { shortInterestPublicationSegments } from "./schedule";
|
|
35
38
|
import type { ShortInterestRecord } from "./types";
|
|
36
39
|
import { loadShortInterestWithFloat } from "./watch-client";
|
|
37
40
|
import { usePaneTickerIdentity } from "../../../state/hooks/pane-ticker";
|
|
38
41
|
|
|
39
42
|
const EMPTY_RECORDS: ShortInterestRecord[] = [];
|
|
43
|
+
/**
|
|
44
|
+
* A narrow pane gives up the float's date before it scrolls: the figures above
|
|
45
|
+
* the chart date the newest settlement's float, and exports keep the column.
|
|
46
|
+
*/
|
|
47
|
+
const DROP_ORDER = ["floatAsOf"] as const;
|
|
40
48
|
const rowKey = (row: ShortInterestRow) => row.key;
|
|
41
49
|
const rowDate = (row: ShortInterestRow) => row.record.settlementDate;
|
|
42
50
|
|
|
@@ -62,7 +70,8 @@ function ShortInterestView({ width, height, focused }: { width: number; height:
|
|
|
62
70
|
|
|
63
71
|
const rows = useMemo(() => buildRows(records), [records]);
|
|
64
72
|
const sortedRows = useMemo(() => sortRows(rows, sortPreference), [rows, sortPreference]);
|
|
65
|
-
const
|
|
73
|
+
const allColumns = useMemo(() => buildColumns(records), [records]);
|
|
74
|
+
const columns = useMemo(() => dropColumnsToFit(allColumns, width - 1, DROP_ORDER), [allColumns, width]);
|
|
66
75
|
// The header row, plus the scrollbar row once the columns overflow the pane.
|
|
67
76
|
const tableChromeRows = chartTableChromeRows(columns, width);
|
|
68
77
|
const effectiveKey = sortedRows.some((row) => row.key === selectedKey) ? selectedKey : sortedRows[0]?.key ?? null;
|
|
@@ -91,6 +100,8 @@ function ShortInterestView({ width, height, focused }: { width: number; height:
|
|
|
91
100
|
switch (column.id) {
|
|
92
101
|
case "settlementDate":
|
|
93
102
|
return { text: row.settlementDate, color: colors.textDim };
|
|
103
|
+
case "publishedDate":
|
|
104
|
+
return { text: row.publishedDate, color: colors.textDim };
|
|
94
105
|
case "sharesShort":
|
|
95
106
|
return { text: row.sharesShort, color: colors.textBright, attributes: TextAttributes.BOLD };
|
|
96
107
|
case "shortRatio":
|
|
@@ -99,12 +110,17 @@ function ShortInterestView({ width, height, focused }: { width: number; height:
|
|
|
99
110
|
return { text: row.averageDailyVolume, color: colors.textDim };
|
|
100
111
|
case "shortPercentFloat":
|
|
101
112
|
return { text: row.shortPercentFloat, color: colors.text };
|
|
113
|
+
case "floatAsOf":
|
|
114
|
+
return { text: row.floatAsOf, color: colors.textDim };
|
|
102
115
|
}
|
|
103
116
|
}, []);
|
|
104
117
|
|
|
118
|
+
// When the newest settlement shown was published and the next is due, as `fn SI` dates it.
|
|
119
|
+
const latestSettlement = useMemo(() => rows.map((row) => row.settlementDate).sort().at(-1) ?? null, [rows]);
|
|
105
120
|
usePaneFooter("short-interest", () => ({
|
|
106
121
|
info: [
|
|
107
122
|
...loadingErrorFooterInfo(status === "loading", status === "error" ? error?.slice(0, 60) : null),
|
|
123
|
+
...shortInterestPublicationSegments(latestSettlement),
|
|
108
124
|
...(latestSettlements ? [{
|
|
109
125
|
id: "source",
|
|
110
126
|
parts: [{
|
|
@@ -113,7 +129,7 @@ function ShortInterestView({ width, height, focused }: { width: number; height:
|
|
|
113
129
|
}],
|
|
114
130
|
}] : []),
|
|
115
131
|
],
|
|
116
|
-
}), [cloudSessionRequired, error, status, latestSettlements]);
|
|
132
|
+
}), [cloudSessionRequired, error, status, latestSettlements, latestSettlement]);
|
|
117
133
|
|
|
118
134
|
if (!ticker || !symbol) {
|
|
119
135
|
return <EmptyState title="No ticker selected." message="Select a ticker to view short interest." />;
|
|
@@ -150,6 +166,7 @@ function ShortInterestView({ width, height, focused }: { width: number; height:
|
|
|
150
166
|
onHeaderClick={handleHeaderClick}
|
|
151
167
|
getItemKey={rowKey}
|
|
152
168
|
renderCell={renderCell}
|
|
169
|
+
exportCsv={() => createDataTableCsv({ columns: allColumns, items: sortedRows, renderCell })}
|
|
153
170
|
selectedTextOverridesCellColor
|
|
154
171
|
emptyStateTitle="No data"
|
|
155
172
|
/>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { apiClient } from "../../../api-client";
|
|
2
|
+
import type { FailsToDeliverPayload, OtcVolumePayload, ShortSidePublication } from "../../../api-client/short-side-publications";
|
|
3
|
+
import { createPluginCache } from "../../../data/plugin-cache";
|
|
4
|
+
import { cachedCloudResource, loadCloudResource, unavailableOnServer } from "../shared/cloud-resource";
|
|
5
|
+
|
|
6
|
+
export type PublicationKind = "ftd" | "ats";
|
|
7
|
+
export type PublicationPayload = FailsToDeliverPayload | OtcVolumePayload;
|
|
8
|
+
export const publicationCache = createPluginCache<PublicationPayload>({
|
|
9
|
+
kind: "short-side-publications", source: "gloom-cloud", schemaVersion: 2,
|
|
10
|
+
policy: { staleMs: 60 * 60_000, expireMs: 30 * 24 * 60 * 60_000 },
|
|
11
|
+
});
|
|
12
|
+
const date = (value: unknown): value is string => typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)
|
|
13
|
+
&& Number.isFinite(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value;
|
|
14
|
+
const dateOrNull = (value: unknown) => value === null || date(value);
|
|
15
|
+
const count = (value: unknown): value is number => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
16
|
+
const countOrNull = (value: unknown) => value === null || count(value);
|
|
17
|
+
const sharesOrNull = (value: unknown) => value === null || typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= Number.MAX_SAFE_INTEGER;
|
|
18
|
+
const numberOrNull = (value: unknown) => value === null || typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
19
|
+
const url = (value: unknown): value is string => typeof value === "string" && /^https?:\/\//.test(value);
|
|
20
|
+
|
|
21
|
+
function validateEnvelope(payload: ShortSidePublication<unknown>, symbol: string): boolean {
|
|
22
|
+
return !!payload && payload.symbol === symbol && ["available", "partial", "unavailable"].includes(payload.status)
|
|
23
|
+
&& dateOrNull(payload.asOf) && dateOrNull(payload.sourceAsOf)
|
|
24
|
+
&& (payload.loadedAt === null || typeof payload.loadedAt === "string" && Number.isFinite(Date.parse(payload.loadedAt)))
|
|
25
|
+
&& typeof payload.fetchedAt === "string" && Number.isFinite(Date.parse(payload.fetchedAt))
|
|
26
|
+
&& !!payload.source && typeof payload.source.name === "string" && url(payload.source.url) && typeof payload.source.cadence === "string"
|
|
27
|
+
&& Array.isArray(payload.warnings) && payload.warnings.every((warning) => typeof warning === "string")
|
|
28
|
+
&& Array.isArray(payload.history) && !!payload.coverage && date(payload.coverage.from) && date(payload.coverage.to)
|
|
29
|
+
&& payload.coverage.from <= payload.coverage.to && count(payload.coverage.publications)
|
|
30
|
+
&& (payload.history.length > 0 ? payload.status !== "unavailable" && payload.asOf !== null : payload.status === "unavailable" && payload.asOf === null);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Reject mixed symbols, duplicate identities and inconsistent category totals; preserve missing values. */
|
|
34
|
+
export function validatePublication(payload: PublicationPayload, symbol: string, kind: PublicationKind): PublicationPayload {
|
|
35
|
+
const invalid = () => { throw new Error(`The server returned invalid ${kind === "ftd" ? "fails-to-deliver" : "weekly off-exchange volume"} history`); };
|
|
36
|
+
if (!validateEnvelope(payload, symbol)) return invalid();
|
|
37
|
+
let previous = "";
|
|
38
|
+
const identities = new Set<string>();
|
|
39
|
+
for (const row of payload.history) {
|
|
40
|
+
if (!row || !url(row.sourceUrl)) return invalid();
|
|
41
|
+
let observed: string;
|
|
42
|
+
let identity: string;
|
|
43
|
+
if (kind === "ftd") {
|
|
44
|
+
if (!("date" in row) || !date(row.date) || (typeof row.cusip !== "string" || !row.cusip.trim()) || !count(row.quantity)
|
|
45
|
+
|| !numberOrNull(row.price) || typeof row.description !== "string") return invalid();
|
|
46
|
+
observed = row.date;
|
|
47
|
+
identity = `${row.date}:${row.cusip}`;
|
|
48
|
+
} else {
|
|
49
|
+
if (!("weekStart" in row) || !date(row.weekStart) || new Date(row.weekStart).getUTCDay() !== 1
|
|
50
|
+
|| ![row.atsShares, row.nonAtsShares, row.totalShares].every(sharesOrNull)
|
|
51
|
+
|| ![row.atsTrades, row.nonAtsTrades].every(countOrNull)
|
|
52
|
+
|| !numberOrNull(row.atsSharePercent) || row.atsSharePercent !== null && row.atsSharePercent > 100) return invalid();
|
|
53
|
+
const complete = row.atsShares !== null && row.nonAtsShares !== null;
|
|
54
|
+
const total = complete ? row.atsShares! + row.nonAtsShares! : null;
|
|
55
|
+
if (row.totalShares !== total || (!total ? row.atsSharePercent !== null
|
|
56
|
+
: row.atsSharePercent === null || Math.abs(row.atsSharePercent - row.atsShares! / total * 100) > 0.0001)) return invalid();
|
|
57
|
+
observed = row.weekStart;
|
|
58
|
+
identity = observed;
|
|
59
|
+
}
|
|
60
|
+
if (observed < previous || observed < payload.coverage.from || observed > payload.coverage.to || identities.has(identity)) return invalid();
|
|
61
|
+
previous = observed;
|
|
62
|
+
identities.add(identity);
|
|
63
|
+
}
|
|
64
|
+
if (payload.history.length && payload.asOf !== previous) return invalid();
|
|
65
|
+
return payload;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function fetchPublication(symbol: string, kind: PublicationKind,
|
|
69
|
+
client: Pick<typeof apiClient, "getCloudFailsToDeliver" | "getCloudOtcVolume"> = apiClient): Promise<PublicationPayload> {
|
|
70
|
+
try {
|
|
71
|
+
const payload = kind === "ftd" ? await client.getCloudFailsToDeliver(symbol) : await client.getCloudOtcVolume(symbol);
|
|
72
|
+
return validatePublication(payload, symbol, kind);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw unavailableOnServer(error, `${kind === "ftd" ? "Fails to deliver" : "Weekly off-exchange volume"} is not available yet.`, [404, 503]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const cacheKey = (symbol: string, kind: PublicationKind) => `${kind}:${symbol}`;
|
|
78
|
+
export const cachedPublication = (symbol: string, kind: PublicationKind) =>
|
|
79
|
+
cachedCloudResource(publicationCache, cacheKey(symbol, kind), (data) => validatePublication(data, symbol, kind));
|
|
80
|
+
export const loadPublication = (symbol: string, kind: PublicationKind, force = false) =>
|
|
81
|
+
loadCloudResource(publicationCache, cacheKey(symbol, kind), () => fetchPublication(symbol, kind),
|
|
82
|
+
{ force, validate: (data) => validatePublication(data, symbol, kind) });
|