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
package/src/cli/symbol-rows.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { DataProvider } from "../types/data-provider";
|
|
2
2
|
import type { TickerRecord } from "../types/ticker";
|
|
3
|
-
import { listingFields, savedListingName, type ListingChoice } from "./listing-arg";
|
|
3
|
+
import { listingFields, listingVenues, savedListingName, type ListingChoice } from "./listing-arg";
|
|
4
4
|
import { StagedTickerRepository, type TickerSource } from "./staged-tickers";
|
|
5
5
|
import { symbolInputKey } from "./symbol-args";
|
|
6
|
-
import { describeSuggestion, isPlainNoMatch, suggestListings } from "./listing-suggestion";
|
|
6
|
+
import { describeSuggestion, isPlainNoMatch, suggestListings, suggestUsTicker } from "./listing-suggestion";
|
|
7
|
+
import { NotASymbolError } from "./symbol-cells";
|
|
7
8
|
import {
|
|
8
9
|
CoinListingError,
|
|
9
10
|
ListingChoiceError,
|
|
11
|
+
LookupUnansweredError,
|
|
10
12
|
resolveCliTicker,
|
|
11
13
|
resolveTickersForCli,
|
|
12
14
|
TickerNotFoundError,
|
|
@@ -18,16 +20,21 @@ import { isUsSymbolVenue, LOOKUP_TIMEOUT_MS, tickerChangeLine, tickerChangeSymbo
|
|
|
18
20
|
import { isVenueAbroad } from "../tickers/listing-fate";
|
|
19
21
|
import { sameCompany } from "../tickers/company-name";
|
|
20
22
|
import { tickerHasListingSuffix } from "../sources/listing-symbols";
|
|
21
|
-
import { canonicalExchange, resolveExchangeTimeZone } from "../utils/exchanges";
|
|
23
|
+
import { canonicalExchange, exchangeLabel, resolveExchangeTimeZone } from "../utils/exchanges";
|
|
22
24
|
import { isCurrencyPairListing } from "../utils/fx-market-hours";
|
|
25
|
+
import { isCurrencyCode } from "../utils/currency-pair";
|
|
26
|
+
import { logFailure } from "../utils/log-failure";
|
|
23
27
|
|
|
24
28
|
/**
|
|
25
29
|
* What became of one symbol of an add or remove. `needs_choice`: a symbol of
|
|
26
30
|
* an add whose company moved or merged away, whose listing stopped trading, or
|
|
27
31
|
* that matched only a listing abroad; it is not added, and the row offers what
|
|
28
|
-
* to add instead.
|
|
32
|
+
* to add instead. `not_a_symbol`: an entry refused before any lookup (`N/A`,
|
|
33
|
+
* `$$$`, a price). `not_looked_up`: Gloom Cloud kept refusing its lookup, so
|
|
34
|
+
* it is neither found nor missing, and is worth adding again.
|
|
29
35
|
*/
|
|
30
|
-
export type SymbolStatus =
|
|
36
|
+
export type SymbolStatus =
|
|
37
|
+
| "added" | "already_listed" | "removed" | "not_listed" | "not_found" | "needs_choice" | "failed" | "not_a_symbol" | "not_looked_up";
|
|
31
38
|
|
|
32
39
|
/** One symbol's line: the `--json` and `--csv` row, and a line of text. */
|
|
33
40
|
export interface SymbolRow extends Record<string, unknown> {
|
|
@@ -65,6 +72,8 @@ export interface SymbolRow extends Record<string, unknown> {
|
|
|
65
72
|
tradesAs?: string | null;
|
|
66
73
|
/** An added row's line saying that company moved or merged away, so the listing stored is another's. */
|
|
67
74
|
changeNote?: string;
|
|
75
|
+
/** A bare symbol added on its only listing, abroad: "GARAN has no US listing; it trades on BIST, in TRY." */
|
|
76
|
+
abroad?: string;
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
export type Verb = "add" | "remove";
|
|
@@ -91,7 +100,15 @@ export function listingRow(
|
|
|
91
100
|
...readAs ? { readAs } : {}, ...extra };
|
|
92
101
|
}
|
|
93
102
|
|
|
94
|
-
|
|
103
|
+
/** The status a failure gives its row: not found, not a symbol, not looked up, or failed for its own reason. */
|
|
104
|
+
function failureStatus(error: Error): SymbolStatus {
|
|
105
|
+
if (error instanceof TickerNotFoundError) return "not_found";
|
|
106
|
+
if (error instanceof NotASymbolError) return "not_a_symbol";
|
|
107
|
+
if (error instanceof LookupUnansweredError) return "not_looked_up";
|
|
108
|
+
return "failed";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function failedRow(input: string, error: Error, status: SymbolStatus = failureStatus(error)): SymbolRow {
|
|
95
112
|
const hint = error instanceof CoinListingError ? error.hint : null;
|
|
96
113
|
const choice = error instanceof ListingChoiceError
|
|
97
114
|
? { choices: error.choices, listingCount: error.listingCount, ...error.successor ? { successor: error.successor } : {} }
|
|
@@ -156,6 +173,77 @@ function isListedAbroad(ticker: TickerRecord): boolean {
|
|
|
156
173
|
return !isUsSymbolVenue(venue) && !!currency && currency !== "USD";
|
|
157
174
|
}
|
|
158
175
|
|
|
176
|
+
/** A bare US-shaped symbol (JPM, BRK.B), not 7203 or RY.TO, which name a venue of their own. */
|
|
177
|
+
function bareUsShapedSymbol(resolution: Pick<CliTicker, "bareSymbol">): string | null {
|
|
178
|
+
const symbol = resolution.bareSymbol;
|
|
179
|
+
return symbol && tickerChangeSymbol(symbol) && !tickerHasListingSuffix(symbol) ? symbol : null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
type SymbolDeps = { store: TickerSource; dataProvider: DataProvider };
|
|
183
|
+
|
|
184
|
+
const NO_SAVED_ROWS = { loadTicker: async () => null, loadAllTickers: async () => [] };
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Whether a bare symbol also names a US listing: a US company had or has it
|
|
188
|
+
* (its change history: DFS was Discover Financial Services), or it lists on
|
|
189
|
+
* a US venue, by the venues the lookup saw or, when it asked none (a saved
|
|
190
|
+
* row, read with no search), by search now, else by the symbol's own quote,
|
|
191
|
+
* which names its US line first. When neither answers it counts as naming
|
|
192
|
+
* one, so the match stays a choice.
|
|
193
|
+
*/
|
|
194
|
+
async function namesUsListing(resolution: CliTicker, deps: SymbolDeps): Promise<boolean> {
|
|
195
|
+
if (resolution.change || resolution.formerIssuer) return true;
|
|
196
|
+
if (resolution.otherVenues) return resolution.otherVenues.some((venue) => isUsSymbolVenue(venue));
|
|
197
|
+
const symbol = resolution.bareSymbol!;
|
|
198
|
+
// Search's listings, not the saved row it would answer with; none found (or search failed) says nothing.
|
|
199
|
+
const venues = await listingVenues(symbol, { store: NO_SAVED_ROWS, dataProvider: deps.dataProvider })
|
|
200
|
+
.catch(logFailure("cli.symbol-rows", "Read listing venues failed", []));
|
|
201
|
+
if (venues.length > 0) return venues.some((venue) => isUsSymbolVenue(venue.exchange));
|
|
202
|
+
const quote = await deps.dataProvider.getQuote(symbol, "").catch(logFailure("cli.symbol-rows", "Quote bare symbol failed", null));
|
|
203
|
+
const venue = canonicalExchange(quote?.listingExchangeName || quote?.exchangeName);
|
|
204
|
+
return !venue || isUsSymbolVenue(venue);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Whether a bare symbol is stored on its listing abroad, still trading, and
|
|
209
|
+
* that is all it names (`namesUsListing`): GARAN is added on BIST, saying so.
|
|
210
|
+
*/
|
|
211
|
+
async function listedOnlyAbroad(resolution: CliTicker, deps: SymbolDeps): Promise<boolean> {
|
|
212
|
+
if (!bareUsShapedSymbol(resolution) || resolution.ended || !isListedAbroad(resolution.ticker)) return false;
|
|
213
|
+
return !await namesUsListing(resolution, deps);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** "GARAN has no US listing; it trades on BIST, in TRY.": the line an add says beside a symbol `listedOnlyAbroad`. */
|
|
217
|
+
function abroadOnlyNote(resolution: CliTicker): string {
|
|
218
|
+
const { exchange, currency } = resolution.ticker.metadata;
|
|
219
|
+
const unit = currency?.trim();
|
|
220
|
+
return `${resolution.bareSymbol} has no US listing; it trades on ${exchangeLabel(exchange)}${unit ? `, in ${unit}` : ""}.`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* What a bare symbol listed only abroad was more likely typed for: a
|
|
225
|
+
* currency (MXN, mixi Inc in Stuttgart) or a US ticker one slip away (APPL,
|
|
226
|
+
* Aptus Pharma in Mumbai, for AAPL). "APPL is one slip from AAPL (Apple
|
|
227
|
+
* Inc.)" or "MXN is also a currency"; null when the symbol is likely meant as typed.
|
|
228
|
+
*/
|
|
229
|
+
async function meantInstead(symbol: string, deps: SymbolDeps): Promise<string | null> {
|
|
230
|
+
if (symbol !== "USD" && /^[A-Z]{3}$/.test(symbol) && isCurrencyCode(symbol)) return `${symbol} is also a currency`;
|
|
231
|
+
const suggestion = await suggestUsTicker(symbol, deps).catch(logFailure("cli.symbol-rows", "Suggest a US ticker failed", null));
|
|
232
|
+
return suggestion ? `${symbol} is one slip from ${describeSuggestion(suggestion)}` : null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* How a bare symbol matched abroad is settled: `abroad` when it is added
|
|
237
|
+
* there, with its line, or `meant` when it is left for a choice as more
|
|
238
|
+
* likely typed for something else. Both null for anything else, which
|
|
239
|
+
* `choiceNeeded` decides.
|
|
240
|
+
*/
|
|
241
|
+
async function settleAbroad(resolution: CliTicker, deps: SymbolDeps): Promise<{ abroad: string | null; meant: string | null; onlyAbroad: boolean }> {
|
|
242
|
+
if (!await listedOnlyAbroad(resolution, deps)) return { abroad: null, meant: null, onlyAbroad: false };
|
|
243
|
+
const meant = await meantInstead(resolution.bareSymbol!, deps);
|
|
244
|
+
return { abroad: meant ? null : abroadOnlyNote(resolution), meant, onlyAbroad: true };
|
|
245
|
+
}
|
|
246
|
+
|
|
159
247
|
/** Whether a YYYY-MM-DD day is within `ms` before `now`. */
|
|
160
248
|
function within(day: string | null, ms: number, now: number): boolean {
|
|
161
249
|
const at = day ? Date.parse(day.slice(0, 10)) : Number.NaN;
|
|
@@ -164,27 +252,34 @@ function within(day: string | null, ms: number, now: number): boolean {
|
|
|
164
252
|
|
|
165
253
|
/**
|
|
166
254
|
* Why a symbol of an add that named no exchange is not stored as it matched:
|
|
167
|
-
* the listing found stopped trading (NYCB:NYSE), it is a listing abroad
|
|
168
|
-
* Furniture's DFS:LSE for DFS
|
|
255
|
+
* the listing found stopped trading (NYCB:NYSE), it is a listing abroad while
|
|
256
|
+
* the symbol also names a US one (DFS Furniture's DFS:LSE for DFS, Discover's
|
|
257
|
+
* old symbol) or was likely typed for something else (`meantInstead`: APPL
|
|
258
|
+
* for AAPL), or the company that had the symbol left it in
|
|
169
259
|
* the last two years (BRKL, Brookline Bancorp's until 2025, now a fund's). The message
|
|
170
260
|
* leads with what became of the company that held the symbol, when the
|
|
171
261
|
* symbol's history says ("DFS was Discover Financial Services until 2025, now
|
|
172
262
|
* Capital One Financial: COF"), whose symbol now is the successor offered; the
|
|
173
263
|
* match is offered too. Null for a match stored as it is: a trading US
|
|
174
264
|
* listing whose symbol changed hands longer ago (its row says so) or never,
|
|
175
|
-
*
|
|
176
|
-
*
|
|
265
|
+
* a listing abroad that is all the symbol names (GARAN:BIST for GARAN, said
|
|
266
|
+
* with `abroadOnlyNote`), or one whose input named its exchange; coins,
|
|
267
|
+
* perpetual markets and currency pairs, which trade in no one country, too.
|
|
177
268
|
*/
|
|
178
|
-
function choiceNeeded(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
269
|
+
function choiceNeeded(
|
|
270
|
+
resolution: CliTicker,
|
|
271
|
+
{ onlyAbroad, meant }: { onlyAbroad: boolean; meant: string | null },
|
|
272
|
+
now = Date.now(),
|
|
273
|
+
): { message: string; successor: string | null } | null {
|
|
274
|
+
const symbol = bareUsShapedSymbol(resolution);
|
|
275
|
+
if (!symbol) return null;
|
|
182
276
|
const history = successorOf(resolution);
|
|
183
277
|
const label = savedListingName(resolution.ticker).label;
|
|
184
278
|
// A company that left lately: the match is another's, or that company's own line, still quoted.
|
|
185
279
|
const recent = !!history?.successor && within(history.left, RECENT_REUSE_MS, now);
|
|
186
280
|
const found = resolution.ended
|
|
187
|
-
?? (isListedAbroad(resolution.ticker)
|
|
281
|
+
?? (isListedAbroad(resolution.ticker) && (!onlyAbroad || meant)
|
|
282
|
+
? `${symbol} matched ${label}, a listing abroad${meant ? `; ${meant}` : ""}`
|
|
188
283
|
: recent ? `${symbol} matched ${label}, ${sameCompany(resolution.ticker.metadata.name, history?.company) ? "that company's old line" : "another company's listing"}`
|
|
189
284
|
: null);
|
|
190
285
|
if (!found) return null;
|
|
@@ -201,7 +296,9 @@ export const NO_MATCH = /^No ticker match found for /;
|
|
|
201
296
|
* went nowhere are named so the list can be fixed.
|
|
202
297
|
*/
|
|
203
298
|
export function summarizeSymbolRows(rows: readonly SymbolRow[], verb: Verb, repeated: number): string {
|
|
204
|
-
|
|
299
|
+
// An entry that is no symbol, or was not looked up, is named as it was written: `$$$`, `philip morris intl`.
|
|
300
|
+
const inputs = (status: SymbolStatus) => rows.filter((row) => row.status === status)
|
|
301
|
+
.map((row) => status === "not_a_symbol" || status === "not_looked_up" ? row.input.trim() : symbolInputKey(row.input));
|
|
205
302
|
const counts = SETTLED[verb]
|
|
206
303
|
.map(([status, word], index) => ({ count: inputs(status).length, word, index }))
|
|
207
304
|
.filter(({ count, index }) => index === 0 || count > 0)
|
|
@@ -213,6 +310,12 @@ export function summarizeSymbolRows(rows: readonly SymbolRow[], verb: Verb, repe
|
|
|
213
310
|
if (choices.length > 0) groups.push(`${choices.length} need${choices.length === 1 ? "s" : ""} a choice: ${choices.join(", ")}`);
|
|
214
311
|
const failed = inputs("failed");
|
|
215
312
|
if (failed.length > 0) groups.push(`${failed.length} not ${verb === "add" ? "added" : "removed"}: ${failed.join(", ")}`);
|
|
313
|
+
const unanswered = inputs("not_looked_up");
|
|
314
|
+
if (unanswered.length > 0) groups.push(`${unanswered.length} not looked up: ${unanswered.join(", ")}`);
|
|
315
|
+
const junk = inputs("not_a_symbol");
|
|
316
|
+
if (junk.length > 0) {
|
|
317
|
+
groups.push(`${junk.length} not ${junk.length === 1 ? "a symbol" : "symbols"}: ${junk.join(junk.some((input) => input.includes(",")) ? "; " : ", ")}`);
|
|
318
|
+
}
|
|
216
319
|
if (repeated > 0) groups.push(`${repeated} repeat${repeated === 1 ? "" : "s"} skipped`);
|
|
217
320
|
return `${groups.join("; ")}.`;
|
|
218
321
|
}
|
|
@@ -248,6 +351,7 @@ async function settleAdd(
|
|
|
248
351
|
input: string,
|
|
249
352
|
lookup: CliTickerResolution,
|
|
250
353
|
staged: StagedTickerRepository,
|
|
354
|
+
dataProvider: DataProvider,
|
|
251
355
|
add: AddTicker,
|
|
252
356
|
added: Set<string>,
|
|
253
357
|
): Promise<AddOutcome> {
|
|
@@ -258,7 +362,8 @@ async function settleAdd(
|
|
|
258
362
|
? { row: { ...failedRow(input, error, "needs_choice"), tradesAs: error.successor }, error }
|
|
259
363
|
: { row: failedRow(input, error), error };
|
|
260
364
|
}
|
|
261
|
-
const
|
|
365
|
+
const abroad = await settleAbroad(lookup, { store: staged, dataProvider });
|
|
366
|
+
const choice = choiceNeeded(lookup, abroad);
|
|
262
367
|
if (choice) {
|
|
263
368
|
// The lookup saved the listing it matched; one that is in no list of this run is not kept.
|
|
264
369
|
if (!added.has(lookup.ticker.metadata.ticker)) staged.discard(lookup.ticker.metadata.ticker);
|
|
@@ -281,7 +386,7 @@ async function settleAdd(
|
|
|
281
386
|
const history = successorOf(lookup);
|
|
282
387
|
return { row: listingRow(input, result.changed ? "added" : "already_listed", result.ticker, {
|
|
283
388
|
notes: lookup.notes, ended: lookup.ended, hint: lookup.coinNote, readAs: lookup.readAs,
|
|
284
|
-
extra: history ? { changeNote: history.note, tradesAs: history.successor } : {},
|
|
389
|
+
extra: { ...history ? { changeNote: history.note, tradesAs: history.successor } : {}, ...abroad.abroad ? { abroad: abroad.abroad } : {} },
|
|
285
390
|
}), error: null };
|
|
286
391
|
}
|
|
287
392
|
|
|
@@ -337,7 +442,7 @@ export async function addSymbols({
|
|
|
337
442
|
rows.push(failedRow(input, refusal ?? new Error("Not looked up.")));
|
|
338
443
|
continue;
|
|
339
444
|
}
|
|
340
|
-
const { row } = await settleAdd(input, resolution, staged, add, added);
|
|
445
|
+
const { row } = await settleAdd(input, resolution, staged, dataProvider, add, added);
|
|
341
446
|
rows.push(resolution.error && row.status !== "needs_choice" && failure ? failedRow(input, failure(resolution.error)) : row);
|
|
342
447
|
}
|
|
343
448
|
if (!dryRun) await staged.commit();
|
|
@@ -374,15 +479,16 @@ export async function addSymbol(
|
|
|
374
479
|
} catch (caught) {
|
|
375
480
|
lookup = { input, error: caught instanceof Error ? caught : new Error(String(caught)) };
|
|
376
481
|
}
|
|
377
|
-
const outcome = await settleAdd(input, lookup, staged, add, new Set());
|
|
482
|
+
const outcome = await settleAdd(input, lookup, staged, dataProvider, add, new Set());
|
|
378
483
|
if (!dryRun) await staged.commit();
|
|
379
484
|
return { ...outcome, lookup: lookup.error ? null : lookup };
|
|
380
485
|
}
|
|
381
486
|
|
|
382
487
|
/**
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
488
|
+
* How a typed symbol the command bar adds on its own is decided, as a symbol
|
|
489
|
+
* of a pasted list is (`settleAdd`): a needs-choice row when it would not be
|
|
490
|
+
* stored as it matched, else the row it would add, which says when it is
|
|
491
|
+
* listed only abroad; null when nothing was looked up. Nothing is saved.
|
|
386
492
|
*/
|
|
387
493
|
export async function typedSymbolChoice(input: string, store: TickerSource, dataProvider: DataProvider): Promise<SymbolRow | null> {
|
|
388
494
|
const symbol = input.trim().toUpperCase();
|
|
@@ -395,8 +501,8 @@ export async function typedSymbolChoice(input: string, store: TickerSource, data
|
|
|
395
501
|
} catch (caught) {
|
|
396
502
|
lookup = { input: symbol, error: caught instanceof Error ? caught : new Error(String(caught)) };
|
|
397
503
|
}
|
|
398
|
-
const { row } = await settleAdd(symbol, lookup, staged, (ticker) => ({ changed: false, ticker }), new Set());
|
|
399
|
-
return row
|
|
504
|
+
const { row } = await settleAdd(symbol, lookup, staged, dataProvider, (ticker) => ({ changed: false, ticker }), new Set());
|
|
505
|
+
return row;
|
|
400
506
|
}
|
|
401
507
|
|
|
402
508
|
/** The rows, each symbol search found no listing for with the nearest listing it did find, when that is a near match. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logFailure } from "../utils/log-failure";
|
|
2
2
|
import type { DataProvider } from "../types/data-provider";
|
|
3
3
|
import type { Quote } from "../types/financials";
|
|
4
|
+
import type { InstrumentSearchResult } from "../types/instrument";
|
|
4
5
|
import type { TickerRecord } from "../types/ticker";
|
|
5
6
|
import type { AppTickerRepositoryPort } from "../core/app-service-ports";
|
|
6
7
|
import { connectionHealth, GLOOM_CLOUD_HTTP_CONNECTION_ID } from "../core/connection-health";
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
import { canonicalExchange, parsePublicTickerKey } from "../utils/exchanges";
|
|
16
17
|
import {
|
|
17
18
|
chosenListingNote,
|
|
19
|
+
isNoProviderError,
|
|
18
20
|
ListingArgError,
|
|
19
21
|
listingChoiceNote,
|
|
20
22
|
listingReadNotes,
|
|
@@ -25,6 +27,7 @@ import {
|
|
|
25
27
|
quoteBareListing,
|
|
26
28
|
resolveCliListing,
|
|
27
29
|
savedListingName,
|
|
30
|
+
UNLISTED_TYPES,
|
|
28
31
|
type CliListing,
|
|
29
32
|
type ListingChoice,
|
|
30
33
|
type ListingDeps,
|
|
@@ -33,6 +36,7 @@ import { listingChangeLine, loadListingFate, noLongerTradingNote, tradingListing
|
|
|
33
36
|
import {
|
|
34
37
|
describeFormerIssuer,
|
|
35
38
|
describeTickerChange,
|
|
39
|
+
isUsSymbolVenue,
|
|
36
40
|
movedAwayChange,
|
|
37
41
|
LOOKUP_TIMEOUT_MS,
|
|
38
42
|
startTickerChangeLookup,
|
|
@@ -46,6 +50,9 @@ import {
|
|
|
46
50
|
import { batchedListLookups, type ListLookupPlan } from "../tickers/batched-lookups";
|
|
47
51
|
import { providerSearchQueries } from "../tickers/search";
|
|
48
52
|
import { coinElsewhereNote, savedListingCoinNote } from "./commands/crypto-hints";
|
|
53
|
+
import { NotASymbolError, notASymbolError } from "./symbol-cells";
|
|
54
|
+
import { kindFromListingSyntax } from "../tickers/instrument-kind";
|
|
55
|
+
import { normalizeTickerSymbol } from "../tickers/search/ranking";
|
|
49
56
|
|
|
50
57
|
/** The saved ticker for a symbol (`SAN:EPA`, or `SAN` with `--exchange EPA`), saving it from search first if needed. */
|
|
51
58
|
export async function resolveTickerForCli(
|
|
@@ -87,10 +94,18 @@ export interface CliTicker {
|
|
|
87
94
|
* the input named its listing, or a company's name was read as one.
|
|
88
95
|
*/
|
|
89
96
|
bareSymbol: string | null;
|
|
97
|
+
/**
|
|
98
|
+
* The venues other than the stored one the symbol lists on, as far as the
|
|
99
|
+
* lookup saw them: search's, or none when the symbol's own quote named the
|
|
100
|
+
* listing and search was busy. Null when the lookup asked neither (a saved
|
|
101
|
+
* row), so whether a bare symbol matched abroad also names a US listing is
|
|
102
|
+
* still to be asked.
|
|
103
|
+
*/
|
|
104
|
+
otherVenues: string[] | null;
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
export interface CliTickerOptions {
|
|
93
|
-
/** The command that takes one listing, for the choices a failure names: `
|
|
108
|
+
/** The command that takes one listing, for the choices a failure names: `gloom watchlist add Growth 2222:JPX`. */
|
|
94
109
|
retry?: (key: string) => string;
|
|
95
110
|
/** `--exchange` only fills in the symbols that name no exchange of their own, as for a list of symbols. */
|
|
96
111
|
ownExchangeWins?: boolean;
|
|
@@ -159,6 +174,17 @@ export class TickerNotFoundError extends ListingArgError {
|
|
|
159
174
|
}
|
|
160
175
|
}
|
|
161
176
|
|
|
177
|
+
/**
|
|
178
|
+
* A list's symbol Gloom Cloud kept refusing to look up, through every wait:
|
|
179
|
+
* the lookup did not happen, so the symbol is neither found nor missing.
|
|
180
|
+
*/
|
|
181
|
+
export class LookupUnansweredError extends Error {
|
|
182
|
+
constructor(readonly input: string) {
|
|
183
|
+
super(`Could not look up ${input}: Gloom Cloud did not answer. Try again in a minute.`);
|
|
184
|
+
this.name = "LookupUnansweredError";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
162
188
|
/**
|
|
163
189
|
* `resolveTickerForCli`, saying which listing a bare symbol went to. A bare
|
|
164
190
|
* symbol goes where `quote` reads it: the listing its own quote is on, else,
|
|
@@ -166,7 +192,9 @@ export class TickerNotFoundError extends ListingArgError {
|
|
|
166
192
|
* (`quoteBareListing`); a code several companies list asks which. A symbol
|
|
167
193
|
* search no longer lists, whose quote stopped long ago, is no longer trading,
|
|
168
194
|
* and a named exchange the symbol is not on says where it is. Those failures
|
|
169
|
-
* are `ListingArgError`s, with any choices in `details`.
|
|
195
|
+
* are `ListingArgError`s, with any choices in `details`. What cannot be a
|
|
196
|
+
* symbol (`N/A`, `$$$`, a price such as `2.582,52`) fails with
|
|
197
|
+
* `NotASymbolError` before anything is asked.
|
|
170
198
|
*/
|
|
171
199
|
export async function resolveCliTicker(
|
|
172
200
|
symbol: string,
|
|
@@ -178,8 +206,11 @@ export async function resolveCliTicker(
|
|
|
178
206
|
if (!symbol.trim()) {
|
|
179
207
|
throw new Error("Ticker symbol is required.");
|
|
180
208
|
}
|
|
209
|
+
const notSymbol = notASymbolError(symbol);
|
|
210
|
+
if (notSymbol) throw notSymbol;
|
|
181
211
|
const deps: ListingDeps = { store, dataProvider };
|
|
182
|
-
|
|
212
|
+
// A vendor's suffix is the venue it names (GARAN.IS is GARAN:BIST), so the listing is saved under one key.
|
|
213
|
+
const listing = await resolveCliListing(symbol, exchange, deps, { ownExchangeWins: options.ownExchangeWins, listingSuffix: true });
|
|
183
214
|
const read = listingReadNotes(listing);
|
|
184
215
|
// Looked up beside the search, so saying FB is now META costs no wait.
|
|
185
216
|
const changes = options.changes === false ? null : startTickerChangeLookup(dataProvider, listing.symbol, listing.exchange);
|
|
@@ -195,6 +226,20 @@ export async function resolveCliTicker(
|
|
|
195
226
|
const saved = options.refreshName === false ? { ticker: listing.saved, quote: null } : await nameFromListingQuote(listing.saved, store, dataProvider, null);
|
|
196
227
|
return withChange(withEnded(saved, read), { name: saved.ticker.metadata.name });
|
|
197
228
|
}
|
|
229
|
+
// A listing its own quote names is found as `quote` finds it, the quote cache first, so a busy search never
|
|
230
|
+
// blocks a listing the quote knows. Search is asked after, for the venues a note names, and may fail.
|
|
231
|
+
const known = await listingOfOwnQuote(listing, dataProvider);
|
|
232
|
+
if (known) {
|
|
233
|
+
const { ticker, created } = await upsertTickerFromSearchResult(store, known.result);
|
|
234
|
+
const named = created ? await nameFromListingQuote(ticker, store, dataProvider, known.quote) : { ticker, quote: known.quote };
|
|
235
|
+
const saved = savedListingName(named.ticker);
|
|
236
|
+
const venues = listing.exchange ? [] : await listingVenues(listing.symbol, deps).catch(logFailure("cli.ticker-resolution", "Read quoted listing venues failed", []));
|
|
237
|
+
const others = venues.map((venue) => venue.exchange).filter((venue) => venue !== saved.exchange);
|
|
238
|
+
const venueNote = others.length > 0 && saved.exchange
|
|
239
|
+
? listingChoiceNote(listing.symbol, saved, venues) ?? chosenListingNote(listing.symbol, saved.exchange, others)
|
|
240
|
+
: null;
|
|
241
|
+
return withChange({ ticker: named.ticker, notes: [...read, ...venueNote ? [venueNote] : []], ended: null, otherVenues: others }, tradingListing(known.quote));
|
|
242
|
+
}
|
|
198
243
|
|
|
199
244
|
const localTickers = new Map(
|
|
200
245
|
(await store.loadAllTickers()).map((ticker) => [ticker.metadata.ticker.toUpperCase(), ticker] as const),
|
|
@@ -203,6 +248,7 @@ export async function resolveCliTicker(
|
|
|
203
248
|
let resolved: ResolvedTickerSearch | null;
|
|
204
249
|
let bareNote: string | null = null;
|
|
205
250
|
let bareQuote: Quote | null = null;
|
|
251
|
+
let bareVenues: string[] = [];
|
|
206
252
|
try {
|
|
207
253
|
resolved = await search(listing.key);
|
|
208
254
|
} catch (error) {
|
|
@@ -224,6 +270,7 @@ export async function resolveCliTicker(
|
|
|
224
270
|
resolved = await search(bare.listing.key);
|
|
225
271
|
bareNote = bare.note;
|
|
226
272
|
bareQuote = bare.quote;
|
|
273
|
+
bareVenues = error.listings.flatMap((key) => parsePublicTickerKey(key).exchange ?? []).filter((venue) => venue !== bare.listing.exchange);
|
|
227
274
|
}
|
|
228
275
|
|
|
229
276
|
if (!resolved) {
|
|
@@ -238,7 +285,7 @@ export async function resolveCliTicker(
|
|
|
238
285
|
}
|
|
239
286
|
if (resolved.kind === "local") {
|
|
240
287
|
const local = options.refreshName === false ? { ticker: resolved.ticker, quote: null } : await nameFromListingQuote(resolved.ticker, store, dataProvider, bareQuote);
|
|
241
|
-
return withChange(withEnded(local, [...read, ...bareNote ? [bareNote] : []]), { name: local.ticker.metadata.name });
|
|
288
|
+
return withChange({ ...withEnded(local, [...read, ...bareNote ? [bareNote] : []]), otherVenues: bareNote ? bareVenues : null }, { name: local.ticker.metadata.name });
|
|
242
289
|
}
|
|
243
290
|
|
|
244
291
|
const { ticker, created } = await upsertTickerFromSearchResult(store, resolved.result);
|
|
@@ -257,10 +304,50 @@ export async function resolveCliTicker(
|
|
|
257
304
|
ticker: named.ticker,
|
|
258
305
|
notes: [...read, venueNote, ended].filter((note): note is string => !!note),
|
|
259
306
|
ended,
|
|
307
|
+
otherVenues: bareNote ? bareVenues : others,
|
|
260
308
|
}, current);
|
|
261
309
|
}
|
|
262
310
|
|
|
263
|
-
|
|
311
|
+
/**
|
|
312
|
+
* The listing a symbol's own quote names, asked as `quote` asks it (the quote
|
|
313
|
+
* cache first): a priced quote answering for that symbol, on the venue named
|
|
314
|
+
* when one was, that still trades. Null when there is none, and for a pair, a
|
|
315
|
+
* future, an index or a coin, which search types; search then looks it up. So
|
|
316
|
+
* is a named US venue: the US exchanges share one symbol, and a quote asked
|
|
317
|
+
* for on any of them answers as that venue (AAPL:NYSE), where search says
|
|
318
|
+
* AAPL trades on NASDAQ.
|
|
319
|
+
*/
|
|
320
|
+
async function listingOfOwnQuote(listing: CliListing, dataProvider: DataProvider): Promise<{ result: InstrumentSearchResult; quote: Quote } | null> {
|
|
321
|
+
if (listing.sharedCode || kindFromListingSyntax(listing.key, listing.exchange) || (listing.exchange && isUsSymbolVenue(listing.exchange))) return null;
|
|
322
|
+
let quote: Quote;
|
|
323
|
+
try {
|
|
324
|
+
quote = await dataProvider.getQuote(listing.request.symbol, listing.request.exchange);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
// Search then says what is wrong with the symbol.
|
|
327
|
+
if (!isNoProviderError(error)) logFailure("cli.ticker-resolution", "Quote listing before search failed")(error);
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
const exchange = canonicalExchange(quote.listingExchangeName || quote.exchangeName);
|
|
331
|
+
const answered = normalizeTickerSymbol(quote.symbol ?? "");
|
|
332
|
+
if (!exchange || (answered !== listing.symbol && answered !== listing.key)) return null;
|
|
333
|
+
if (listing.exchange && exchange !== listing.exchange) return null;
|
|
334
|
+
if (!Number.isFinite(quote.price) || quote.price === 0 || !(quote.lastUpdated > 0)) return null;
|
|
335
|
+
if (quote.delisting || noLongerTradingNote(listing.key, quote)) return null;
|
|
336
|
+
if (UNLISTED_TYPES.has(quote.instrumentType?.trim().toUpperCase() ?? "")) return null;
|
|
337
|
+
return {
|
|
338
|
+
quote,
|
|
339
|
+
result: {
|
|
340
|
+
providerId: dataProvider.id,
|
|
341
|
+
symbol: listing.symbol,
|
|
342
|
+
name: quote.name?.trim() || listing.symbol,
|
|
343
|
+
exchange,
|
|
344
|
+
...quote.currency ? { currency: quote.currency } : {},
|
|
345
|
+
type: quote.instrumentType || "",
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
type ResolvedListing = Omit<CliTicker, "change" | "formerIssuer" | "coinNote" | "readAs" | "bareSymbol" | "otherVenues"> & { otherVenues?: string[] | null };
|
|
264
351
|
|
|
265
352
|
/**
|
|
266
353
|
* The resolution with the symbol's change, when it has one, and the coin note
|
|
@@ -282,7 +369,7 @@ async function describeResolution(
|
|
|
282
369
|
const line = tickerChangeLine(change) ?? formerIssuer?.note;
|
|
283
370
|
const coinNote = listing.exchange ? null : savedListingCoinNote(listing.symbol, resolved.ticker);
|
|
284
371
|
return { ...resolved, notes: [...line ? [line] : [], ...resolved.notes, ...coinNote ? [coinNote] : []], change, formerIssuer, coinNote,
|
|
285
|
-
readAs: listing.readAs ?? null, bareSymbol: listing.exchange ? null : listing.symbol };
|
|
372
|
+
readAs: listing.readAs ?? null, bareSymbol: listing.exchange ? null : listing.symbol, otherVenues: resolved.otherVenues ?? null };
|
|
286
373
|
}
|
|
287
374
|
|
|
288
375
|
/**
|
|
@@ -368,6 +455,11 @@ function watchFailedRequests(): { count: () => number; stop: () => void } {
|
|
|
368
455
|
return { count: () => failures.size, stop: () => { unsubscribe(); dispose?.(); } };
|
|
369
456
|
}
|
|
370
457
|
|
|
458
|
+
/** Whether a lookup's failure may be the service refusing it, so a new look could answer: not one refused before any request. */
|
|
459
|
+
function mayBeRefusal(error: Error): boolean {
|
|
460
|
+
return !(error instanceof NotASymbolError);
|
|
461
|
+
}
|
|
462
|
+
|
|
371
463
|
function lookUpTickers(
|
|
372
464
|
symbols: readonly string[],
|
|
373
465
|
concurrency: number,
|
|
@@ -389,8 +481,11 @@ function lookUpTickers(
|
|
|
389
481
|
* is searched as it always is.
|
|
390
482
|
*/
|
|
391
483
|
function listLookupPlan(input: string, exchange: string | undefined): ListLookupPlan {
|
|
484
|
+
// What cannot be a symbol is refused without a request.
|
|
485
|
+
if (notASymbolError(input)) return { searches: [], changes: null };
|
|
392
486
|
try {
|
|
393
|
-
|
|
487
|
+
// GARAN.IS names its venue, as GARAN:BIST does: it is looked up as a named listing is.
|
|
488
|
+
const listing = parseListingArg(input, exchange, { ownExchangeWins: true, listingSuffix: true });
|
|
394
489
|
const searchable = !listing.exchange && /^[A-Z0-9][A-Z0-9.-]{0,11}$/.test(listing.symbol);
|
|
395
490
|
return {
|
|
396
491
|
searches: searchable ? providerSearchQueries(listing.symbol) : [],
|
|
@@ -410,7 +505,9 @@ function listLookupPlan(input: string, exchange: string | undefined): ListLookup
|
|
|
410
505
|
* few batched requests first (`batchedListLookups`). "Not found" means search
|
|
411
506
|
* found no listing: while the service refuses requests, the symbols that
|
|
412
507
|
* failed are looked up again after a pause, and any it still did not answer
|
|
413
|
-
* for
|
|
508
|
+
* for fail with `LookupUnansweredError`. One that cannot be a symbol fails
|
|
509
|
+
* with `NotASymbolError` at once: it is never asked for, looked up again or
|
|
510
|
+
* waited for.
|
|
414
511
|
*/
|
|
415
512
|
export async function resolveTickersForCli(
|
|
416
513
|
symbols: readonly string[],
|
|
@@ -448,7 +545,7 @@ export async function resolveTickersForCli(
|
|
|
448
545
|
let lookups = symbols.map((input) => looked.get(input)!);
|
|
449
546
|
let failing = failedRequests.count() > 0;
|
|
450
547
|
for (const waitMs of retryWaitsMs) {
|
|
451
|
-
const failed = lookups.filter((entry) => entry.error).map((entry) => entry.input);
|
|
548
|
+
const failed = lookups.filter((entry) => entry.error && mayBeRefusal(entry.error)).map((entry) => entry.input);
|
|
452
549
|
if (!failing || failed.length === 0) break;
|
|
453
550
|
onRetry?.(failed.length, waitMs);
|
|
454
551
|
await new Promise((resolveWait) => setTimeout(resolveWait, waitMs));
|
|
@@ -459,8 +556,8 @@ export async function resolveTickersForCli(
|
|
|
459
556
|
}
|
|
460
557
|
if (!failing) return lookups;
|
|
461
558
|
// Still refused after the last wait: a failure may only be the refusal, so none is called not found.
|
|
462
|
-
return lookups.map((entry) => entry.error
|
|
463
|
-
? { input: entry.input, error: new
|
|
559
|
+
return lookups.map((entry) => entry.error && mayBeRefusal(entry.error)
|
|
560
|
+
? { input: entry.input, error: new LookupUnansweredError(entry.input) }
|
|
464
561
|
: entry);
|
|
465
562
|
} finally {
|
|
466
563
|
failedRequests.stop();
|
|
@@ -68,18 +68,18 @@ export function treasuryYieldTenor(text: string): TreasuryYieldTenor | null {
|
|
|
68
68
|
/** The commands with the yield: its Cboe index when there is one, its FRED series, the curve. */
|
|
69
69
|
function yieldCommands(tenor: TreasuryYieldTenor): Array<readonly [command: string, gives: string]> {
|
|
70
70
|
return [
|
|
71
|
-
...tenor.index ? [[`
|
|
72
|
-
[`
|
|
73
|
-
["
|
|
71
|
+
...tenor.index ? [[`gloom quote ${tenor.index}`, "Cboe index"] as const] : [],
|
|
72
|
+
[`gloom fred ${tenor.fred}`, "daily"],
|
|
73
|
+
["gloom yield-curve", "every tenor"],
|
|
74
74
|
];
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/** "US 10-year Treasury yield:
|
|
77
|
+
/** "US 10-year Treasury yield: gloom quote ^TNX (Cboe index), ...", for `search`, `catalog` and a bare root. */
|
|
78
78
|
export function treasuryYieldLine(tenor: TreasuryYieldTenor): string {
|
|
79
79
|
return `US ${tenor.label} Treasury yield: ${yieldCommands(tenor).map(([command, gives]) => `${command} (${gives})`).join(", ")}.`;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/** "Try `
|
|
82
|
+
/** "Try `gloom quote ^TNX`, ... for the US 10-year Treasury yield.", after "Not a ticker: US10Y." */
|
|
83
83
|
export function treasuryYieldHint(tenor: TreasuryYieldTenor): string {
|
|
84
84
|
const commands = yieldCommands(tenor).map(([command]) => `\`${command}\``);
|
|
85
85
|
return `Try ${commands.slice(0, -1).join(", ")} or ${commands.at(-1)} for the US ${tenor.label} Treasury yield.`;
|
package/src/cli/types.ts
CHANGED
|
@@ -19,6 +19,8 @@ export type MarketContext = ConfigContext & {
|
|
|
19
19
|
resolveBroker?: (brokerType: string) => import("../types/broker").BrokerAdapter | null;
|
|
20
20
|
/** Charts catalog series in a report run without the plugin runtime. */
|
|
21
21
|
seriesCapabilities?: CapabilityInvoker;
|
|
22
|
+
/** The catalog series charted as an expression (`FRED:DFII10`), in a report run without the plugin runtime. */
|
|
23
|
+
findCatalogSeries?: (expression: string) => import("../series/types").SeriesDefinition | undefined;
|
|
22
24
|
/** `--refresh`: prefetched data bypasses the local cache. */
|
|
23
25
|
refresh?: boolean;
|
|
24
26
|
/** Filings behind the statements and a bank's figures, read from Gloom Cloud; absent where the data service is a stand-in. */
|
|
@@ -14,7 +14,7 @@ const VIX_FUNCTION_INDICES: ReadonlySet<string> = new Set(VOLATILITY_INDICES.map
|
|
|
14
14
|
export function uncoveredInstrumentCommand(instrument: InstrumentOfKind): string {
|
|
15
15
|
const symbol = instrument.symbol;
|
|
16
16
|
const bare = parsePublicTickerKey(symbol).symbol.toUpperCase();
|
|
17
|
-
if (instrument.kind === "index" && VIX_FUNCTION_INDICES.has(bare)) return "
|
|
18
|
-
if (instrument.kind === "fund") return `
|
|
19
|
-
return `
|
|
17
|
+
if (instrument.kind === "index" && VIX_FUNCTION_INDICES.has(bare)) return "gloom fn VIX";
|
|
18
|
+
if (instrument.kind === "fund") return `gloom fundamentals ${symbol}`;
|
|
19
|
+
return `gloom ticker ${symbol}`;
|
|
20
20
|
}
|
|
@@ -22,13 +22,13 @@ function shellWord(arg: string): string {
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* The command that runs `hit` with what the reader typed after the unknown
|
|
25
|
-
* word: their tickers (`
|
|
25
|
+
* word: their tickers (`gloom fn RV DUOL --peers`, the switch added when
|
|
26
26
|
* one symbol meets a function that picks its peers), or the function's
|
|
27
27
|
* placeholder and a search when they typed a company's name.
|
|
28
28
|
*/
|
|
29
29
|
function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { command: string; search: string | null } {
|
|
30
30
|
const typed = args.filter((arg) => arg.trim() && !arg.startsWith("-"));
|
|
31
|
-
const base = `
|
|
31
|
+
const base = `gloom fn ${hit.code}`;
|
|
32
32
|
if (hit.argKind === "none") return { command: base, search: null };
|
|
33
33
|
const placeholder = hit.argPlaceholder ?? hit.argKind;
|
|
34
34
|
if (!hit.argKind || !TICKER_ARGUMENTS.has(hit.argKind)) {
|
|
@@ -39,7 +39,7 @@ function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { c
|
|
|
39
39
|
const single = typed.length === 1;
|
|
40
40
|
const peers = hit.peers && single ? " --peers" : "";
|
|
41
41
|
if (names.length > 0) {
|
|
42
|
-
return { command: `${base} <${single ? "ticker" : placeholder ?? "tickers"}>${peers}`, search: `
|
|
42
|
+
return { command: `${base} <${single ? "ticker" : placeholder ?? "tickers"}>${peers}`, search: `gloom search ${names.map(shellWord).join(" ")}` };
|
|
43
43
|
}
|
|
44
44
|
return { command: `${base} ${typed.length > 0 ? typed.map(shellWord).join(" ") : `<${placeholder ?? "ticker"}>`}${peers}`, search: null };
|
|
45
45
|
}
|
|
@@ -52,14 +52,14 @@ function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { c
|
|
|
52
52
|
const TICKER_SHAPED = /^\^?[A-Z0-9][A-Z0-9.=-]{0,11}(?::[A-Z0-9]{1,8})?$/;
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* What a ticker typed as a command (`
|
|
55
|
+
* What a ticker typed as a command (`gloom PLTR`) is answered with: the
|
|
56
56
|
* command that quotes it and the search that finds it. Null for a word not
|
|
57
57
|
* written as a ticker.
|
|
58
58
|
*/
|
|
59
59
|
export function tickerPointer(token: string): string | null {
|
|
60
60
|
const word = token.trim();
|
|
61
61
|
if (!TICKER_SHAPED.test(word) || !/[A-Z]/.test(word)) return null;
|
|
62
|
-
return [`To quote it:
|
|
62
|
+
return [`To quote it: gloom quote ${word}`, `Find the ticker: gloom search ${word}`].join("\n");
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -71,7 +71,7 @@ export function tickerPointer(token: string): string | null {
|
|
|
71
71
|
export function catalogPointer(token: string, hits: readonly CatalogCommandHit[], args: readonly string[]): string | null {
|
|
72
72
|
if (hits.length === 0) return null;
|
|
73
73
|
const word = /^[\w.:-]+$/.test(token) ? token : JSON.stringify(token);
|
|
74
|
-
const more = `
|
|
74
|
+
const more = `gloom catalog ${word}`;
|
|
75
75
|
if (hits.length === 1) {
|
|
76
76
|
const { command, search } = catalogHitCommand(hits[0]!, args);
|
|
77
77
|
return `Try \`${command}\` (${hits[0]!.label})${search ? `; \`${search}\` finds the ticker` : ""}. \`${more}\` lists more.`;
|