gloomberb 0.18.3 → 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/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 +84 -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 +22 -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 +21 -4
- 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/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- 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/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- 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 +1117 -264
- 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 +192 -47
- 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 +19 -13
- 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 +24 -18
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +300 -41
- package/src/cli/name-entries.ts +30 -18
- 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 +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- 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 +24 -11
- package/src/cli/pane-functions/index.ts +18 -16
- 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 +47 -10
- 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 +61 -16
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +111 -22
- 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 +198 -68
- 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 +373 -16
- package/src/components/chart/composite/interactions.ts +7 -2
- 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 +305 -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 +13 -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/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/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 +12 -6
- package/src/components/layout/header.tsx +7 -6
- 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/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/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 +29 -12
- package/src/i18n/ja.ts +29 -12
- package/src/i18n/ko.ts +29 -12
- package/src/i18n/zh-cn.ts +29 -12
- package/src/i18n/zh-tw.ts +29 -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 +29 -19
- 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 +107 -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 +76 -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 +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- 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 +6 -3
- 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 +22 -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 +110 -23
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- 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 +25 -12
- 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/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 +6 -8
- 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 +127 -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 +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- 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 +79 -23
- 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 +1 -1
- 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 +5 -3
- 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 +3 -2
- 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/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/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 +18 -11
- 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 +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
- 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 +6 -1
- 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/headless.ts +9 -4
- 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 +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- 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/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- 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/headless.ts +4 -4
- 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 +10 -4
- 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 +33 -19
- 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 +29 -8
- 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 +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/view.tsx +10 -10
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- 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 +36 -15
- 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 +9 -5
- 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 +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- 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 +4 -1
- 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 +8 -1
- 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/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -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 +2 -1
- 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-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 +21 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.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/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 +5 -4
- package/src/plugins/builtin/vol-surface/headless.ts +12 -3
- package/src/plugins/builtin/vol-surface/model.ts +4 -2
- 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/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/styles.css +76 -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/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +46 -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/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 +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- 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 +1 -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 +32 -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/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 +17 -4
- 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 +210 -33
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- 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 +14 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +76 -6
- package/src/types/instrument.ts +3 -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/index.ts +10 -5
- 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-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 +3 -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
|
@@ -4,10 +4,12 @@ import { spanDigits } from "../../../components/chart-table";
|
|
|
4
4
|
import { compositeAxisTicks } from "../../../components/chart/composite/format";
|
|
5
5
|
import type { CompositeAxisDomain } from "../../../components/chart/composite/types";
|
|
6
6
|
import { FUTURES_CONTRACTS, futuresBoardContractForTicker, futuresContractByCode, tickDecimals } from "../../../market-data/futures-board";
|
|
7
|
+
import { contractMonthLabel } from "../../../utils/contract-month";
|
|
7
8
|
import { formatPercentileRank } from "../../../utils/format";
|
|
8
9
|
import { cryptoPairCoin, isFuturesSymbol } from "../shared/crypto-pair";
|
|
9
10
|
import { parseReportTime } from "../../../utils/utc-time";
|
|
10
|
-
import {
|
|
11
|
+
import { zonedWallClockToUtcMs } from "../../../utils/zoned-date-time";
|
|
12
|
+
import { dateOptionError, dateOptionFormatsOr, readCalendarDate } from "../../../utils/calendar-date";
|
|
11
13
|
import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -147,6 +149,41 @@ export function curveSpreadLabel(slope: Pick<FuturesCurvePayload["slope"], "fron
|
|
|
147
149
|
return slope.frontSymbol && slope.nextSymbol ? `${curveContractCode(slope.nextSymbol)}-${curveContractCode(slope.frontSymbol)}` : "M2-M1";
|
|
148
150
|
}
|
|
149
151
|
|
|
152
|
+
/** A leg that traded fewer lots than this in its session is too thin to call a curve's slope from. */
|
|
153
|
+
const THIN_SPREAD_LOTS = 20;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* What the front spread subtracts, as its figure says it: "settle 10-22" for
|
|
157
|
+
* two settlements of a session (the Settle column's date), "last 20:59" for
|
|
158
|
+
* two last trades made together, dated when not the newest quote's day. Null
|
|
159
|
+
* when the server does not say.
|
|
160
|
+
*/
|
|
161
|
+
export function curveSpreadBasis(slope: Pick<FuturesCurvePayload["slope"], "basis" | "asOf">, newest: string | null): string | null {
|
|
162
|
+
if (!slope.basis || !slope.asOf) return null;
|
|
163
|
+
if (slope.basis === "settle" || !slope.asOf.includes("T")) return `${slope.basis} ${slope.asOf.slice(5, 10)}`;
|
|
164
|
+
const stamp = curveTimestamp(slope.asOf);
|
|
165
|
+
return `last ${newest?.includes("T") && curveTimestamp(newest).slice(0, 10) === stamp.slice(0, 10) ? stamp.slice(11) : stamp.slice(5)}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Why the front spread is thin, from its thin leg's row: "ALIX26 traded 4 lots"
|
|
170
|
+
* or "ALIX26 last traded 2026-10-22". Null when it is not thin.
|
|
171
|
+
*/
|
|
172
|
+
function thinSpreadReason(data: Pick<FuturesCurvePayload, "slope" | "contracts">): string | null {
|
|
173
|
+
if (data.slope.state !== "thin") return null;
|
|
174
|
+
const leg = data.contracts.find((row) => row.symbol === data.slope.thinSymbol);
|
|
175
|
+
if (!leg) return null;
|
|
176
|
+
const code = curveContractCode(leg.symbol);
|
|
177
|
+
if (leg.volume != null && leg.volume < THIN_SPREAD_LOTS) return `${code} traded ${leg.volume} lot${leg.volume === 1 ? "" : "s"}`;
|
|
178
|
+
return leg.asOf ? `${code} last traded ${leg.asOf.slice(0, 10)}` : `${code} has not traded`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** The warning a thin front spread carries: why, and that its sign is no slope call. */
|
|
182
|
+
export function thinSpreadNotice(data: Pick<FuturesCurvePayload, "slope" | "contracts">): string | null {
|
|
183
|
+
const reason = thinSpreadReason(data);
|
|
184
|
+
return reason ? `${curveSpreadLabel(data.slope)} is thin (${reason}): no contango or backwardation call` : null;
|
|
185
|
+
}
|
|
186
|
+
|
|
150
187
|
/**
|
|
151
188
|
* Axis gridlines sit on round values, so they need no tick precision: one
|
|
152
189
|
* decimal count across the gutter, as many as the plotted range asks for and
|
|
@@ -166,17 +203,16 @@ export function curveAxisPrice(value: number, domain: CompositeAxisDomain, root:
|
|
|
166
203
|
}
|
|
167
204
|
|
|
168
205
|
const MONTH_CODES = "FGHJKMNQUVXZ";
|
|
169
|
-
const MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
170
206
|
|
|
171
207
|
/**
|
|
172
|
-
* The delivery month a trader names a contract by ("Nov
|
|
208
|
+
* The delivery month a trader names a contract by ("Nov 2026" for CLX26), not
|
|
173
209
|
* its last trading day: crude's November contract expires in October, and a
|
|
174
210
|
* "26-10-20" label also reads as a day-first date.
|
|
175
211
|
*/
|
|
176
212
|
export function curveContractMonth(symbol: string, expiration: string): string {
|
|
177
213
|
const coded = /^[A-Z0-9]+?([FGHJKMNQUVXZ])(\d{2})\.[A-Z]+$/.exec(symbol);
|
|
178
|
-
if (coded) return
|
|
179
|
-
return
|
|
214
|
+
if (coded) return contractMonthLabel(Number(coded[2]), MONTH_CODES.indexOf(coded[1]!));
|
|
215
|
+
return contractMonthLabel(Number(expiration.slice(0, 4)), Number(expiration.slice(5, 7)) - 1);
|
|
180
216
|
}
|
|
181
217
|
|
|
182
218
|
export function curveTimestamp(value: string | null): string {
|
|
@@ -288,7 +324,17 @@ const SPOT_STALE_MS = 10 * 60_000;
|
|
|
288
324
|
/** A free account's quote is held back on purpose; that delay is not staleness, so it is allowed on top. */
|
|
289
325
|
const DELAYED_SPOT_MS = 15 * 60_000;
|
|
290
326
|
|
|
291
|
-
/**
|
|
327
|
+
/**
|
|
328
|
+
* The listing codes the quote path reports for a spot, in plain words: a
|
|
329
|
+
* reader is told what the price is, never handed a bare code.
|
|
330
|
+
*/
|
|
331
|
+
const SPOT_VENUE_LABELS: Readonly<Record<string, string>> = { CCC: "crypto composite price" };
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* The latest spot quote, which the footer shows beside the curve, or why there
|
|
335
|
+
* is none. `asOf` is the quote's own time, never the fetch's. The basis does
|
|
336
|
+
* not read it: each contract is read against the spot in its own minute.
|
|
337
|
+
*/
|
|
292
338
|
export interface CurveSpot {
|
|
293
339
|
symbol: string;
|
|
294
340
|
price: number | null;
|
|
@@ -296,7 +342,7 @@ export interface CurveSpot {
|
|
|
296
342
|
asOf: string | null;
|
|
297
343
|
status: "ok" | "stale" | "missing";
|
|
298
344
|
reason: string | null;
|
|
299
|
-
/**
|
|
345
|
+
/** What the quote path reports the price is, in plain words (`crypto composite price`), when it reports it. */
|
|
300
346
|
venue?: string;
|
|
301
347
|
/** Whether the quote is real-time or held back, as the quote path reports it. */
|
|
302
348
|
feed?: "real-time" | "delayed";
|
|
@@ -324,7 +370,8 @@ function quoteAge(ms: number): string {
|
|
|
324
370
|
export function curveSpot(symbol: string, quote: SpotQuote | null | undefined, now: number): CurveSpot {
|
|
325
371
|
if (!quote || !positive(quote.price)) return { symbol, price: null, asOf: null, status: "missing", reason: `no ${symbol} quote` };
|
|
326
372
|
// What the quote path says about the quote itself, kept beside the price so the footer can name it.
|
|
327
|
-
const
|
|
373
|
+
const code = (quote.listingExchangeName || quote.exchangeName)?.trim();
|
|
374
|
+
const venue = code ? SPOT_VENUE_LABELS[code.toUpperCase()] ?? code : undefined;
|
|
328
375
|
const feed: CurveSpot["feed"] = quote.dataSource === "live" ? "real-time" : quote.dataSource === "delayed" ? "delayed" : undefined;
|
|
329
376
|
const source = { ...venue ? { venue } : {}, ...feed ? { feed } : {} };
|
|
330
377
|
const time = quote.lastUpdated;
|
|
@@ -339,54 +386,115 @@ export function curveSpot(symbol: string, quote: SpotQuote | null | undefined, n
|
|
|
339
386
|
return { symbol, price: quote.price, asOf, status: "ok", reason: null, ...source };
|
|
340
387
|
}
|
|
341
388
|
|
|
342
|
-
|
|
389
|
+
const MINUTE_MS = 60_000;
|
|
390
|
+
const minuteOf = (time: number) => Math.floor(time / MINUTE_MS) * MINUTE_MS;
|
|
391
|
+
const isoMinute = (time: number) => new Date(time).toISOString().replace(":00.000Z", ":00Z");
|
|
392
|
+
|
|
393
|
+
/** The spot in one UTC minute: the close of the spot pair's one-minute bar that opened then. */
|
|
394
|
+
export interface SpotBar {
|
|
395
|
+
/** Epoch milliseconds of the minute's start. */
|
|
396
|
+
minute: number;
|
|
397
|
+
price: number;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** One-minute bars as the spot by minute, oldest first; a bar with no usable time or close is left out. */
|
|
401
|
+
export function spotBarsFromHistory(points: readonly { date: Date | string | number; close: number }[]): SpotBar[] {
|
|
402
|
+
const byMinute = new Map<number, number>();
|
|
403
|
+
for (const point of points) {
|
|
404
|
+
const time = new Date(point.date).getTime();
|
|
405
|
+
if (Number.isFinite(time) && positive(point.close)) byMinute.set(minuteOf(time), point.close);
|
|
406
|
+
}
|
|
407
|
+
return [...byMinute].sort((a, b) => a[0] - b[0]).map(([minute, price]) => ({ minute, price }));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/** The bar in `minute`, else the one nearest it; null when there are none. */
|
|
411
|
+
function nearestSpotBar(bars: readonly SpotBar[], minute: number): SpotBar | null {
|
|
412
|
+
let low = 0;
|
|
413
|
+
let high = bars.length - 1;
|
|
414
|
+
while (low <= high) {
|
|
415
|
+
const middle = (low + high) >> 1;
|
|
416
|
+
const bar = bars[middle]!;
|
|
417
|
+
if (bar.minute === minute) return bar;
|
|
418
|
+
if (bar.minute < minute) low = middle + 1;
|
|
419
|
+
else high = middle - 1;
|
|
420
|
+
}
|
|
421
|
+
const before = bars[high];
|
|
422
|
+
const after = bars[low];
|
|
423
|
+
if (!before) return after ?? null;
|
|
424
|
+
if (!after) return before;
|
|
425
|
+
return minute - before.minute <= after.minute - minute ? before : after;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** How far a contract trades over (positive) or under spot, in percent. */
|
|
343
429
|
export function vsSpotPct(futures: number | null | undefined, spot: number | null | undefined): number | null {
|
|
344
430
|
return positive(futures) && positive(spot) ? (futures / spot - 1) * 100 : null;
|
|
345
431
|
}
|
|
346
432
|
|
|
347
|
-
/**
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
433
|
+
/**
|
|
434
|
+
* CME's crypto futures stop trading at 4:00 p.m. London time on their last
|
|
435
|
+
* trading day and settle to the CME CF reference rate published then, so a
|
|
436
|
+
* contract's days to expiry run to that instant, not to a calendar date.
|
|
437
|
+
*/
|
|
438
|
+
const FINAL_SETTLEMENT = { timeZone: "Europe/London", hour: 16 } as const;
|
|
439
|
+
|
|
440
|
+
/** The instant a crypto contract expiring on `expiration` (YYYY-MM-DD) settles, or null for a date that cannot be read. */
|
|
441
|
+
function finalSettlementTime(expiration: string): number | null {
|
|
442
|
+
const date = /^(\d{4})-(\d{2})-(\d{2})$/.exec(expiration);
|
|
443
|
+
if (!date) return null;
|
|
444
|
+
const time = zonedWallClockToUtcMs(FINAL_SETTLEMENT.timeZone, Number(date[1]), Number(date[2]), Number(date[3]), FINAL_SETTLEMENT.hour, 0, 0);
|
|
445
|
+
return Number.isFinite(time) ? time : null;
|
|
353
446
|
}
|
|
354
447
|
|
|
355
|
-
/**
|
|
448
|
+
/** Days, fractional, from `from` to the contract's final settlement: 6.6 from Saturday 01:33 UTC to Friday 16:00 London. */
|
|
449
|
+
export function daysToExpiry(from: number, expiration: string): number | null {
|
|
450
|
+
const settles = finalSettlementTime(expiration);
|
|
451
|
+
return settles == null || !Number.isFinite(from) ? null : (settles - from) / DAY_MS;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/** The premium over spot as a yearly rate, on a 365-day year. Blank at or past final settlement, where it has no meaning. */
|
|
356
455
|
export function annualisedBasisPct(futures: number | null | undefined, spot: number | null | undefined, days: number | null): number | null {
|
|
357
456
|
if (!positive(futures) || !positive(spot) || days == null || !Number.isFinite(days) || days <= 0) return null;
|
|
358
457
|
return (futures / spot - 1) * 365 / days * 100;
|
|
359
458
|
}
|
|
360
459
|
|
|
361
|
-
/** A contract that printed longer than this before the spot quote is too old to read against it. */
|
|
362
|
-
const CONTRACT_PRINT_MAX_AGE_MS = 60 * 60_000;
|
|
363
|
-
|
|
364
460
|
export interface ContractBasis {
|
|
365
461
|
vsSpotPct: number | null;
|
|
366
462
|
annualisedBasisPct: number | null;
|
|
367
|
-
/**
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
463
|
+
/** The spot the last trade is read against: the close of the spot's bar in the trade's own minute. */
|
|
464
|
+
spot: number | null;
|
|
465
|
+
/** That bar's minute, as a UTC ISO instant. */
|
|
466
|
+
spotTime: string | null;
|
|
467
|
+
/** Fractional days from the last trade to the contract's final settlement. */
|
|
468
|
+
daysToExpiry: number | null;
|
|
469
|
+
/**
|
|
470
|
+
* Why a priced, current contract has no basis: its last trade has no time
|
|
471
|
+
* of day (`print` null), or no spot bar shares its minute, with the
|
|
472
|
+
* nearest bar's minute (null when there are no bars at all). Null when
|
|
473
|
+
* the contract has a basis or another rule blanks it.
|
|
474
|
+
*/
|
|
475
|
+
unpaired: { print: number | null; spot: number | null } | null;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const NO_BASIS: ContractBasis = { vsSpotPct: null, annualisedBasisPct: null, spot: null, spotTime: null, daysToExpiry: null, unpaired: null };
|
|
372
479
|
|
|
373
480
|
/**
|
|
374
|
-
* One contract's basis
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* delayed feed trails the futures).
|
|
481
|
+
* One contract's basis: its last trade against the spot in the same UTC
|
|
482
|
+
* minute, so the two prices are never minutes apart, whichever is the newer
|
|
483
|
+
* (a delayed spot trails the futures, a live one leads them). Blank while
|
|
484
|
+
* the bars are unknown (`bars` null), for a contract whose own price is
|
|
485
|
+
* missing or stale, for a trade with no time of day, and for one no spot bar
|
|
486
|
+
* shares a minute with.
|
|
381
487
|
*/
|
|
382
|
-
export function contractBasis(row: Pick<FuturesContract, "price" | "stale" | "expiration" | "asOf">,
|
|
383
|
-
if (
|
|
384
|
-
const
|
|
385
|
-
if (
|
|
386
|
-
const
|
|
387
|
-
const
|
|
388
|
-
if (
|
|
389
|
-
|
|
488
|
+
export function contractBasis(row: Pick<FuturesContract, "price" | "stale" | "expiration" | "asOf">, bars: readonly SpotBar[] | null): ContractBasis {
|
|
489
|
+
if (!bars || row.stale || !positive(row.price)) return NO_BASIS;
|
|
490
|
+
const printed = parseReportTime(row.asOf);
|
|
491
|
+
if (!printed || printed.dateOnly) return { ...NO_BASIS, unpaired: { print: null, spot: null } };
|
|
492
|
+
const minute = minuteOf(printed.time);
|
|
493
|
+
const bar = nearestSpotBar(bars, minute);
|
|
494
|
+
if (!bar || bar.minute !== minute) return { ...NO_BASIS, unpaired: { print: printed.time, spot: bar?.minute ?? null } };
|
|
495
|
+
const days = daysToExpiry(printed.time, row.expiration);
|
|
496
|
+
return { vsSpotPct: vsSpotPct(row.price, bar.price), annualisedBasisPct: annualisedBasisPct(row.price, bar.price, days),
|
|
497
|
+
spot: bar.price, spotTime: isoMinute(minute), daysToExpiry: days, unpaired: null };
|
|
390
498
|
}
|
|
391
499
|
|
|
392
500
|
/** A basis in percent, signed; one that rounds to zero stays unsigned. */
|
|
@@ -408,23 +516,18 @@ export function curveSpotLabel(spot: CurveSpot, root: string, now: number): stri
|
|
|
408
516
|
/** The basis columns' sort values, which live beside the contract rather than on it. */
|
|
409
517
|
export type CurveBasisRows = ReadonlyMap<string, ContractBasis>;
|
|
410
518
|
|
|
411
|
-
export function curveBasisRows(rows: readonly FuturesContract[],
|
|
412
|
-
return new Map(rows.map((row) => [row.symbol,
|
|
519
|
+
export function curveBasisRows(rows: readonly FuturesContract[], bars: readonly SpotBar[] | null): CurveBasisRows {
|
|
520
|
+
return new Map(rows.map((row) => [row.symbol, contractBasis(row, bars)]));
|
|
413
521
|
}
|
|
414
522
|
|
|
415
|
-
/** The contracts a
|
|
416
|
-
export function
|
|
523
|
+
/** The contracts a known set of spot bars left blank for timing: no time of day, or no bar in their minute. */
|
|
524
|
+
export function unpairedContractCount(basis: Iterable<ContractBasis>): number {
|
|
417
525
|
let count = 0;
|
|
418
|
-
for (const row of basis) if (row.
|
|
526
|
+
for (const row of basis) if (row.unpaired) count += 1;
|
|
419
527
|
return count;
|
|
420
528
|
}
|
|
421
529
|
|
|
422
|
-
/**
|
|
423
|
-
export function thinContractsNotice(count: number): string {
|
|
424
|
-
return `Basis blank on ${count} thin contract${count === 1 ? "" : "s"} (last print over 1h before spot)`;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/** What the quote path reports of the spot itself, as the footer names it: `CCC, real-time`. Null when it reports neither. */
|
|
530
|
+
/** What the quote path reports of the spot itself, as the footer names it: `crypto composite price, real-time`. Null when it reports neither. */
|
|
428
531
|
export function curveSpotSource(spot: Pick<CurveSpot, "venue" | "feed">): string | null {
|
|
429
532
|
const parts = [spot.venue, spot.feed].filter((part): part is string => !!part);
|
|
430
533
|
return parts.length ? parts.join(", ") : null;
|
|
@@ -433,19 +536,39 @@ export function curveSpotSource(spot: Pick<CurveSpot, "venue" | "feed">): string
|
|
|
433
536
|
/** What Ann Basis is: Vs Spot is the same ratio before it is annualised. */
|
|
434
537
|
export const BASIS_FORMULA = "(Last / spot - 1) × 365 / days to expiry";
|
|
435
538
|
/** The two basis columns' convention in one line. */
|
|
436
|
-
export const BASIS_CONVENTION = `Ann Basis = ${BASIS_FORMULA}: simple actual/365,
|
|
539
|
+
export const BASIS_CONVENTION = `Ann Basis = ${BASIS_FORMULA}: simple actual/365, each last trade against spot in the same minute, `
|
|
540
|
+
+ "with days counted to final settlement at 16:00 London on the last trading day.";
|
|
437
541
|
|
|
438
|
-
/**
|
|
542
|
+
/** A gap in whole minutes as a reader counts it: `5 min`, `3 h`, `2 days`. */
|
|
543
|
+
function gapText(minutes: number): string {
|
|
544
|
+
if (minutes < 120) return `${minutes} min`;
|
|
545
|
+
const hours = Math.floor(minutes / 60);
|
|
546
|
+
return hours < 48 ? `${hours} h` : `${Math.floor(hours / 24)} days`;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/** The UTC minutes a blank names, the date only when the two fall on different days. */
|
|
550
|
+
function pairTimes(print: number, spot: number): string {
|
|
551
|
+
const [printDate, printTime] = curveTimestamp(new Date(print).toISOString()).split(" ");
|
|
552
|
+
const [spotDate, spotTime] = curveTimestamp(new Date(spot).toISOString()).split(" ");
|
|
553
|
+
return printDate === spotDate ? `print ${printTime}, nearest spot ${spotTime} UTC` : `print ${printDate} ${printTime}, nearest spot ${spotDate} ${spotTime} UTC`;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/** Why one priced-or-not contract has no basis against known spot bars, in the order `contractBasis` decides it. */
|
|
439
557
|
function blankReason(row: Pick<FuturesContract, "price" | "stale">, basis: ContractBasis): string | null {
|
|
440
558
|
if (basis.vsSpotPct != null) return null;
|
|
441
559
|
if (!positive(row.price)) return "no price";
|
|
442
560
|
if (row.stale) return "price over two sessions old";
|
|
443
|
-
|
|
561
|
+
const unpaired = basis.unpaired;
|
|
562
|
+
if (!unpaired) return null;
|
|
563
|
+
if (unpaired.print == null) return "last trade has no time of day";
|
|
564
|
+
if (unpaired.spot == null) return "no one-minute spot prices";
|
|
565
|
+
const minutes = Math.round(Math.abs(minuteOf(unpaired.print) - unpaired.spot) / MINUTE_MS);
|
|
566
|
+
return `spot and print ${gapText(minutes)} apart: ${pairTimes(unpaired.print, unpaired.spot)}`;
|
|
444
567
|
}
|
|
445
568
|
|
|
446
569
|
/**
|
|
447
|
-
* The contracts whose basis cells are blank against
|
|
448
|
-
* unexplained: the far months of a curve print rarely, and a
|
|
570
|
+
* The contracts whose basis cells are blank against known spot bars, grouped by cause and named, so a blank is
|
|
571
|
+
* never unexplained: the far months of a curve print rarely, and a trade no spot bar shares a minute with is not read.
|
|
449
572
|
*/
|
|
450
573
|
export function blankBasisNote(rows: readonly Pick<FuturesContract, "symbol" | "price" | "stale">[], basis: CurveBasisRows): string | null {
|
|
451
574
|
const groups = new Map<string, string[]>();
|
|
@@ -457,29 +580,37 @@ export function blankBasisNote(rows: readonly Pick<FuturesContract, "symbol" | "
|
|
|
457
580
|
return groups.size ? `Basis blank for ${[...groups].map(([reason, codes]) => `${codes.join(", ")} (${reason})`).join("; ")}.` : null;
|
|
458
581
|
}
|
|
459
582
|
|
|
460
|
-
/** Under this many days to expiry a few basis points of spot move the annualised rate by whole points. */
|
|
461
|
-
const SHORT_DATED_DAYS =
|
|
462
|
-
/** The noise the note sizes the swing against: ten basis points of spot, a
|
|
583
|
+
/** Under this many days to expiry a few basis points of spot move the annualised rate by whole points: Vs Spot leads and the rate is greyed. */
|
|
584
|
+
const SHORT_DATED_DAYS = 7;
|
|
585
|
+
/** The noise the note sizes the swing against: ten basis points of spot, a CME trade's usual gap to a composite price in the same minute. */
|
|
463
586
|
const SPOT_NOISE_PCT = 0.1;
|
|
464
587
|
|
|
588
|
+
/** A contract whose annualised basis is shown inside `SHORT_DATED_DAYS` of final settlement, where spot noise swamps it. */
|
|
589
|
+
export function shortDatedBasis(basis: ContractBasis | null | undefined): boolean {
|
|
590
|
+
return basis?.annualisedBasisPct != null && basis.daysToExpiry != null && basis.daysToExpiry < SHORT_DATED_DAYS;
|
|
591
|
+
}
|
|
592
|
+
|
|
465
593
|
/** The note for contracts showing an annualised basis inside `SHORT_DATED_DAYS`: what 10 bp of spot noise does to each. */
|
|
466
|
-
export function shortDatedBasisNote(rows: readonly Pick<FuturesContract, "symbol"
|
|
467
|
-
if (!spot || spot.status !== "ok" || spot.asOf == null) return null;
|
|
468
|
-
const spotTime = Date.parse(spot.asOf);
|
|
594
|
+
export function shortDatedBasisNote(rows: readonly Pick<FuturesContract, "symbol">[], basis: CurveBasisRows): string | null {
|
|
469
595
|
const near = rows.flatMap((row) => {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
596
|
+
const cell = basis.get(row.symbol);
|
|
597
|
+
if (!shortDatedBasis(cell)) return [];
|
|
598
|
+
const days = cell!.daysToExpiry!;
|
|
599
|
+
return [`${curveContractCode(row.symbol)} (${days.toFixed(1)} days) by ±${(SPOT_NOISE_PCT * 365 / days).toFixed(1)} points`];
|
|
473
600
|
});
|
|
474
|
-
return near.length ? `Ann Basis is noisy under ${SHORT_DATED_DAYS} days to expiry: 10 bp of spot noise moves ${near.join(", ")}.` : null;
|
|
601
|
+
return near.length ? `Ann Basis is noisy under ${SHORT_DATED_DAYS} days to expiry, so read Vs Spot there: 10 bp of spot noise moves ${near.join(", ")}.` : null;
|
|
475
602
|
}
|
|
476
603
|
|
|
477
|
-
/**
|
|
478
|
-
|
|
604
|
+
/**
|
|
605
|
+
* A past date for the as-of view: empty (or "latest") for the live curve, else
|
|
606
|
+
* YYYY-MM-DD no later than today. `option` is how a command line types it
|
|
607
|
+
* (`--date`), empty for the pane's field.
|
|
608
|
+
*/
|
|
609
|
+
export function curveAsOfDate(value: unknown, now = new Date(), option = ""): string {
|
|
479
610
|
const text = typeof value === "string" ? value.trim() : "";
|
|
480
611
|
if (!text || text.toLowerCase() === "latest") return "";
|
|
481
612
|
const date = readCalendarDate(text);
|
|
482
|
-
if (!date) throw new Error(
|
|
613
|
+
if (!date) throw new Error(dateOptionError(text, option, { now, subject: "an as-of date", formats: dateOptionFormatsOr("latest") }));
|
|
483
614
|
if (date > now.toISOString().slice(0, 10)) throw new Error("A futures curve cannot use a future date.");
|
|
484
615
|
return date;
|
|
485
616
|
}
|
|
@@ -531,6 +662,61 @@ export function withTradedExpirations(data: FuturesCurvePayload): FuturesCurvePa
|
|
|
531
662
|
};
|
|
532
663
|
}
|
|
533
664
|
|
|
665
|
+
/**
|
|
666
|
+
* The trading date a print belongs to, as the server dates sessions: CME's
|
|
667
|
+
* session for a date opens at 18:00 New York the evening before (22:00 or
|
|
668
|
+
* 23:00 UTC), so a two-hour shift puts those evening trades on the next date
|
|
669
|
+
* and leaves day-only venues as they are. A settlement's date is its session.
|
|
670
|
+
*/
|
|
671
|
+
function curveSessionDate(asOf: string): string {
|
|
672
|
+
return asOf.length === 10 ? asOf : new Date(Date.parse(asOf) + 2 * 3_600_000).toISOString().slice(0, 10);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* The settlement session a live contract has not traded since: its Settle
|
|
677
|
+
* column shows that session's settlement and its latest price is from that
|
|
678
|
+
* session or before. Null when it has traded since, or shows no settlement. A
|
|
679
|
+
* Cboe price is the settlement itself, so it has no trade to wait for.
|
|
680
|
+
*/
|
|
681
|
+
export function curveNoTradeSince(row: Pick<FuturesContract, "price" | "settlement" | "asOf">,
|
|
682
|
+
data: Pick<FuturesCurvePayload, "source" | "settlementDate">): string | null {
|
|
683
|
+
const session = data.settlementDate;
|
|
684
|
+
if (data.source === "cboe" || !session || row.price == null || row.settlement == null || !row.asOf) return null;
|
|
685
|
+
return curveSessionDate(row.asOf) <= session ? session : null;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* The live curve with every Change on the basis its table states: the last
|
|
690
|
+
* trade less the settlement in the Settle column. The source's session change
|
|
691
|
+
* is from the settlement before the contract's own last trade, so a back month
|
|
692
|
+
* that last traded on the settlement's session read against the session
|
|
693
|
+
* before it, beside front months read against the one shown. A contract with
|
|
694
|
+
* no trade since the settlement (curveNoTradeSince), or no settlement shown,
|
|
695
|
+
* has no change. A Cboe price is a settlement, and its change, from the
|
|
696
|
+
* settlement before, is kept.
|
|
697
|
+
*/
|
|
698
|
+
export function withSettleChanges(data: FuturesCurvePayload): FuturesCurvePayload {
|
|
699
|
+
if (data.source === "cboe") return data;
|
|
700
|
+
return { ...data, contracts: data.contracts.map((row) => {
|
|
701
|
+
const change = row.price != null && row.settlement != null && data.settlementDate && row.asOf && !curveNoTradeSince(row, data)
|
|
702
|
+
? row.price - row.settlement : null;
|
|
703
|
+
return change === (row.change ?? null) ? row : { ...row, change };
|
|
704
|
+
}) };
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* The contracts whose Change is blank because they have not traded since the
|
|
709
|
+
* settlement shown, named, in the words the basis notes use; a pane with no
|
|
710
|
+
* room for the names counts them.
|
|
711
|
+
*/
|
|
712
|
+
export function noTradeChangeNote(rows: readonly Pick<FuturesContract, "symbol" | "price" | "settlement" | "asOf">[],
|
|
713
|
+
data: Pick<FuturesCurvePayload, "source" | "settlementDate">, options: { count?: boolean } = {}): string | null {
|
|
714
|
+
const untraded = rows.filter((row) => curveNoTradeSince(row, data) != null).map((row) => curveContractCode(row.symbol));
|
|
715
|
+
if (!untraded.length) return null;
|
|
716
|
+
const named = options.count ? `on ${untraded.length} contract${untraded.length === 1 ? "" : "s"}` : `for ${untraded.join(", ")}`;
|
|
717
|
+
return `Change blank ${named} (no trade since ${data.settlementDate})${options.count ? "" : "."}`;
|
|
718
|
+
}
|
|
719
|
+
|
|
534
720
|
/**
|
|
535
721
|
* The archived curve on a past date in the live curve's shape, so the pane
|
|
536
722
|
* draws it the same way. Its week- and month-back ghosts are the curves as
|
|
@@ -566,6 +752,8 @@ export function archivedFuturesCurve(root: string, curve: FuturesCurveAsOfPayloa
|
|
|
566
752
|
const settled = contracts.filter((row) => row.settlement != null);
|
|
567
753
|
const [front, next] = settled.length >= 2 ? settled : settled.length ? [] : contracts.filter((row) => !row.stale);
|
|
568
754
|
const value = front && next ? next.price! - front.price! : null;
|
|
755
|
+
// A leg that traded under THIN_SPREAD_LOTS lots that session gets no slope call, as on the live curve.
|
|
756
|
+
const thin = [front, next].find((row) => row?.volume != null && row.volume < THIN_SPREAD_LOTS)?.symbol ?? null;
|
|
569
757
|
const days = front && next ? (Date.parse(next.expiration) - Date.parse(front.expiration)) / DAY_MS : 0;
|
|
570
758
|
const roll = front && next && front.price! > 0 && next.price! > 0 && days > 0 ? (front.price! / next.price! - 1) * 365 / days * 100 : null;
|
|
571
759
|
return {
|
|
@@ -574,7 +762,8 @@ export function archivedFuturesCurve(root: string, curve: FuturesCurveAsOfPayloa
|
|
|
574
762
|
catalogue: { method: "provider", complete: true, horizonEnd: null }, contracts, ghosts,
|
|
575
763
|
slope: { frontSymbol: front?.symbol ?? null, nextSymbol: next?.symbol ?? null, value, annualizedRollYield: roll, percentile: null,
|
|
576
764
|
rollPercentile: null, samples: 0, historyStart: null, historyEnd: null, asOf: front && next ? curve.asOf : null,
|
|
577
|
-
|
|
765
|
+
basis: front && next ? settled.length >= 2 ? "settle" : "last" : null, thinSymbol: value == null ? null : thin,
|
|
766
|
+
state: value == null ? "unavailable" : thin ? "thin" : Math.abs(value) < 1e-10 ? "flat" : value > 0 ? "contango" : "backwardation" },
|
|
578
767
|
gaps: curve.gaps, spec: curve.spec ?? null, settlementDate: settled.length ? curve.asOf : null,
|
|
579
768
|
};
|
|
580
769
|
}
|