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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
/**
|
|
2
3
|
* The land under the desktop and web map: a quiet fill, 1 px coastlines and
|
|
3
4
|
* fainter borders, at 1:50m for the world and 1:10m for the tiles in view once
|
|
@@ -67,7 +68,7 @@ function useWorldPaths(): BasemapPaths | null {
|
|
|
67
68
|
let current = true;
|
|
68
69
|
loadWorldBasemap().then((loaded) => {
|
|
69
70
|
if (current) setPaths(loaded);
|
|
70
|
-
}, (
|
|
71
|
+
}, logFailure("world-venue-map.basemap", "Load world basemap failed"));
|
|
71
72
|
return () => {
|
|
72
73
|
current = false;
|
|
73
74
|
};
|
|
@@ -83,7 +84,7 @@ function useDetailTiles(active: boolean, view: GeoBox): { tiles: DetailTile[]; l
|
|
|
83
84
|
let current = true;
|
|
84
85
|
loadDetailIndex().then((tiles) => {
|
|
85
86
|
if (current) setIndex(tiles);
|
|
86
|
-
}, (
|
|
87
|
+
}, logFailure("world-venue-map.basemap", "Load detail tile index failed"));
|
|
87
88
|
return () => {
|
|
88
89
|
current = false;
|
|
89
90
|
};
|
|
@@ -105,7 +106,7 @@ function useDetailTiles(active: boolean, view: GeoBox): { tiles: DetailTile[]; l
|
|
|
105
106
|
while (next.size > TILE_CACHE_SIZE) next.delete(next.keys().next().value!);
|
|
106
107
|
return next;
|
|
107
108
|
});
|
|
108
|
-
}, (
|
|
109
|
+
}, logFailure("world-venue-map.basemap", "Load detail tile failed"));
|
|
109
110
|
}
|
|
110
111
|
return () => {
|
|
111
112
|
current = false;
|
|
@@ -221,7 +221,9 @@ export function loadDetailTile(tile: DetailTile): Promise<BasemapPaths> {
|
|
|
221
221
|
const pending = tile.load()
|
|
222
222
|
.then((chunk) => {
|
|
223
223
|
const decoded = decodeQueue.then(nextTask).then(() => basemapPaths(chunk, tile.box));
|
|
224
|
-
decodeQueue = decoded.catch(() => {
|
|
224
|
+
decodeQueue = decoded.catch(() => {
|
|
225
|
+
// Intentional ignore: keep the decode queue usable; the returned decoded promise still rejects to the tile caller.
|
|
226
|
+
});
|
|
225
227
|
return decoded;
|
|
226
228
|
})
|
|
227
229
|
.catch((error: unknown) => {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { GeoRequest } from "../../../api-client/geo";
|
|
2
|
+
import { SERIES_COLORS } from "../../../theme/series-colors";
|
|
3
|
+
import type { PaneTemplateInstanceConfig } from "../../../types/plugin";
|
|
4
|
+
import { buildCustomChartPreset } from "../chart-composer/presets";
|
|
5
|
+
import { formatGeoSeriesExpression } from "../chart-composer/series-expression";
|
|
6
|
+
import { chokepointSeriesFor, chokepointSeriesIds, chokepointShortName, KEY_CHOKEPOINTS, unknownChokepointMessage } from "./geo-series";
|
|
7
|
+
|
|
8
|
+
const CHOKE_SERIES_LIMIT = 6;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* CHOKE's chart: the key straits' daily transits together, or the one the
|
|
12
|
+
* argument names. Text that names no strait (a ticker) is told which do, as
|
|
13
|
+
* COT and PSD tell an unknown market or crop, rather than charting nothing.
|
|
14
|
+
*/
|
|
15
|
+
export async function createChokepointInstance(request: GeoRequest, arg?: string): Promise<PaneTemplateInstanceConfig> {
|
|
16
|
+
const typed = arg?.trim();
|
|
17
|
+
const named = typed ? await chokepointSeriesFor(request, typed) : null;
|
|
18
|
+
if (typed && !named) throw new Error(unknownChokepointMessage(typed));
|
|
19
|
+
const ids = named
|
|
20
|
+
? [named]
|
|
21
|
+
// Without the series index, CHOKE still asks for the key straits by name.
|
|
22
|
+
: await chokepointSeriesIds(request).then((found) => (found.length ? found : KEY_CHOKEPOINTS)).catch(() => KEY_CHOKEPOINTS);
|
|
23
|
+
const charted = ids.slice(0, CHOKE_SERIES_LIMIT);
|
|
24
|
+
const base = buildCustomChartPreset(charted.map(formatGeoSeriesExpression).join(", "));
|
|
25
|
+
// Daily transits read best over a year, each strait in its own colour. Six together
|
|
26
|
+
// take short names so the legend shows each whole; one strait keeps the index's full name.
|
|
27
|
+
const spec = {
|
|
28
|
+
...base,
|
|
29
|
+
viewport: { ...base.viewport, range: "1Y" as const },
|
|
30
|
+
series: base.series.map((series, index) => {
|
|
31
|
+
const label = named ? undefined : chokepointShortName(charted[index] ?? "");
|
|
32
|
+
return { ...series, color: series.color ?? SERIES_COLORS[index % SERIES_COLORS.length]!, ...(label ? { label } : {}) };
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
title: named ? `G ${named} transits` : "G Chokepoint transits",
|
|
37
|
+
placement: "floating",
|
|
38
|
+
settings: { chartSpec: spec },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* What `
|
|
2
|
+
* What `gloom shot MAP <layers>` certifies: the layers the map drew and
|
|
3
3
|
* what each held, so a capture taken before the features arrived is refused.
|
|
4
4
|
*/
|
|
5
5
|
import type { PaneScreenshotEvidenceHook } from "../../../cli/pane-functions/screenshot-evidence";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ApiRequestError } from "../../../api-client/errors";
|
|
2
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
3
|
/**
|
|
2
4
|
* Map series in G: numbers over time for things with a place (chokepoint
|
|
3
5
|
* transits, port calls). `GEO:<id or alias>` resolves through the server's
|
|
@@ -54,9 +56,20 @@ export async function resolveGeoChartSeries(
|
|
|
54
56
|
viewport: ChartViewportSpec,
|
|
55
57
|
signal?: AbortSignal,
|
|
56
58
|
): Promise<ResolvedSeries> {
|
|
57
|
-
|
|
59
|
+
let indexFailed = false;
|
|
60
|
+
const hit = await resolveGeoSeries(request, token, signal).catch((error: unknown) => {
|
|
61
|
+
if (signal?.aborted) throw error;
|
|
62
|
+
logFailure("world-venue-map.geo-series", "Resolve map series failed")(error);
|
|
63
|
+
indexFailed = true;
|
|
64
|
+
return null;
|
|
65
|
+
});
|
|
58
66
|
const payload = await getGeoSeries(request, hit?.id ?? token, geoSeriesRange(viewport), signal).catch((error: unknown) => {
|
|
59
|
-
|
|
67
|
+
if (signal?.aborted) throw error;
|
|
68
|
+
if (hit) throw error;
|
|
69
|
+
if (!indexFailed && error instanceof ApiRequestError && error.status === 404) {
|
|
70
|
+
throw new Error(`No map series named ${token}.`);
|
|
71
|
+
}
|
|
72
|
+
throw new Error("Map series unavailable.", { cause: error });
|
|
60
73
|
});
|
|
61
74
|
const points: TimeSeriesPoint[] = (payload.points ?? []).flatMap(([day, value]) => {
|
|
62
75
|
const date = new Date(`${day}T00:00:00Z`);
|
|
@@ -83,7 +96,11 @@ export async function resolveGeoChartSeries(
|
|
|
83
96
|
|
|
84
97
|
export function createGeoChartSeriesCapability(request: GeoRequest = cloudGeoRequest): ChartSeriesCapability {
|
|
85
98
|
const search = async (query: string, limit: number, signal?: AbortSignal) => {
|
|
86
|
-
const { series } = await searchGeoSeries(request, query, signal).catch(() =>
|
|
99
|
+
const { series } = await searchGeoSeries(request, query, signal).catch((error: unknown) => {
|
|
100
|
+
if (signal?.aborted) throw error;
|
|
101
|
+
logFailure("world-venue-map.geo-series", "Search map series failed")(error);
|
|
102
|
+
throw new Error("Map series search unavailable.", { cause: error });
|
|
103
|
+
});
|
|
87
104
|
return series.slice(0, limit).map(catalogItem);
|
|
88
105
|
};
|
|
89
106
|
return chartSeriesProvider({
|
|
@@ -118,6 +135,25 @@ const CHOKEPOINT_NAMES: Readonly<Record<string, string>> = {
|
|
|
118
135
|
BOSPHORUS: "Bosphorus",
|
|
119
136
|
};
|
|
120
137
|
|
|
138
|
+
/**
|
|
139
|
+
* The key straits as a legend of all six can carry them: the full series
|
|
140
|
+
* names ("Strait of Hormuz transits") would be cut to a fragment each. The
|
|
141
|
+
* chart's title and unit already say these are transits.
|
|
142
|
+
*/
|
|
143
|
+
const CHOKEPOINT_SHORT_NAMES: Readonly<Record<string, string>> = {
|
|
144
|
+
SUEZ: "Suez",
|
|
145
|
+
PANAMA: "Panama",
|
|
146
|
+
HORMUZ: "Hormuz",
|
|
147
|
+
BABELMANDEB: "Bab el-Mandeb",
|
|
148
|
+
MALACCA: "Malacca",
|
|
149
|
+
BOSPHORUS: "Bosphorus",
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/** A key strait's short legend name; undefined for any other series, which keeps the name the index gives it. */
|
|
153
|
+
export function chokepointShortName(alias: string): string | undefined {
|
|
154
|
+
return CHOKEPOINT_SHORT_NAMES[alias.toUpperCase()];
|
|
155
|
+
}
|
|
156
|
+
|
|
121
157
|
/**
|
|
122
158
|
* Who publishes the chokepoints' daily transits, as the server's chokepoints
|
|
123
159
|
* layer names them (`publisher`); the catalog lists the key straits offline.
|
|
@@ -161,16 +197,59 @@ export async function chokepointSeriesIds(request: GeoRequest, signal?: AbortSig
|
|
|
161
197
|
});
|
|
162
198
|
}
|
|
163
199
|
|
|
200
|
+
/** A series' chokepoint as the index names it: "Strait of Hormuz transits" is "Strait of Hormuz". */
|
|
201
|
+
function chokepointName(seriesName: string): string {
|
|
202
|
+
return seriesName.replace(/\s+transits$/i, "");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** A chokepoint's name without what straits and canals share ("Strait of Hormuz" is Hormuz, "Suez Canal" Suez), as it is typed short. */
|
|
206
|
+
function chokepointCore(name: string): string {
|
|
207
|
+
return compact(chokepointName(name)
|
|
208
|
+
.replace(/^strait of\s+/i, "")
|
|
209
|
+
.replace(/\s+(strait|canal|channel|passage)$/i, ""));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function matchIndexedChokepoint(series: readonly GeoSeriesSearchHit[], wanted: string): string | null {
|
|
213
|
+
const chokepoints = series.filter((hit) => hit.layer === CHOKEPOINTS_LAYER && hit.alias);
|
|
214
|
+
// A main transit series has the plain alias (SUEZ), its splits a suffix (SUEZ.TANKER).
|
|
215
|
+
const exact = chokepoints.find((hit) => compact(hit.alias!) === wanted);
|
|
216
|
+
if (exact) return exact.alias!;
|
|
217
|
+
const main = chokepoints.filter((hit) => !hit.alias!.includes("."));
|
|
218
|
+
const named = main.find((hit) => compact(chokepointName(hit.name)) === wanted || chokepointCore(hit.name) === wanted);
|
|
219
|
+
if (named) return named.alias!;
|
|
220
|
+
// Part of one strait's name ("mandeb") finds it; part of several ("strait") names none.
|
|
221
|
+
return main.length === 1 ? main[0]!.alias! : null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function matchKeyChokepoint(wanted: string): string | null {
|
|
225
|
+
return KEY_CHOKEPOINTS.find((alias) => alias === wanted || compact(CHOKEPOINT_NAMES[alias] ?? "") === wanted
|
|
226
|
+
|| chokepointCore(CHOKEPOINT_NAMES[alias] ?? "") === wanted) ?? null;
|
|
227
|
+
}
|
|
228
|
+
|
|
164
229
|
/**
|
|
165
230
|
* The series a typed chokepoint names: "suez", "Bab el-Mandeb" and "Strait
|
|
166
|
-
* of Hormuz" all find the strait's main transit series.
|
|
231
|
+
* of Hormuz" all find the strait's main transit series. Null for text that
|
|
232
|
+
* names no chokepoint (a ticker), so CHOKE can say which exist. Without the
|
|
233
|
+
* series index, the key straits are still known by name.
|
|
167
234
|
*/
|
|
168
|
-
export async function chokepointSeriesFor(request: GeoRequest, typed: string, signal?: AbortSignal): Promise<string> {
|
|
235
|
+
export async function chokepointSeriesFor(request: GeoRequest, typed: string, signal?: AbortSignal): Promise<string | null> {
|
|
169
236
|
const wanted = compact(typed);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
237
|
+
if (!wanted) return null;
|
|
238
|
+
let series: GeoSeriesSearchHit[];
|
|
239
|
+
try {
|
|
240
|
+
({ series } = await searchGeoSeries(request, typed, signal));
|
|
241
|
+
} catch (error) {
|
|
242
|
+
if (signal?.aborted) throw error;
|
|
243
|
+
logFailure("world-venue-map.geo-series", "Find chokepoint series failed")(error);
|
|
244
|
+
const known = matchKeyChokepoint(wanted);
|
|
245
|
+
if (known) return known;
|
|
246
|
+
throw new Error("Chokepoint search unavailable. Try again.", { cause: error });
|
|
247
|
+
}
|
|
248
|
+
return matchIndexedChokepoint(series, wanted) ?? matchKeyChokepoint(wanted);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** What CHOKE tells text that names no chokepoint: the key straits, as it takes them typed. */
|
|
252
|
+
export function unknownChokepointMessage(typed: string): string {
|
|
253
|
+
const names = KEY_CHOKEPOINTS.map((alias) => (CHOKEPOINT_SHORT_NAMES[alias] ?? alias).toUpperCase());
|
|
254
|
+
return `No chokepoint named ${typed.trim()}. Try CHOKE ${names.slice(0, -1).join(", ")} or ${names.at(-1)}.`;
|
|
176
255
|
}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { peekGeoCatalog } from "../../../api-client/geo";
|
|
2
|
-
import { SERIES_COLORS } from "../../../theme/series-colors";
|
|
3
2
|
import { CHART_COMPOSER_PANE_ID } from "../../../types/config";
|
|
4
3
|
import type { PaneTemplateDef } from "../../../types/plugin";
|
|
5
4
|
import { chartHeadless } from "../chart-composer/headless";
|
|
6
|
-
import { buildCustomChartPreset } from "../chart-composer/presets";
|
|
7
|
-
import { formatGeoSeriesExpression } from "../chart-composer/series-expression";
|
|
8
5
|
import type { PluginModule } from "../plugin-module";
|
|
6
|
+
import { createChokepointInstance } from "./chokepoint-chart";
|
|
9
7
|
import { cloudGeoRequest } from "./client";
|
|
10
|
-
import {
|
|
8
|
+
import { CHOKEPOINT_SERIES, createGeoChartSeriesCapability } from "./geo-series";
|
|
11
9
|
import { mapHeadless } from "./headless";
|
|
12
10
|
import { buildMapSettingsDef, groupTitle, MAP_PRESET_OPTIONS, parseMapPreset } from "./layers";
|
|
13
11
|
import { WORLD_VENUE_MAP_PANE_ID, WorldVenueMapPane } from "./pane";
|
|
14
12
|
|
|
15
|
-
const CHOKE_SERIES_LIMIT = 6;
|
|
16
|
-
|
|
17
13
|
const chartComposerHeadless = chartHeadless("chart-composer-pane");
|
|
18
14
|
|
|
19
15
|
const chokepointTemplate: PaneTemplateDef = {
|
|
@@ -37,26 +33,7 @@ const chokepointTemplate: PaneTemplateDef = {
|
|
|
37
33
|
keywords: ["chokepoint", "chokepoints", "transits", "suez", "panama", "hormuz", "malacca", "shipping", "strait", "canal"],
|
|
38
34
|
shortcut: { prefix: "CHOKE", argPlaceholder: "chokepoint", argKind: "text", argOptional: true },
|
|
39
35
|
canCreate: () => true,
|
|
40
|
-
createInstance:
|
|
41
|
-
const typed = options?.arg?.trim();
|
|
42
|
-
const named = typed ? await chokepointSeriesFor(cloudGeoRequest, typed) : null;
|
|
43
|
-
const ids = named
|
|
44
|
-
? [named]
|
|
45
|
-
// Without the series index, CHOKE still asks for the key straits by name.
|
|
46
|
-
: await chokepointSeriesIds(cloudGeoRequest).then((found) => (found.length ? found : KEY_CHOKEPOINTS)).catch(() => KEY_CHOKEPOINTS);
|
|
47
|
-
const base = buildCustomChartPreset(ids.slice(0, CHOKE_SERIES_LIMIT).map(formatGeoSeriesExpression).join(", "));
|
|
48
|
-
// Daily transits read best over a year, each strait in its own colour.
|
|
49
|
-
const spec = {
|
|
50
|
-
...base,
|
|
51
|
-
viewport: { ...base.viewport, range: "1Y" as const },
|
|
52
|
-
series: base.series.map((series, index) => ({ ...series, color: series.color ?? SERIES_COLORS[index % SERIES_COLORS.length]! })),
|
|
53
|
-
};
|
|
54
|
-
return {
|
|
55
|
-
title: named ? `G ${named} transits` : "G Chokepoint transits",
|
|
56
|
-
placement: "floating",
|
|
57
|
-
settings: { chartSpec: spec },
|
|
58
|
-
};
|
|
59
|
-
},
|
|
36
|
+
createInstance: (_context, options) => createChokepointInstance(cloudGeoRequest, options?.arg),
|
|
60
37
|
};
|
|
61
38
|
|
|
62
39
|
export const worldVenueMapModule: PluginModule = {
|
|
@@ -163,7 +163,7 @@ const LAYER_COVERAGE: Readonly<Record<string, string>> = {
|
|
|
163
163
|
|
|
164
164
|
/**
|
|
165
165
|
* Why a layer can have nothing for a search or a view outside its region:
|
|
166
|
-
* "Terminals cover the United States only (as of
|
|
166
|
+
* "Terminals cover the United States only (as of 1 Oct 2026)." Null for a
|
|
167
167
|
* worldwide layer.
|
|
168
168
|
*/
|
|
169
169
|
export function layerCoverageNote(layer: Pick<GeoLayerInfo, "id" | "name" | "asOf" | "cadence">): string | null {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
1
2
|
import { createElement, useCallback, useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointerEvent } from "react";
|
|
2
3
|
import type { CloudWorldVenuePayload } from "../../../api-client";
|
|
3
4
|
import { Box, ChartSurface, Text, useNativeRenderer, useUiCapabilities, useUiHost } from "../../../ui";
|
|
@@ -399,7 +400,7 @@ function useCountryLabels(): readonly CountryLabel[] | null {
|
|
|
399
400
|
let current = true;
|
|
400
401
|
loadCountryLabels().then((loaded) => {
|
|
401
402
|
if (current) setLabels(loaded);
|
|
402
|
-
}, (
|
|
403
|
+
}, logFailure("world-venue-map.map", "Load country labels failed"));
|
|
403
404
|
return () => {
|
|
404
405
|
current = false;
|
|
405
406
|
};
|
|
@@ -21,6 +21,7 @@ import { useAsyncResource, usePaneSettingValue, usePluginPaneState } from "../..
|
|
|
21
21
|
import { colors } from "../../../theme/colors";
|
|
22
22
|
import type { PaneProps } from "../../../types/plugin";
|
|
23
23
|
import { Box, TextAttributes, useUiCapabilities } from "../../../ui";
|
|
24
|
+
import { withCountryFlag } from "../../../components/ui/country-flag";
|
|
24
25
|
import { loadWorldVenues } from "./client";
|
|
25
26
|
import { WORLD_VENUE_MAP_PANE_ID } from "./ids";
|
|
26
27
|
import { LayeredMapView } from "./layered-pane";
|
|
@@ -160,11 +161,12 @@ function VenueMapView({ focused, width, height }: PaneProps) {
|
|
|
160
161
|
case "mic":
|
|
161
162
|
return { text: venue.mic, color: colors.textBright, attributes: TextAttributes.BOLD };
|
|
162
163
|
case "name":
|
|
163
|
-
|
|
164
|
+
// The desktop and the web lead each venue with its country's flag.
|
|
165
|
+
return withCountryFlag({ text: venue.title, color: colors.textMuted }, venue.countryCode, nativePaneChrome === true);
|
|
164
166
|
case "time":
|
|
165
167
|
return { text: formatVenueLocalTime(venue.timezone, now), color: colors.textDim };
|
|
166
168
|
}
|
|
167
|
-
}, [now]);
|
|
169
|
+
}, [nativePaneChrome, now]);
|
|
168
170
|
|
|
169
171
|
const sidebarHeader = (
|
|
170
172
|
<QueryBar
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CloudWorldVenuePayload } from "../../../api-client";
|
|
2
2
|
import { colors } from "../../../theme/colors";
|
|
3
|
-
import {
|
|
3
|
+
import { CountryFlagLead } from "../../../components/ui/country-flag";
|
|
4
|
+
import { Box, Text, TextAttributes, useUiCapabilities } from "../../../ui";
|
|
4
5
|
import { formatVenueCountdown, formatVenueLocalTime, venueRemainingSeconds } from "./model";
|
|
5
6
|
|
|
6
7
|
export function SelectedVenueHeader({
|
|
@@ -14,19 +15,29 @@ export function SelectedVenueHeader({
|
|
|
14
15
|
now: number;
|
|
15
16
|
width: number;
|
|
16
17
|
}) {
|
|
18
|
+
const desktop = useUiCapabilities().nativePaneChrome === true;
|
|
17
19
|
if (!venue) return <Box height={2} />;
|
|
18
20
|
const remaining = formatVenueCountdown(venueRemainingSeconds(venue, checkedAt, now));
|
|
19
21
|
const state = venue.isOpen ? "OPEN" : "CLOSED";
|
|
20
22
|
const transition = remaining ? `${venue.isOpen ? "closes" : "opens"} ${remaining}` : "";
|
|
23
|
+
const place = (
|
|
24
|
+
<Text fg={colors.textMuted}>
|
|
25
|
+
{`${venue.city}, ${venue.country} · ${formatVenueLocalTime(venue.timezone, now)}${transition ? ` · ${transition}` : ""}`}
|
|
26
|
+
</Text>
|
|
27
|
+
);
|
|
21
28
|
return (
|
|
22
29
|
<Box flexDirection="column" height={2} width={width} paddingX={1}>
|
|
23
30
|
<Box flexDirection="row" justifyContent="space-between" width="100%">
|
|
24
31
|
<Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{venue.mic}</Text>
|
|
25
32
|
<Text fg={venue.isOpen ? colors.positive : colors.textDim}>{state}</Text>
|
|
26
33
|
</Box>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
{desktop ? (
|
|
35
|
+
// The desktop and the web lead the venue's place with its country's flag.
|
|
36
|
+
<Box flexDirection="row" alignItems="center">
|
|
37
|
+
<CountryFlagLead value={venue.countryCode} />
|
|
38
|
+
{place}
|
|
39
|
+
</Box>
|
|
40
|
+
) : place}
|
|
30
41
|
</Box>
|
|
31
42
|
);
|
|
32
43
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { apiClient } from "../../../api-client";
|
|
2
|
+
import type { SwapCurvePayload, SwapTenor } from "../../../api-client/swap-curve";
|
|
3
|
+
import { createPluginCache } from "../../../data/plugin-cache";
|
|
4
|
+
import { cachedCloudResource, loadCloudResource, unavailableOnServer } from "../shared/cloud-resource";
|
|
5
|
+
import { validateSwapCurve } from "./swaps-model";
|
|
6
|
+
|
|
7
|
+
export const swapCurveCache = createPluginCache<SwapCurvePayload>({
|
|
8
|
+
kind: "sofr-swap-curve", source: "gloom-cloud", schemaVersion: 1,
|
|
9
|
+
policy: { staleMs: 60 * 60_000, expireMs: 7 * 24 * 60 * 60_000 },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export async function fetchSwapCurve(tenor: SwapTenor,
|
|
13
|
+
client: Pick<typeof apiClient, "getCloudSwapCurve"> = apiClient): Promise<SwapCurvePayload> {
|
|
14
|
+
try {
|
|
15
|
+
const payload = validateSwapCurve(await client.getCloudSwapCurve(tenor, 365));
|
|
16
|
+
if (payload.history.tenor !== tenor) throw new Error("The server returned history for a different swap tenor");
|
|
17
|
+
return payload;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw unavailableOnServer(error, "SOFR swap rates are not available yet.");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const getCachedSwapCurve = (tenor: SwapTenor) => cachedCloudResource(swapCurveCache, tenor, validateSwapCurve);
|
|
24
|
+
export const loadSwapCurve = (tenor: SwapTenor, force = false) =>
|
|
25
|
+
loadCloudResource(swapCurveCache, tenor, () => fetchSwapCurve(tenor), { force, validate: validateSwapCurve });
|
|
@@ -5,7 +5,7 @@ import type { MoveHorizon } from "../shared/move-rank";
|
|
|
5
5
|
import type { CurveBasis } from "./forward";
|
|
6
6
|
import { yieldSpreads, type YieldLookbackCurves } from "./chart";
|
|
7
7
|
import { completeYieldCurve, loadHistoricalYieldCurve, yieldCurveDate } from "./history";
|
|
8
|
-
import { DATE_OPTION_FORMATS, readCalendarDate } from "../../../utils/calendar-date";
|
|
8
|
+
import { DATE_OPTION_FORMATS, dateOptionHint, readCalendarDate } from "../../../utils/calendar-date";
|
|
9
9
|
import { isYieldObservationDate, loadYieldCurve, type YieldPoint } from "./treasury-data";
|
|
10
10
|
|
|
11
11
|
export type CurveId = CloudCurveId;
|
|
@@ -178,7 +178,7 @@ export async function loadComparePoints(curve: CurveId, date: string, client: Cu
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
const RELATIVE = /^(\d{1,2})([DWMY])$/i;
|
|
181
|
-
const
|
|
181
|
+
const COMPARE_FORMS = `Compare with a date as ${DATE_OPTION_FORMATS}, or a span such as 1D, 1W, 3M or 1Y`;
|
|
182
182
|
|
|
183
183
|
/** A span back from the session (1D, 1W, 3M, 1Y): what the compare field takes besides a date. */
|
|
184
184
|
export function isCompareSpan(value: string): boolean {
|
|
@@ -191,12 +191,15 @@ export function isCompareSpan(value: string): boolean {
|
|
|
191
191
|
* session (1D, 1W, 3M, 1Y). Empty turns comparing off. Anything else gets the
|
|
192
192
|
* help for both forms, not the as-of field's date-only message.
|
|
193
193
|
*/
|
|
194
|
-
export function parseCompareInput(value: string, now = new Date()): string {
|
|
194
|
+
export function parseCompareInput(value: string, now = new Date(), option = ""): string {
|
|
195
195
|
const text = value.trim();
|
|
196
196
|
if (!text) return "";
|
|
197
197
|
if (isCompareSpan(text)) return text.toUpperCase();
|
|
198
198
|
const date = readCalendarDate(text);
|
|
199
|
-
if (!date)
|
|
199
|
+
if (!date) {
|
|
200
|
+
const hint = dateOptionHint(text, option);
|
|
201
|
+
throw new Error(hint ? `${COMPARE_FORMS}: ${hint}.` : `${COMPARE_FORMS}.`);
|
|
202
|
+
}
|
|
200
203
|
return yieldCurveDate(date, now);
|
|
201
204
|
}
|
|
202
205
|
|
|
@@ -12,6 +12,9 @@ import { loadYieldCurveLookbacks, yieldCurveDate } from "./history";
|
|
|
12
12
|
import { loadWorldRows, type WorldRow } from "./world";
|
|
13
13
|
import { formatBasisPoints, toBasisPoints } from "../../../utils/basis-points";
|
|
14
14
|
import { DATE_OPTION_EXAMPLES } from "../../../utils/calendar-date";
|
|
15
|
+
import { SWAP_TENORS, type SwapCurvePayload, type SwapTenor } from "../../../api-client/swap-curve";
|
|
16
|
+
import { fetchSwapCurve } from "./client";
|
|
17
|
+
import { formatSwapBp, selectedSwapTenor } from "./swaps-model";
|
|
15
18
|
|
|
16
19
|
const percent = (value: unknown) => value == null ? "-" : `${Number(value).toFixed(2)}%`;
|
|
17
20
|
/** A move already in basis points: `+3bp`, `-1bp`, `0bp`. */
|
|
@@ -65,6 +68,14 @@ const WORLD_COLUMNS = [
|
|
|
65
68
|
{ key: "tenYearChangeBasisPoints", header: "10Y 1D bp", align: "right" as const, format: basisPoints },
|
|
66
69
|
{ key: "asOf", header: "As of" },
|
|
67
70
|
];
|
|
71
|
+
const SWAP_COLUMNS = [
|
|
72
|
+
{ key: "tenor", header: "Tenor" },
|
|
73
|
+
{ key: "rate", header: "Rate %", align: "right" as const, format: percent },
|
|
74
|
+
{ key: "changeBp", header: "1D bp", align: "right" as const, format: (value: unknown) => value == null ? "-" : formatSwapBp(Number(value)) },
|
|
75
|
+
{ key: "spreadBp", header: "Spread bp", align: "right" as const, format: (value: unknown) => value == null ? "-" : formatSwapBp(Number(value)) },
|
|
76
|
+
{ key: "tradeCount", header: "Trades", align: "right" as const,
|
|
77
|
+
format: (value: unknown, row: Record<string, unknown>) => `${value}${row.quality === "thin" ? " Thin" : ""}` },
|
|
78
|
+
];
|
|
68
79
|
|
|
69
80
|
export interface YieldCurveHeadlessDependencies {
|
|
70
81
|
load(curve: CurveId, requestedDate: string, context: HeadlessPaneContext): Promise<CurveData>;
|
|
@@ -72,6 +83,7 @@ export interface YieldCurveHeadlessDependencies {
|
|
|
72
83
|
/** The 1D, 1W and 1M curves of a session, for a curve loaded without them (the FRED fallback). */
|
|
73
84
|
lookbacks?(session: string, context: HeadlessPaneContext): Promise<YieldLookbackCurves>;
|
|
74
85
|
world?(context: HeadlessPaneContext): Promise<WorldRow[]>;
|
|
86
|
+
swaps?(tenor: SwapTenor, context: HeadlessPaneContext): Promise<SwapCurvePayload>;
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
const defaultDependencies: Required<YieldCurveHeadlessDependencies> = {
|
|
@@ -82,6 +94,7 @@ const defaultDependencies: Required<YieldCurveHeadlessDependencies> = {
|
|
|
82
94
|
.map((lookback) => [lookback.id, lookback.points]),
|
|
83
95
|
),
|
|
84
96
|
world: (context) => loadWorldRows(context.apiClient),
|
|
97
|
+
swaps: (tenor, context) => fetchSwapCurve(tenor, context.apiClient),
|
|
85
98
|
};
|
|
86
99
|
|
|
87
100
|
const bp = (value: number | null) => value == null ? null : Math.round(value * 100);
|
|
@@ -116,6 +129,7 @@ export function createYieldCurveHeadless(
|
|
|
116
129
|
const loadCompare = dependencies.compare ?? defaultDependencies.compare;
|
|
117
130
|
const loadLookbacks = dependencies.lookbacks ?? defaultDependencies.lookbacks;
|
|
118
131
|
const loadWorld = dependencies.world ?? defaultDependencies.world;
|
|
132
|
+
const loadSwaps = dependencies.swaps ?? defaultDependencies.swaps;
|
|
119
133
|
return {
|
|
120
134
|
shape: "rows",
|
|
121
135
|
argument: { kind: "free-text", optional: true, placeholder: "[curve] [date]",
|
|
@@ -129,14 +143,21 @@ export function createYieldCurveHeadless(
|
|
|
129
143
|
pluginState: { pluginId: "macro", key: "yield-curve:view" } },
|
|
130
144
|
{ key: "forward", type: "boolean", description: "Overlay the one-year-forward curve on the chart.",
|
|
131
145
|
pluginState: { pluginId: "macro", key: "yield-curve:forward" } },
|
|
132
|
-
{ key: "tab", type: "enum", values: [{ value: "curve" }, { value: "world" }],
|
|
133
|
-
description: "curve (default),
|
|
146
|
+
{ key: "tab", type: "enum", values: [{ value: "curve" }, { value: "world" }, { value: "swaps" }],
|
|
147
|
+
description: "curve (default), world (government yields), or swaps (USD SOFR rates and Treasury swap spreads). Spreads use native quotes: annual ACT/360 OIS versus semiannual bond-equivalent Treasury yields.",
|
|
134
148
|
pluginState: { pluginId: "macro", key: "yield-curve:tab" } },
|
|
149
|
+
{ key: "tenor", type: "enum", values: SWAP_TENORS.map((value) => ({ value })),
|
|
150
|
+
description: "Swaps history tenor (default 10Y); the curve table always includes every tenor.",
|
|
151
|
+
pluginState: { pluginId: "macro", key: "yield-curve:swap-tenor" } },
|
|
152
|
+
{ key: "swap-view", type: "enum", values: [{ value: "curve" }, { value: "history" }],
|
|
153
|
+
description: "Swaps chart: current curve with 1W/1M comparisons, or the selected tenor's history.",
|
|
154
|
+
pluginState: { pluginId: "macro", key: "yield-curve:swap-view" } },
|
|
135
155
|
],
|
|
136
156
|
columns: COLUMNS,
|
|
137
157
|
// The title names the curve, as the pane's Curve select does.
|
|
138
158
|
describe: (args) => {
|
|
139
159
|
if (args.options.tab === "world") return "Yield Curves | World";
|
|
160
|
+
if (args.options.tab === "swaps") return "Yield Curves | USD SOFR Swaps";
|
|
140
161
|
try {
|
|
141
162
|
const curve = curveIdOf(args.options.curve) ?? parseCurveArgument(args.argument).curve ?? "us";
|
|
142
163
|
return `Yield Curves | ${curveOption(curve).label}`;
|
|
@@ -145,6 +166,19 @@ export function createYieldCurveHeadless(
|
|
|
145
166
|
}
|
|
146
167
|
},
|
|
147
168
|
async load(args, context) {
|
|
169
|
+
if (args.options.tab === "swaps") {
|
|
170
|
+
const data = await loadSwaps(selectedSwapTenor(args.options.tenor), context);
|
|
171
|
+
return {
|
|
172
|
+
freshness: { source: "DTCC public swap reports", status: "not-a-feed", basis: "daily trade estimates", cadence: "daily",
|
|
173
|
+
tradingDayMarket: "US" },
|
|
174
|
+
columns: SWAP_COLUMNS,
|
|
175
|
+
rows: (data.asOf ? data.points : []).map((point) => ({ ...point, asOf: data.asOf })),
|
|
176
|
+
metadata: { currency: data.currency, benchmark: data.benchmark, units: "Percent", changeUnit: "Basis points",
|
|
177
|
+
asOf: data.asOf, fetchedAt: data.fetchedAt, stale: data.stale, previousDate: data.previousDate,
|
|
178
|
+
treasuryDate: data.treasuryDate, comparisons: data.comparisons, history: data.history },
|
|
179
|
+
errors: !data.asOf ? ["No swap rates yet."] : data.stale ? ["The swap curve is stale."] : [],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
148
182
|
if (args.options.tab === "world") {
|
|
149
183
|
const rows = await loadWorld(context);
|
|
150
184
|
return {
|
|
@@ -161,8 +195,8 @@ export function createYieldCurveHeadless(
|
|
|
161
195
|
throw new Error(`Unknown curve ${String(args.options.curve)}; use ${CURVE_OPTIONS.map((option) => option.aliases[0]).join(", ")}.`);
|
|
162
196
|
}
|
|
163
197
|
const curve = optionCurve ?? argument.curve ?? "us";
|
|
164
|
-
const requestedDate = args.options.date != null ? yieldCurveDate(args.options.date) : argument.date;
|
|
165
|
-
const compareInput = args.options.compare == null ? "" : parseCompareInput(String(args.options.compare));
|
|
198
|
+
const requestedDate = args.options.date != null ? yieldCurveDate(args.options.date, new Date(), "--date") : argument.date;
|
|
199
|
+
const compareInput = args.options.compare == null ? "" : parseCompareInput(String(args.options.compare), new Date(), "--compare");
|
|
166
200
|
const data = await dependencies.load(curve, requestedDate, context);
|
|
167
201
|
const points = data.points;
|
|
168
202
|
const session = curveAsOf(points);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { apiClient, type CloudFredSeriesPayload } from "../../../api-client";
|
|
2
2
|
import { isYieldObservationDate, TREASURY_MATURITIES, type YieldPoint } from "./treasury-data";
|
|
3
|
-
import {
|
|
3
|
+
import { dateOptionError, dateOptionFormatsOr, readCalendarDate } from "../../../utils/calendar-date";
|
|
4
4
|
|
|
5
5
|
const DAY_MS = 86_400_000;
|
|
6
6
|
export type TreasurySeriesLoader = (seriesId: string, options: {
|
|
@@ -10,12 +10,13 @@ export type TreasurySeriesLoader = (seriesId: string, options: {
|
|
|
10
10
|
sortOrder: "desc";
|
|
11
11
|
}) => Promise<CloudFredSeriesPayload>;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/** An as-of date, or "latest" (empty) for the newest session; `option` is how a command line types it (`--date`), empty for the pane's field. */
|
|
14
|
+
export function yieldCurveDate(value: unknown, now = new Date(), option = ""): string {
|
|
14
15
|
if (value == null) return "";
|
|
15
16
|
const text = typeof value === "string" ? value.trim() : "";
|
|
16
17
|
if (typeof value === "string" && (text === "" || text.toLowerCase() === "latest")) return "";
|
|
17
18
|
const date = readCalendarDate(text);
|
|
18
|
-
if (!date) throw new Error(
|
|
19
|
+
if (!date) throw new Error(dateOptionError(text, option, { now, subject: "an as-of date", formats: dateOptionFormatsOr("latest") }));
|
|
19
20
|
if (date > now.toISOString().slice(0, 10)) throw new Error("A Treasury curve cannot use a future date.");
|
|
20
21
|
return date;
|
|
21
22
|
}
|
|
@@ -35,9 +35,11 @@ import { forwardCurve, type CurveBasis } from "./forward";
|
|
|
35
35
|
import { loadYieldCurveLookbacks, yieldCurveDate } from "./history";
|
|
36
36
|
import { curveAsOf, isYieldObservationDate, type YieldPoint, yieldCurveErrors } from "./treasury-data";
|
|
37
37
|
import { loadWorldRows, type WorldRow } from "./world";
|
|
38
|
+
import { SwapsTab } from "./swaps";
|
|
39
|
+
import { swapCurveCache } from "./client";
|
|
38
40
|
|
|
39
|
-
type GcTab = "curve" | "world";
|
|
40
|
-
const TABS = [{ label: "Curve", value: "curve" }, { label: "World", value: "world" }];
|
|
41
|
+
type GcTab = "curve" | "world" | "swaps";
|
|
42
|
+
const TABS = [{ label: "Curve", value: "curve" }, { label: "World", value: "world" }, { label: "Swaps", value: "swaps" }];
|
|
41
43
|
const EMPTY_POINTS: YieldPoint[] = [];
|
|
42
44
|
/** Axis word for the loaded curve's basis. */
|
|
43
45
|
const BASIS_LABEL: Record<CurveBasis, string> = {
|
|
@@ -129,13 +131,15 @@ export function YieldCurvePane({ focused, width, height }: PaneProps) {
|
|
|
129
131
|
return (
|
|
130
132
|
<Box flexDirection="column" width={width} height={height}>
|
|
131
133
|
{strip}
|
|
132
|
-
{(["curve", "world"] as const).map((id) => mounted.has(id) ? (
|
|
134
|
+
{(["curve", "world", "swaps"] as const).map((id) => mounted.has(id) ? (
|
|
133
135
|
<Box key={id} visible={tab === id} flexDirection="column" width={width} height={bodyHeight} flexGrow={1} flexBasis={0}
|
|
134
136
|
overflow="hidden">
|
|
135
137
|
<PaneFooterScope active={tab === id}>
|
|
136
138
|
{id === "curve"
|
|
137
139
|
? <CurveTab curve={curve} onCurveChange={setCurve} focused={focused && tab === "curve"} width={width} height={bodyHeight} />
|
|
138
|
-
:
|
|
140
|
+
: id === "world"
|
|
141
|
+
? <WorldTab onOpen={openCurve} focused={focused && tab === "world"} width={width} height={bodyHeight} />
|
|
142
|
+
: <SwapsTab focused={focused && tab === "swaps"} width={width} height={bodyHeight} />}
|
|
139
143
|
</PaneFooterScope>
|
|
140
144
|
</Box>
|
|
141
145
|
) : null)}
|
|
@@ -461,6 +465,8 @@ function WorldTab({ onOpen, focused, width, height }: {
|
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
export const yieldCurveModule: PluginModule = {
|
|
468
|
+
setup(ctx) { swapCurveCache.attach(ctx.persistence); },
|
|
469
|
+
dispose() { swapCurveCache.reset(); },
|
|
464
470
|
series: [...TREASURY_SERIES, ...GOVERNMENT_BOND_SERIES],
|
|
465
471
|
panes: [{
|
|
466
472
|
id: "yield-curve",
|
|
@@ -475,9 +481,9 @@ export const yieldCurveModule: PluginModule = {
|
|
|
475
481
|
id: "yield-curve-pane",
|
|
476
482
|
paneId: "yield-curve",
|
|
477
483
|
label: "Yield Curve",
|
|
478
|
-
description: "Government bond curves
|
|
484
|
+
description: "Government bond curves, a world grid, and USD SOFR swap rates, swap spreads and tenor history.",
|
|
479
485
|
keywords: ["yield", "curve", "treasury", "bonds", "rates", "gc", "interest", "tips", "breakeven", "bund", "gilt", "jgb",
|
|
480
|
-
"sovereign", "world", "forward"],
|
|
486
|
+
"sovereign", "world", "forward", "swaps", "sofr", "ois", "swap spread"],
|
|
481
487
|
shortcut: { prefix: "GC", argPlaceholder: "[curve] [date]", argKind: "text", argOptional: true },
|
|
482
488
|
headless: yieldCurveHeadless,
|
|
483
489
|
createInstance: (_context, options) => {
|