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
|
@@ -108,7 +108,7 @@ export function LayoutShareView({
|
|
|
108
108
|
return (
|
|
109
109
|
<main className="layout-share wide">
|
|
110
110
|
<header>
|
|
111
|
-
<p className="eyebrow">Shared via
|
|
111
|
+
<p className="eyebrow">Shared via Gloom</p>
|
|
112
112
|
<h1>{entry.name}</h1>
|
|
113
113
|
<p className="layout-meta">{[author, date, `${entry.layout.instances.length} panes`].filter(Boolean).join(" · ")}</p>
|
|
114
114
|
</header>
|
|
@@ -126,7 +126,7 @@ export function LayoutShareView({
|
|
|
126
126
|
|
|
127
127
|
<div className="handoff">
|
|
128
128
|
<a className="cta" href={openLiveUrl}>Use this layout</a>
|
|
129
|
-
<p className="descriptor">Opens in
|
|
129
|
+
<p className="descriptor">Opens in Gloom as an independent, editable copy.</p>
|
|
130
130
|
</div>
|
|
131
131
|
</main>
|
|
132
132
|
);
|
|
@@ -40,7 +40,7 @@ function LayoutApp({ id }: { id: string }) {
|
|
|
40
40
|
|
|
41
41
|
return state.entry
|
|
42
42
|
? <LayoutShareView entry={state.entry} openLiveUrl={openLiveMarketplaceLayoutUrl(id)} />
|
|
43
|
-
: <main><h1>
|
|
43
|
+
: <main><h1>Gloom</h1><p>{state.error ?? "Loading shared layout..."}</p></main>;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function ContentShareApp({ id }: { id: string }) {
|
|
@@ -91,18 +91,18 @@ function ContentShareApp({ id }: { id: string }) {
|
|
|
91
91
|
/>
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
|
-
return <main><h1>
|
|
94
|
+
return <main><h1>Gloom</h1><p>{state.error ?? "Loading shared view..."}</p></main>;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
function SocialShareApp() {
|
|
98
98
|
const pathname = window.location.pathname;
|
|
99
99
|
const layoutId = parseMarketplaceLayoutId(pathname);
|
|
100
100
|
if (layoutId) return <LayoutApp id={layoutId} />;
|
|
101
|
-
if (pathname.startsWith("/l/")) return <main><h1>
|
|
101
|
+
if (pathname.startsWith("/l/")) return <main><h1>Gloom</h1><p>Invalid layout link.</p></main>;
|
|
102
102
|
const shareId = parseShareId(pathname);
|
|
103
103
|
return shareId
|
|
104
104
|
? <ContentShareApp id={shareId} />
|
|
105
|
-
: <main><h1>
|
|
105
|
+
: <main><h1>Gloom</h1><p>Invalid share link.</p></main>;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
const root = document.getElementById("root");
|
|
@@ -89,7 +89,7 @@ export function ShareView({
|
|
|
89
89
|
return (
|
|
90
90
|
<main className="pane">
|
|
91
91
|
<header>
|
|
92
|
-
<p className="eyebrow">Shared via
|
|
92
|
+
<p className="eyebrow">Shared via Gloom</p>
|
|
93
93
|
<h1>{share.data.title}</h1>
|
|
94
94
|
{share.data.description ? <p className="pane-description">{share.data.description}</p> : null}
|
|
95
95
|
</header>
|
package/src/series/resolve.ts
CHANGED
|
@@ -6,7 +6,8 @@ import type {
|
|
|
6
6
|
SeriesPeriod,
|
|
7
7
|
TimeSeriesPoint,
|
|
8
8
|
} from "../time-series/types";
|
|
9
|
-
import { getPresetResolution,
|
|
9
|
+
import { chartBarSizeSource, getPresetResolution, isCustomChartResolution } from "../time-series/resolution";
|
|
10
|
+
import { futuresSessionOpenMinute } from "../market-data/market/trading-sessions";
|
|
10
11
|
import { SERIES_COLORS } from "../theme/series-colors";
|
|
11
12
|
import type {
|
|
12
13
|
LoadedSeriesDefinition,
|
|
@@ -74,9 +75,24 @@ function seriesColor(id: string, lineIndex = 0): string {
|
|
|
74
75
|
return SERIES_COLORS[(hash + lineIndex) % SERIES_COLORS.length]!;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The bars a chart draws prices in, as a load request states them: the bar
|
|
80
|
+
* size it was set to, else its range's default. A size the source does not
|
|
81
|
+
* serve (4h) goes as the source bars it is built from (`resolution: 1h`) and
|
|
82
|
+
* the size itself (`barSize: 4h`), so a series that knows only the source
|
|
83
|
+
* sizes still gets one it knows.
|
|
84
|
+
*/
|
|
85
|
+
function viewportBars(viewport: ChartViewportSpec, ticker: string | undefined): Pick<SeriesLoadRequest, "resolution" | "barSize"> {
|
|
86
|
+
if (viewport.resolution === "auto") return { resolution: getPresetResolution(viewport.range) };
|
|
87
|
+
if (!isCustomChartResolution(viewport.resolution)) return { resolution: viewport.resolution };
|
|
88
|
+
const openMinute = ticker ? futuresSessionOpenMinute(splitTicker(ticker).symbol, splitTicker(ticker).exchange) : null;
|
|
89
|
+
return { resolution: chartBarSizeSource(viewport.resolution, [], openMinute), barSize: viewport.resolution };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** `NESN:XSWX` as its symbol and listing. */
|
|
93
|
+
function splitTicker(ticker: string): { symbol: string; exchange: string } {
|
|
94
|
+
const colon = ticker.lastIndexOf(":");
|
|
95
|
+
return colon > 0 ? { symbol: ticker.slice(0, colon), exchange: ticker.slice(colon + 1) } : { symbol: ticker, exchange: "" };
|
|
80
96
|
}
|
|
81
97
|
|
|
82
98
|
/** The dates a chart viewport covers, as a series load request takes them. */
|
|
@@ -133,7 +149,7 @@ function loadSeries(definition: LoadedSeriesDefinition, request: SeriesLoadReque
|
|
|
133
149
|
if (signal?.aborted) return Promise.reject(signal.reason);
|
|
134
150
|
// A window measured back from now moves by milliseconds between the lines' requests.
|
|
135
151
|
const minute = (date: Date | undefined) => date ? Math.floor(date.getTime() / 60_000) : null;
|
|
136
|
-
const key = JSON.stringify([shared.ticker ?? null, minute(shared.start), minute(shared.end), shared.resolution ?? null]);
|
|
152
|
+
const key = JSON.stringify([shared.ticker ?? null, minute(shared.start), minute(shared.end), shared.resolution ?? null, shared.barSize ?? null]);
|
|
137
153
|
let byKey = sharedLoads.get(definition);
|
|
138
154
|
if (!byKey) sharedLoads.set(definition, byKey = new Map());
|
|
139
155
|
let load = byKey.get(key);
|
|
@@ -182,7 +198,7 @@ export async function resolveLoadedSeries(
|
|
|
182
198
|
const { points, edge, warning, attribution } = loadResult(await loadSeries(definition, {
|
|
183
199
|
...seriesLoadWindow(request.viewport, now),
|
|
184
200
|
...(ticker ? { ticker } : {}),
|
|
185
|
-
|
|
201
|
+
...viewportBars(request.viewport, ticker),
|
|
186
202
|
...(request.signal ? { signal: request.signal } : {}),
|
|
187
203
|
}), line);
|
|
188
204
|
const seriesId = ticker ? `${definition.id}/${ticker}` : definition.id;
|
package/src/series/standalone.ts
CHANGED
|
@@ -4,11 +4,12 @@ import type { CapabilityInvoker } from "../capabilities/types";
|
|
|
4
4
|
import type { GloomPlugin } from "../types/plugin";
|
|
5
5
|
import { resolveRegisteredSeries } from "./capability";
|
|
6
6
|
import { readSeriesFolder } from "./files";
|
|
7
|
-
import { SeriesRegistry } from "./registry";
|
|
7
|
+
import { SeriesRegistry, seriesExpression } from "./registry";
|
|
8
|
+
import type { SeriesDefinition } from "./types";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Charts the catalog's loaded series where no plugin runtime runs, such as a
|
|
11
|
-
* `
|
|
12
|
+
* `gloom fn G` report: the series plugins declare, and the files in the
|
|
12
13
|
* data directory's series folder. Series a plugin registers from its setup
|
|
13
14
|
* need the app.
|
|
14
15
|
*/
|
|
@@ -47,3 +48,30 @@ export function standaloneSeriesInvoker(
|
|
|
47
48
|
},
|
|
48
49
|
};
|
|
49
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The plugins' catalog series by what `fn G` charts each as (`FRED:DFII10`),
|
|
54
|
+
* where no plugin runtime runs: a series with an input (a ticker's field) is
|
|
55
|
+
* no one expression. The first plugin to declare an expression keeps it, as
|
|
56
|
+
* the registry's `findByExpression` does.
|
|
57
|
+
*/
|
|
58
|
+
export function standaloneSeriesCatalog(
|
|
59
|
+
plugins: readonly GloomPlugin[],
|
|
60
|
+
disabledPlugins: readonly string[] = [],
|
|
61
|
+
): (expression: string) => SeriesDefinition | undefined {
|
|
62
|
+
let byExpression: Map<string, SeriesDefinition> | null = null;
|
|
63
|
+
return (expression) => {
|
|
64
|
+
if (!byExpression) {
|
|
65
|
+
byExpression = new Map();
|
|
66
|
+
for (const plugin of plugins) {
|
|
67
|
+
if (disabledPlugins.includes(plugin.id)) continue;
|
|
68
|
+
for (const definition of plugin.series ?? []) {
|
|
69
|
+
if (definition.input) continue;
|
|
70
|
+
const key = seriesExpression(definition);
|
|
71
|
+
if (!byExpression.has(key)) byExpression.set(key, definition);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return byExpression.get(expression);
|
|
76
|
+
};
|
|
77
|
+
}
|
package/src/series/types.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* either loads its own history (`load`) or points at something the composer
|
|
7
7
|
* already draws (`expression`), such as a FRED series or a ticker field.
|
|
8
8
|
*/
|
|
9
|
-
import type { ManualChartResolution } from "../time-series/resolution";
|
|
9
|
+
import type { ChartBarSize, ManualChartResolution } from "../time-series/resolution";
|
|
10
10
|
|
|
11
11
|
/** How often a series gets a new observation. */
|
|
12
12
|
export type SeriesFrequency =
|
|
@@ -72,6 +72,13 @@ export interface SeriesLoadRequest {
|
|
|
72
72
|
* bars uses it to compute on the same bars.
|
|
73
73
|
*/
|
|
74
74
|
resolution?: ManualChartResolution;
|
|
75
|
+
/**
|
|
76
|
+
* Set when the chart builds its bars from `resolution` bars rather than
|
|
77
|
+
* drawing those (`4h` from `1h`, `2d` from `1d`): the bar size it draws. A
|
|
78
|
+
* series computed from a ticker's bars builds them the same way with
|
|
79
|
+
* `aggregatePriceBars`, so its points fall on the chart's bars.
|
|
80
|
+
*/
|
|
81
|
+
barSize?: ChartBarSize;
|
|
75
82
|
signal?: AbortSignal;
|
|
76
83
|
}
|
|
77
84
|
|
package/src/shares/api.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiRequestError } from "../api-client/errors";
|
|
2
|
+
import { DataServiceUnreachableError } from "../utils/network-failure";
|
|
2
3
|
import { parseSharePayload, type SharePayload } from "./payload";
|
|
3
4
|
|
|
4
5
|
declare const __GLOOMBERB_API_URL__: string | undefined;
|
|
@@ -36,11 +37,13 @@ function validDate(value: unknown): value is string {
|
|
|
36
37
|
* A request that never got an answer, in the words of whichever fetch made
|
|
37
38
|
* it: a browser's ("Failed to fetch", Safari's "Load failed", Firefox's
|
|
38
39
|
* "NetworkError ..."), Bun's ("Unable to connect ...", which the desktop
|
|
39
|
-
* relays from its Bun process as a plain message),
|
|
40
|
+
* relays from its Bun process as a plain message), the Cloud client's
|
|
41
|
+
* `DataServiceUnreachableError` for any of them, or a timeout.
|
|
40
42
|
*/
|
|
41
43
|
const NETWORK_FAILURE = /failed to fetch|load failed|networkerror|network connection was lost|appears to be offline|fetch failed|unable to connect|socket connection was closed|typo in the url or port|timed out/i;
|
|
42
44
|
|
|
43
45
|
function isNetworkFailure(error: unknown): boolean {
|
|
46
|
+
if (error instanceof DataServiceUnreachableError) return true;
|
|
44
47
|
if (!error || typeof error !== "object") return false;
|
|
45
48
|
const { name, message } = error as { name?: unknown; message?: unknown };
|
|
46
49
|
return name === "AbortError" || name === "TimeoutError" || (typeof message === "string" && NETWORK_FAILURE.test(message));
|
package/src/shares/pane.ts
CHANGED
|
@@ -53,7 +53,7 @@ export async function openPaneShare(
|
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
const template = pluginRegistry.paneTemplates.get(share.templateId);
|
|
56
|
-
if (!template?.publicShare) throw new Error("This shared pane is unavailable in this version of
|
|
56
|
+
if (!template?.publicShare) throw new Error("This shared pane is unavailable in this version of Gloom.");
|
|
57
57
|
const options = template.publicShare.restore(share.data);
|
|
58
58
|
if (!options) throw new Error("This shared pane contains invalid settings.");
|
|
59
59
|
await pluginRegistry.createPaneFromTemplateAsync(template.id, options);
|
|
@@ -68,21 +68,66 @@ const TURKISH_CPI: SeriesNotOnFred = {
|
|
|
68
68
|
url: "https://www.tcmb.gov.tr/wps/wcm/connect/EN/TCMB+EN/Main+Menu/Statistics/Inflation+Data/Consumer+Prices",
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
/** IBGE's IPCA (433) and IPCA-15 (7478), as the central bank's SGS republishes them. */
|
|
72
|
+
const brazilianCpi = (code: number): SeriesNotOnFred => ({
|
|
73
|
+
publisher: "IBGE",
|
|
74
|
+
via: "the Banco Central do Brasil's SGS",
|
|
75
|
+
url: `https://www3.bcb.gov.br/sgspub/consultarvalores/telaCvsSelecionarSeries.paint?codigoSerie=${code}`,
|
|
76
|
+
});
|
|
77
|
+
|
|
71
78
|
const NOT_ON_FRED: Readonly<Record<string, SeriesNotOnFred>> = {
|
|
72
79
|
TURCPIYOY: TURKISH_CPI,
|
|
73
80
|
TURCPIMOM: TURKISH_CPI,
|
|
81
|
+
BRAIPCAMOM: brazilianCpi(433),
|
|
82
|
+
BRAIPCA15MOM: brazilianCpi(7478),
|
|
83
|
+
// NAHB's builder sentiment index as first released, from the economic calendar's actuals.
|
|
84
|
+
NAHBHMI: {
|
|
85
|
+
publisher: "NAHB",
|
|
86
|
+
via: "the economic calendar",
|
|
87
|
+
url: "https://www.nahb.org/news-and-economics/housing-economics/indices/housing-market-index",
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** A series Gloom Cloud computes from two of FRED's, the first less the second, and how. */
|
|
92
|
+
interface ComputedFromFred {
|
|
93
|
+
legs: readonly [string, string];
|
|
94
|
+
note: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const COMPUTED_FROM_FRED: Readonly<Record<string, ComputedFromFred>> = {
|
|
98
|
+
MORTGAGE30US10Y: {
|
|
99
|
+
legs: ["MORTGAGE30US", "DGS10"],
|
|
100
|
+
note: "MORTGAGE30US minus DGS10 on each Freddie Mac PMMS date; when the Treasury market is closed that day, the 10-year yield of the session before.",
|
|
101
|
+
},
|
|
74
102
|
};
|
|
75
103
|
|
|
104
|
+
/** How a series Gloom Cloud computes from FRED's is computed, for the note under its table; null for any other. */
|
|
105
|
+
export function computedFredSeriesNote(seriesId: string): string | null {
|
|
106
|
+
return COMPUTED_FROM_FRED[seriesId.trim().toUpperCase()]?.note ?? null;
|
|
107
|
+
}
|
|
108
|
+
|
|
76
109
|
/** The publisher of a served series FRED does not carry; null for FRED's own. */
|
|
77
110
|
export function seriesNotOnFred(seriesId: string): SeriesNotOnFred | null {
|
|
78
111
|
return NOT_ON_FRED[seriesId.trim().toUpperCase()] ?? null;
|
|
79
112
|
}
|
|
80
113
|
|
|
81
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* The series' page on the FRED site, where its notes and release schedule
|
|
116
|
+
* live; FRED's graph of both legs for a series computed from two; its
|
|
117
|
+
* publisher's page when FRED does not carry it.
|
|
118
|
+
*/
|
|
82
119
|
export function fredSeriesUrl(seriesId: string): string {
|
|
120
|
+
const legs = COMPUTED_FROM_FRED[seriesId.trim().toUpperCase()]?.legs;
|
|
121
|
+
if (legs) return `https://fred.stlouisfed.org/graph/?id=${legs.join(",")}`;
|
|
83
122
|
return seriesNotOnFred(seriesId)?.url ?? `https://fred.stlouisfed.org/series/${seriesId}`;
|
|
84
123
|
}
|
|
85
124
|
|
|
125
|
+
/** What a source line names a series by: `FRED DGS10`, or the FRED series a computed one comes from (`FRED MORTGAGE30US minus DGS10`). */
|
|
126
|
+
export function fredSourceLabel(seriesId: string): string {
|
|
127
|
+
const legs = COMPUTED_FROM_FRED[seriesId.trim().toUpperCase()]?.legs;
|
|
128
|
+
return `FRED ${legs ? legs.join(" minus ") : seriesId}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
86
131
|
function cacheKey(request: FredSeriesRequest): string {
|
|
87
132
|
const range = [
|
|
88
133
|
request.startDate ? `start=${request.startDate}` : "",
|
|
@@ -30,6 +30,7 @@ import { parseHistorySession } from "../../market-data/history-session";
|
|
|
30
30
|
import { quoteMetadataFromQuote, quoteMetadataMatchesTarget } from "../../market-data/quotes/metadata";
|
|
31
31
|
import type { InstrumentSearchResult } from "../../types/instrument";
|
|
32
32
|
import type { TickerChanges } from "../../types/ticker-changes";
|
|
33
|
+
import type { IssuerListings } from "../../types/issuer-listings";
|
|
33
34
|
import {
|
|
34
35
|
apiClient,
|
|
35
36
|
type CloudAnalystResearchPayload,
|
|
@@ -44,7 +45,7 @@ import { resolveCurrencyUnit } from "../../utils/currency-units";
|
|
|
44
45
|
import { isRoundTheClockCoin } from "../../utils/crypto-pair";
|
|
45
46
|
import { canonicalExchange, canonicalTickerKey, parsePublicTickerKey } from "../../utils/exchanges";
|
|
46
47
|
import { normalizePriceHistory, priceHistoryIntervalMs, reachesLatestSettledSession } from "../../utils/price-history";
|
|
47
|
-
import { createProviderMiss, ProviderBusyError, providerMissReason } from "../provider-errors";
|
|
48
|
+
import { createProviderMiss, ProviderBusyError, providerMissReason, StaleHistoryError } from "../provider-errors";
|
|
48
49
|
import { parseListingDelisting } from "../../market-data/quotes/delisting";
|
|
49
50
|
import { isRetryableApiError } from "../../api-client/errors";
|
|
50
51
|
import { assertSecRegistrantMatches } from "../sec-registrant";
|
|
@@ -56,8 +57,9 @@ import { hongKongListingCode, tickerHasListingSuffix } from "../listing-symbols"
|
|
|
56
57
|
import { parseSecAcceptanceTime } from "../sec-edgar/acceptance-time";
|
|
57
58
|
import { hasMalformedIntradayHistory } from "../../time-series/history-quality";
|
|
58
59
|
import {
|
|
59
|
-
|
|
60
|
+
cloudNewsReadArticles,
|
|
60
61
|
mapCloudNewsArticle,
|
|
62
|
+
readCloudNews,
|
|
61
63
|
} from "./news";
|
|
62
64
|
import {
|
|
63
65
|
GLOOMBERB_CLOUD_PROVIDER_ID,
|
|
@@ -76,6 +78,7 @@ import {
|
|
|
76
78
|
import {
|
|
77
79
|
getPerpetualHistory,
|
|
78
80
|
getPerpetualQuote,
|
|
81
|
+
streamedPerpetualQuote,
|
|
79
82
|
namesPerpetualMarket,
|
|
80
83
|
perpetualTarget,
|
|
81
84
|
searchPerpetualMarkets,
|
|
@@ -122,6 +125,7 @@ function mapCloudSecFiling(item: {
|
|
|
122
125
|
filingUrl: string;
|
|
123
126
|
primaryDocumentUrl?: string;
|
|
124
127
|
fileNumber?: string;
|
|
128
|
+
fundSeries?: boolean;
|
|
125
129
|
}): SecFilingItem {
|
|
126
130
|
return {
|
|
127
131
|
accessionNumber: item.accessionNumber,
|
|
@@ -138,6 +142,7 @@ function mapCloudSecFiling(item: {
|
|
|
138
142
|
primaryDocumentUrl: item.primaryDocumentUrl,
|
|
139
143
|
// Absent from an older server: no file number is not the same as an empty one.
|
|
140
144
|
...(typeof item.fileNumber === "string" ? { fileNumber: item.fileNumber } : {}),
|
|
145
|
+
...(typeof item.fundSeries === "boolean" ? { fundSeries: item.fundSeries } : {}),
|
|
141
146
|
};
|
|
142
147
|
}
|
|
143
148
|
|
|
@@ -202,7 +207,7 @@ function mapCloudPriceHistory(
|
|
|
202
207
|
// or a stale answer without bars, are a miss.
|
|
203
208
|
const stale = isStaleCloudResponse(response);
|
|
204
209
|
if (stale && response.status !== "success" && response.status !== "partial") {
|
|
205
|
-
throw
|
|
210
|
+
throw new StaleHistoryError(`Cloud chart data is stale for ${ticker}`);
|
|
206
211
|
}
|
|
207
212
|
if (response.status === "unsupported" && response.reasonCode === "HISTORY_RETENTION" && requestedEnd) {
|
|
208
213
|
const retention = parseHistoryRetention(response.historyRetention);
|
|
@@ -227,7 +232,7 @@ function mapCloudPriceHistory(
|
|
|
227
232
|
).map((point) => mapPricePoint(point, divisor, exchange, coin)),
|
|
228
233
|
);
|
|
229
234
|
if (stale && !reachesLatestSettledSession(points, Date.now(), { symbol: ticker, exchange, intervalMs: priceHistoryIntervalMs(interval) })) {
|
|
230
|
-
throw
|
|
235
|
+
throw new StaleHistoryError(`Cloud chart data is stale for ${ticker}`);
|
|
231
236
|
}
|
|
232
237
|
const intraday = /^\d+(min|h)$/i.test(interval);
|
|
233
238
|
// Daily bars answering an intraday range: the listing has no intraday bars.
|
|
@@ -718,6 +723,12 @@ export class GloomberbCloudProvider implements AssetDataProvider {
|
|
|
718
723
|
return cloudTickerChangesBatch(symbols, options);
|
|
719
724
|
}
|
|
720
725
|
|
|
726
|
+
async getIssuerListings(symbol: string, exchange = "", options: { signal?: AbortSignal } = {}): Promise<IssuerListings | null> {
|
|
727
|
+
const response = await apiClient.getCloudIssuerListings(symbol, exchange, options);
|
|
728
|
+
// "empty" is an answer: the service holds no company for the listing.
|
|
729
|
+
return response.status === "success" || response.status === "partial" ? response.data : null;
|
|
730
|
+
}
|
|
731
|
+
|
|
721
732
|
async searchBatch(queries: string[], options: { limit?: number; signal?: AbortSignal } = {}): Promise<Map<string, InstrumentSearchResult[]> | null> {
|
|
722
733
|
const answers = await cloudSearchBatch(queries, options);
|
|
723
734
|
if (!answers) return null;
|
|
@@ -878,14 +889,23 @@ export class GloomberbCloudProvider implements AssetDataProvider {
|
|
|
878
889
|
targets: QuoteSubscriptionTarget[],
|
|
879
890
|
onQuote: (target: QuoteSubscriptionTarget, quote: Quote) => void,
|
|
880
891
|
): () => void {
|
|
881
|
-
//
|
|
882
|
-
|
|
892
|
+
// A perpetual market streams as its listing on its venue (BTC:HYPERLIQUID): Gloom Cloud follows the venue's own
|
|
893
|
+
// socket for it, once the server says it can (the socket holds it back until then).
|
|
894
|
+
const { perpetuals, others } = splitPerpetualTargets(targets);
|
|
895
|
+
const valid: Array<{ target: QuoteSubscriptionTarget; request: { symbol: string; exchange?: string } }> = [
|
|
896
|
+
...cloudBatchTargets(others).valid,
|
|
897
|
+
...perpetuals.flatMap((target) => {
|
|
898
|
+
const listing = perpetualTarget(target.symbol, target.exchange);
|
|
899
|
+
return listing ? [{ target, request: { symbol: listing.symbol, exchange: listing.exchange } }] : [];
|
|
900
|
+
}),
|
|
901
|
+
];
|
|
883
902
|
if (!valid.length) return () => {};
|
|
884
903
|
// No-op without a session credential; covers browser cookie sessions too.
|
|
885
904
|
void apiClient.ensureVerifiedSession().catch(logFailure("sources.gloomberb-cloud.index", "Verifying the quote streaming session failed"));
|
|
886
905
|
const targetMap = new Map<string, QuoteSubscriptionTarget[]>();
|
|
887
|
-
for (const { target } of valid) {
|
|
888
|
-
|
|
906
|
+
for (const { target, request } of valid) {
|
|
907
|
+
// A perpetual comes back as its listing, whatever form it was asked for in.
|
|
908
|
+
const key = perpetuals.includes(target) ? quoteTargetKey(request.symbol, request.exchange) : quoteTargetKey(target.symbol, target.exchange);
|
|
889
909
|
const matches = targetMap.get(key) ?? [];
|
|
890
910
|
matches.push(target);
|
|
891
911
|
targetMap.set(key, matches);
|
|
@@ -909,7 +929,10 @@ export class GloomberbCloudProvider implements AssetDataProvider {
|
|
|
909
929
|
}
|
|
910
930
|
const matchedKey = cloudResponseTargetKey(key, requested);
|
|
911
931
|
const matches = matchedKey ? targetMap.get(matchedKey) ?? [] : [];
|
|
912
|
-
|
|
932
|
+
if (!matches.length) return;
|
|
933
|
+
const listing = perpetualTarget(target.symbol, target.exchange);
|
|
934
|
+
const mappedQuote = listing ? streamedPerpetualQuote(quote, listing) : mapQuote(quote);
|
|
935
|
+
if (!mappedQuote) return;
|
|
913
936
|
for (const match of matches) {
|
|
914
937
|
onQuote(match, retainRequestedQuoteSymbol(mappedQuote, match.symbol));
|
|
915
938
|
}
|
|
@@ -934,21 +957,21 @@ export function createGloomberbCloudCapabilities(provider = createGloomberbCloud
|
|
|
934
957
|
return normalizeNewsFeed(query) === "ticker" ? !!query.ticker && !predictionMarketListing(query.ticker, query.exchange) : true;
|
|
935
958
|
},
|
|
936
959
|
async fetchNewsPage(query: NewsQuery) {
|
|
937
|
-
const
|
|
938
|
-
() => apiClient
|
|
960
|
+
const read = await withCloudFallback(
|
|
961
|
+
() => readCloudNews(apiClient, query),
|
|
939
962
|
"Cloud news is unavailable",
|
|
940
963
|
);
|
|
941
964
|
return {
|
|
942
|
-
articles:
|
|
943
|
-
nextCursor:
|
|
965
|
+
articles: cloudNewsReadArticles(read, query.ticker),
|
|
966
|
+
nextCursor: read.nextCursor ?? null,
|
|
944
967
|
};
|
|
945
968
|
},
|
|
946
969
|
async fetchNews(query: NewsQuery): Promise<NewsArticle[]> {
|
|
947
|
-
const
|
|
948
|
-
() => apiClient
|
|
970
|
+
const read = await withCloudFallback(
|
|
971
|
+
() => readCloudNews(apiClient, query),
|
|
949
972
|
"Cloud news is unavailable",
|
|
950
973
|
);
|
|
951
|
-
return
|
|
974
|
+
return cloudNewsReadArticles(read, query.ticker);
|
|
952
975
|
},
|
|
953
976
|
async fetchNewsStory(storyId: string): Promise<NewsArticle | null> {
|
|
954
977
|
const story = await withCloudFallback(
|
|
@@ -3,11 +3,15 @@ import { readableNewsSource } from "../../news/source-label";
|
|
|
3
3
|
import { collectNewsDisplayTickers } from "../../news/ticker-symbols";
|
|
4
4
|
import type { NewsArticle, NewsQuery, NewsStoryItem } from "../../types/news-source";
|
|
5
5
|
import type {
|
|
6
|
+
apiClient,
|
|
7
|
+
CloudNewsListResponse,
|
|
6
8
|
CloudNewsPayload,
|
|
7
9
|
CloudNewsStoryItemPayload,
|
|
8
10
|
} from "../../api-client";
|
|
9
11
|
import type { CloudNewsParams } from "../../api-client/paths";
|
|
10
12
|
import { parsePublicTickerKey, publicExchange } from "../../utils/exchanges";
|
|
13
|
+
import { coinSearchName } from "../../utils/crypto-pair";
|
|
14
|
+
import { logFailure } from "../../utils/log-failure";
|
|
11
15
|
import { getListingSymbol, tickerHasListingSuffix } from "../listing-symbols";
|
|
12
16
|
|
|
13
17
|
function normalizeStringArray(value: unknown): string[] {
|
|
@@ -129,3 +133,38 @@ export function cloudNewsParams(query: NewsQuery): CloudNewsParams {
|
|
|
129
133
|
cursor: query.cursor,
|
|
130
134
|
};
|
|
131
135
|
}
|
|
136
|
+
|
|
137
|
+
/** A page of Gloom Cloud stories, with the text searched for when a coin pair's feed had none filed under it. */
|
|
138
|
+
export type CloudNewsRead = CloudNewsListResponse & { searchedFor?: string };
|
|
139
|
+
|
|
140
|
+
type CloudNewsClient = Pick<typeof apiClient, "getCloudNews" | "searchCloudNews">;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* A news query's first page from Gloom Cloud. Stories are filed under company
|
|
144
|
+
* tickers, and a coin pair (BTC-USD) rarely has any filed under it, so its
|
|
145
|
+
* empty feed falls back to the stories that mention the coin ("bitcoin"),
|
|
146
|
+
* marked with what was searched. A later page, a failed search or a coin with
|
|
147
|
+
* no name to search keeps the empty answer.
|
|
148
|
+
*/
|
|
149
|
+
export async function readCloudNews(client: CloudNewsClient, query: NewsQuery): Promise<CloudNewsRead> {
|
|
150
|
+
const response = await client.getCloudNews(cloudNewsParams(query));
|
|
151
|
+
if (response.items.length > 0 || query.cursor || normalizeNewsFeed(query) !== "ticker") return response;
|
|
152
|
+
const text = coinSearchName(query.ticker, query.exchange, query.listingName);
|
|
153
|
+
if (!text) return response;
|
|
154
|
+
const found = await client.searchCloudNews(text, query.limit)
|
|
155
|
+
.catch(logFailure("sources.gloomberb-cloud.news", "Search a coin's stories failed", null));
|
|
156
|
+
return found && found.items.length > 0 ? { items: found.items, nextCursor: null, searchedFor: text } : response;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A read's stories as articles, each marked with the text a coin's fallback searched for. */
|
|
160
|
+
export function cloudNewsReadArticles(read: CloudNewsRead, ticker?: string): NewsArticle[] {
|
|
161
|
+
return read.items.map((item) => {
|
|
162
|
+
const article = mapCloudNewsArticle(item, read.searchedFor ? undefined : ticker);
|
|
163
|
+
return read.searchedFor ? { ...article, searchedFor: read.searchedFor } : article;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** What a pane or report says above the stories a coin's fallback found: "No stories are filed under BTC-USD; these mention bitcoin." */
|
|
168
|
+
export function coinNewsFallbackNotice(ticker: string, searchedFor: string): string {
|
|
169
|
+
return `No stories are filed under ${ticker}; these mention ${searchedFor}.`;
|
|
170
|
+
}
|
|
@@ -28,6 +28,7 @@ import { reconcileQuoteDayRange } from "../../market-data/quotes/day-range";
|
|
|
28
28
|
import { redactUnavailableFundamentals } from "../../utils/fundamentals";
|
|
29
29
|
import { readWithdrawnObservations } from "../../utils/statement-gaps";
|
|
30
30
|
import { parseListingDelisting } from "../../market-data/quotes/delisting";
|
|
31
|
+
import { readIntradayBar, readStaleReason } from "../../market-data/quotes/intraday-bar";
|
|
31
32
|
|
|
32
33
|
export const GLOOMBERB_CLOUD_PROVIDER_ID = "gloomberb-cloud" as const;
|
|
33
34
|
|
|
@@ -96,6 +97,8 @@ export function mapQuote(
|
|
|
96
97
|
return withoutUndefinedFields(reconcileQuoteDayRange({
|
|
97
98
|
...quote,
|
|
98
99
|
delisting: parseListingDelisting(quote.delisting),
|
|
100
|
+
intradayBar: readIntradayBar(quote.intradayBar),
|
|
101
|
+
staleReason: readStaleReason(quote.staleReason),
|
|
99
102
|
priceBasis,
|
|
100
103
|
priceObservation,
|
|
101
104
|
currency: currency || quote.currency,
|
|
@@ -222,6 +225,15 @@ function parseCloudPricePointDate(
|
|
|
222
225
|
: new Date(value);
|
|
223
226
|
}
|
|
224
227
|
|
|
228
|
+
/** A served venue count, when it is one: a venue name and a count of zero or more. */
|
|
229
|
+
function venueVolume(value: unknown): { venueVolume: { venue: string; volume: number } } | null {
|
|
230
|
+
if (!value || typeof value !== "object") return null;
|
|
231
|
+
const { venue, volume } = value as { venue?: unknown; volume?: unknown };
|
|
232
|
+
return typeof venue === "string" && venue.trim() && typeof volume === "number" && Number.isFinite(volume) && volume >= 0
|
|
233
|
+
? { venueVolume: { venue: venue.trim(), volume } }
|
|
234
|
+
: null;
|
|
235
|
+
}
|
|
236
|
+
|
|
225
237
|
/**
|
|
226
238
|
* One served bar. `coin`: the bars are a coin's, which trades every hour of every day. Its intraday volume is the
|
|
227
239
|
* value traded in the bar on major spot venues, and a bar no venue reported has none rather than 0, so a 0 (from an
|
|
@@ -241,6 +253,7 @@ export function mapPricePoint(
|
|
|
241
253
|
low: normalizePriceValueByDivisor(point.low, divisor),
|
|
242
254
|
close: normalizePriceValueByDivisor(point.close, divisor) ?? point.close,
|
|
243
255
|
volume: coin && point.volume === 0 ? undefined : point.volume,
|
|
256
|
+
...(venueVolume(point.venueVolume) ?? {}),
|
|
244
257
|
...(point.partial === true ? { partial: true } : {}),
|
|
245
258
|
...(point.filled === true ? { filled: true } : {}),
|
|
246
259
|
...(point.unsettled === true ? { unsettled: true } : {}),
|
|
@@ -437,7 +450,7 @@ const HISTORY_OUTPUT_SIZE: Record<TimeRange, number> = {
|
|
|
437
450
|
"ALL": 600,
|
|
438
451
|
};
|
|
439
452
|
|
|
440
|
-
/** The bar size comes from the shared range table, which `
|
|
453
|
+
/** The bar size comes from the shared range table, which `gloom help history` also lists. */
|
|
441
454
|
export function toHistoryRequest(range: TimeRange): {
|
|
442
455
|
interval: string;
|
|
443
456
|
outputsize: number;
|
|
@@ -115,7 +115,55 @@ export function perpetualQuote(row: PerpBoardRow, listing: PerpetualListing): Qu
|
|
|
115
115
|
dataSource: "delayed",
|
|
116
116
|
...(row.markPrice != null ? { mark: row.markPrice } : {}),
|
|
117
117
|
...(row.lastPrice != null ? { lastTradePrice: row.lastPrice } : {}),
|
|
118
|
-
|
|
118
|
+
// Said either way: a fresh reading merged over a stale one must clear it, not inherit it.
|
|
119
|
+
stale: row.stale === true || row.delisted === true,
|
|
120
|
+
perpetual: row,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** The figures a streamed row is read by: each a finite number, or none. */
|
|
125
|
+
const STREAMED_FIGURES = ["markPrice", "lastPrice", "fundingRate8h", "openInterestUsd", "premium"] as const;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* A row the market socket carried for this listing's market, readable as a fetched one; null for anything else. A
|
|
129
|
+
* figure the frame leaves out (a server writes no key for a value it does not have) is none, as null says.
|
|
130
|
+
*/
|
|
131
|
+
function streamedRow(value: unknown, listing: PerpetualListing): PerpBoardRow | null {
|
|
132
|
+
if (!value || typeof value !== "object") return null;
|
|
133
|
+
const row = value as PerpBoardRow;
|
|
134
|
+
if (typeof row.marketId !== "string" || row.marketId.toLowerCase() !== listing.marketId.toLowerCase()
|
|
135
|
+
|| typeof row.quoteCurrency !== "string" || typeof row.observedAt !== "string" || !Number.isFinite(Date.parse(row.observedAt))) return null;
|
|
136
|
+
const figures: Partial<Record<(typeof STREAMED_FIGURES)[number], number | null>> = {};
|
|
137
|
+
for (const field of STREAMED_FIGURES) {
|
|
138
|
+
const figure: unknown = row[field];
|
|
139
|
+
if (figure != null && !(typeof figure === "number" && Number.isFinite(figure))) return null;
|
|
140
|
+
figures[field] = figure ?? null;
|
|
141
|
+
}
|
|
142
|
+
return { ...row, ...figures };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A perpetual's quote from the market socket: the same quote its fetched row
|
|
147
|
+
* makes, from the row the socket carried, marked live while the venue's own
|
|
148
|
+
* socket feeds it. Null when the frame holds no row for this market.
|
|
149
|
+
*/
|
|
150
|
+
export function streamedPerpetualQuote(
|
|
151
|
+
frame: { perpetual?: unknown; dataSource?: unknown; delivery?: unknown; stale?: unknown; bid?: unknown; ask?: unknown },
|
|
152
|
+
listing: PerpetualListing,
|
|
153
|
+
): Quote | null {
|
|
154
|
+
const row = streamedRow(frame.perpetual, listing);
|
|
155
|
+
const quote = row ? perpetualQuote(row, listing) : null;
|
|
156
|
+
if (!quote) return null;
|
|
157
|
+
const number = (value: unknown) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
158
|
+
const bid = number(frame.bid);
|
|
159
|
+
const ask = number(frame.ask);
|
|
160
|
+
return {
|
|
161
|
+
...quote,
|
|
162
|
+
...(frame.dataSource === "live" ? { dataSource: "live" as const } : {}),
|
|
163
|
+
...(frame.delivery === "stream" || frame.delivery === "poll" ? { delivery: frame.delivery } : {}),
|
|
164
|
+
stale: quote.stale === true || frame.stale === true,
|
|
165
|
+
...(bid !== undefined ? { bid } : {}),
|
|
166
|
+
...(ask !== undefined ? { ask } : {}),
|
|
119
167
|
};
|
|
120
168
|
}
|
|
121
169
|
|
|
@@ -139,6 +139,43 @@ export function listingSuffixConflictsWithExchange(ticker: string, exchange: str
|
|
|
139
139
|
return suffixes.length > 0 && !suffixes.includes(ticker.slice(ticker.indexOf(".")));
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* The venue a vendor's suffix names, whatever else it could be: GARAN.IS is
|
|
144
|
+
* GARAN on BIST, 7203.T 7203 on JPX, and MKC.V reads as MKC on TSXV, though it
|
|
145
|
+
* is McCormick's voting class on NYSE. For a caller that confirms it, by a row
|
|
146
|
+
* saved on that venue or the listing's own quote (`listingSuffixVenue`). Null
|
|
147
|
+
* for a symbol without a venue suffix (BRK.B) and a suffix several venues share.
|
|
148
|
+
*/
|
|
149
|
+
export function listingSuffixCandidate(ticker: string): { symbol: string; exchange: string } | null {
|
|
150
|
+
if (!tickerHasListingSuffix(ticker)) return null;
|
|
151
|
+
const dot = ticker.indexOf(".");
|
|
152
|
+
const suffix = ticker.slice(dot);
|
|
153
|
+
// The one host venue the suffix names, else the one venue the table names for it (BIST, which the host table lacks).
|
|
154
|
+
const venues = new Set(HOST_SUFFIX_ENTRIES.filter(([, entry]) => entry === suffix).map(([venue]) => venue));
|
|
155
|
+
const venue = listingSuffixExchange(ticker) ?? (venues.size === 1 ? [...venues][0] : undefined);
|
|
156
|
+
return venue ? { symbol: ticker.slice(0, dot), exchange: venue } : null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The listing a vendor's suffixed symbol stands for, when that is settled:
|
|
161
|
+
* GARAN.IS is GARAN on BIST, VOD.L on LSE is VOD there. A venue the table
|
|
162
|
+
* knows settles it, either way: its own suffix maps, another's (MKC.V on NYSE,
|
|
163
|
+
* McCormick's voting class) does not. With no venue, or one the table does not
|
|
164
|
+
* know (IST, JNB), the suffix's own venue is read for a suffix of two letters
|
|
165
|
+
* or more; a one-letter suffix is also a US class letter (MKC.V, BRK.B), so it
|
|
166
|
+
* maps only when a venue agrees. Null when it does not map.
|
|
167
|
+
*/
|
|
168
|
+
export function listingSuffixVenue(ticker: string, exchange?: string): { symbol: string; exchange: string } | null {
|
|
169
|
+
const candidate = listingSuffixCandidate(ticker);
|
|
170
|
+
if (!candidate) return null;
|
|
171
|
+
const suffix = ticker.slice(ticker.indexOf("."));
|
|
172
|
+
const given = canonicalExchange(exchange);
|
|
173
|
+
// SMART routes for a broker; it names no venue.
|
|
174
|
+
const suffixes = given && given !== "SMART" ? HOST_SUFFIX_ENTRIES.filter(([venue]) => venue === given).map(([, entry]) => entry) : [];
|
|
175
|
+
if (suffixes.length > 0) return suffixes.includes(suffix) ? { symbol: candidate.symbol, exchange: given } : null;
|
|
176
|
+
return suffix.length > 2 ? candidate : null;
|
|
177
|
+
}
|
|
178
|
+
|
|
142
179
|
/** Infer a venue only when the suffix names one recognized host exchange. */
|
|
143
180
|
export function listingSuffixExchange(ticker: string): string | undefined {
|
|
144
181
|
if (!tickerHasListingSuffix(ticker)) return undefined;
|