gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import type { Quote } from "../../../types/financials";
|
|
2
2
|
import type { HeadlessBundleSection, HeadlessPaneDefinition, HeadlessPaneFreshness, HeadlessPaneLoadArgs, HeadlessPaneRow } from "../../../types/plugin";
|
|
3
3
|
import {
|
|
4
|
-
expirationOptionSeconds,
|
|
4
|
+
expirationOptionSeconds, expiredExpiryText, findListedExpiry, isLiveOptionExpiry, OPTION_EXPIRATION_FORMAT, OPTION_EXPIRATION_PLACEHOLDER,
|
|
5
|
+
readOptionExpiration, unlistedExpiryText,
|
|
5
6
|
} from "../../../utils/option-expiry";
|
|
6
7
|
import { DATE_OPTION_EXAMPLES } from "../../../utils/calendar-date";
|
|
7
|
-
import { skewHeader } from "../iv-history/format";
|
|
8
|
+
import { IMPLIED_VOL_WORDS, skewHeader } from "../iv-history/format";
|
|
8
9
|
import { formatStrikeLabel } from "../options/table";
|
|
9
10
|
import { createSurfaceDependencies, loadVolatilitySurface } from "./client";
|
|
10
11
|
import { buildSurfaceGrid, type SurfaceGridOptions, type SurfaceSettings, type SurfaceSnapshot } from "./model";
|
|
11
|
-
import { formatCaptureTime, loadDatedSurface, storedSurfaceDate, type DatedSurfaceSnapshot } from "./stored";
|
|
12
|
+
import { atCapturePrecision, formatCaptureTime, loadDatedSurface, storedSurfaceDate, type DatedSurfaceSnapshot } from "./stored";
|
|
13
|
+
import { listingFateEmpty, loadListingFate } from "../../../tickers/listing-fate";
|
|
12
14
|
import {
|
|
13
15
|
expiryFeedFields, expiryLabel, formatIv, formatPrice, formatVolPoints, HIDDEN_SLOPE_TEXT, HIDDEN_YIELD_TEXT, selectSurfaceExpiry, surfaceForwardRow, surfaceSkewRow,
|
|
14
|
-
surfaceSmileRows, surfaceTermRows, TERM_SLOPE_MIN_DAYS, type SurfaceForwardRow, type SurfaceSkewRow,
|
|
16
|
+
surfaceSmileRows, surfaceSpotBasisLabel, surfaceTermRows, TERM_SLOPE_MIN_DAYS, type SurfaceForwardRow, type SurfaceSkewRow,
|
|
15
17
|
} from "./tables";
|
|
16
18
|
|
|
17
19
|
type SurfaceAxis = NonNullable<SurfaceGridOptions["axis"]>;
|
|
@@ -26,8 +28,8 @@ export function surfaceCoordinateLabel(axis: SurfaceAxis, coordinate: number, in
|
|
|
26
28
|
|
|
27
29
|
/** The Skew view's sign conventions and units, one line each. */
|
|
28
30
|
const SKEW_NOTES = [
|
|
29
|
-
"RR is 25D call IV minus 25D put IV, BF the average 25D wing IV minus
|
|
30
|
-
`Slope is the
|
|
31
|
+
"RR is 25D call IV minus 25D put IV, BF the average 25D wing IV minus the IV at the forward, 90/110 the IV at 90% of the forward minus the IV at 110%; all in vol points.",
|
|
32
|
+
`Slope is the change per year in the IV at the forward to the next listed expiry, in vol points; left out under ${TERM_SLOPE_MIN_DAYS} days to expiry, where it annualises a few hours of noise.`,
|
|
31
33
|
];
|
|
32
34
|
|
|
33
35
|
/**
|
|
@@ -132,6 +134,7 @@ function forwardsSection(snapshot: SurfaceSnapshot): HeadlessBundleSection {
|
|
|
132
134
|
export const volSurfaceHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
133
135
|
shape: "bundle", argument: { kind: "ticker", description: "Underlying ticker" },
|
|
134
136
|
usListingsOnly: "Options data",
|
|
137
|
+
discovery: { suggestFor: IMPLIED_VOL_WORDS },
|
|
135
138
|
describe: (args) => `OVDV ${args.symbols[0] ?? ""}`,
|
|
136
139
|
options: [
|
|
137
140
|
{ key: "tab", type: "enum", values: SURFACE_TABS.map((value) => ({ value })),
|
|
@@ -154,6 +157,7 @@ export const volSurfaceHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
154
157
|
const date = typeof args.options.date === "string" && args.options.date ? storedSurfaceDate(args.options.date) : null;
|
|
155
158
|
let snapshot: DatedSurfaceSnapshot;
|
|
156
159
|
let quote: Quote | null = null;
|
|
160
|
+
let instrument: { symbol: string; exchange?: string } = { symbol };
|
|
157
161
|
if (date) {
|
|
158
162
|
// A stored close needs no current price: it carries the spot it was fitted at.
|
|
159
163
|
snapshot = await loadDatedSurface(symbol, date, { signal: ctx.signal, api: ctx.apiClient });
|
|
@@ -162,21 +166,43 @@ export const volSurfaceHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
162
166
|
snapshot = { ...snapshot, failures: [...snapshot.failures, { expiration: requested, message: unlistedExpiryText(requested, snapshot.catalogue) }] };
|
|
163
167
|
}
|
|
164
168
|
} else {
|
|
165
|
-
const
|
|
166
|
-
|
|
169
|
+
const resolved = await ctx.resolveInstrument?.(symbol) ?? { symbol };
|
|
170
|
+
instrument = resolved;
|
|
171
|
+
quote = await ctx.marketData.getQuote(symbol, resolved.exchange);
|
|
167
172
|
if (!(quote.price > 0) || !Number.isFinite(quote.price) || quote.stale) {
|
|
168
|
-
|
|
173
|
+
// A listing that stopped trading has no current price: what became of it is why (TWTR).
|
|
174
|
+
const fate = await loadListingFate(resolved, ctx.marketData, { quote });
|
|
175
|
+
return { sections: [], complete: false, unavailableSymbols: [symbol],
|
|
176
|
+
...listingFateEmpty(fate, ["A current underlying price is required"]) };
|
|
169
177
|
}
|
|
170
|
-
|
|
178
|
+
// At a stored close's precision, so the live report and a --date one export the same digits. A chain
|
|
179
|
+
// from a closed session is priced at that session's close, as OMON prices it.
|
|
180
|
+
snapshot = atCapturePrecision(await loadVolatilitySurface({ instrument, spot: quote.price, spotAsOf: quote.lastUpdated, quote,
|
|
171
181
|
settings: { ivSource: args.options.ivSource as SurfaceSettings["ivSource"], priceSide: args.options.priceSide as SurfaceSettings["priceSide"] },
|
|
172
182
|
limit: Number(args.options.limit), signal: ctx.signal,
|
|
173
183
|
requiredExpiries: requested == null ? [] : [requested],
|
|
174
|
-
}, createSurfaceDependencies(ctx.marketData, ctx.apiClient));
|
|
184
|
+
}, createSurfaceDependencies(ctx.marketData, ctx.apiClient)));
|
|
185
|
+
// An expired --expiration names the flag that asks for the nearest live one.
|
|
186
|
+
const now = Date.now();
|
|
187
|
+
if (requested != null && !isLiveOptionExpiry(requested, now, instrument.exchange)) {
|
|
188
|
+
const message = expiredExpiryText(requested, snapshot.catalogue, now, { exchange: instrument.exchange, flag: "expiration" });
|
|
189
|
+
snapshot = { ...snapshot, failures: snapshot.failures.map((failure) => failure.expiration === requested ? { ...failure, message } : failure) };
|
|
190
|
+
}
|
|
175
191
|
}
|
|
192
|
+
const available = snapshot.expiries.some((expiry) => expiry.fit);
|
|
193
|
+
// An expiry that failed as the whole surface did (no connection) is not listed again under its own date.
|
|
194
|
+
const surfaceWide = new Set(snapshot.failures.filter((failure) => failure.expiration == null).map((failure) => failure.message));
|
|
195
|
+
const loadErrors = snapshot.failures.filter((failure) => failure.expiration == null || !surfaceWide.has(failure.message))
|
|
196
|
+
.map((failure) => failure.expiration == null ? failure.message : `${expiryLabel(failure.expiration)}: ${failure.message}`);
|
|
197
|
+
// A symbol with no option chain at all says what became of it when something did (FB is a fund now,
|
|
198
|
+
// Meta trades as META) in place of the chain's own error; a chain without clean quotes is the symbol's own.
|
|
199
|
+
const fate = !snapshot.stored && !available && snapshot.catalogue.length === 0
|
|
200
|
+
? listingFateEmpty(await loadListingFate(instrument, ctx.marketData, { quote }), loadErrors) : null;
|
|
201
|
+
// The spot a chain from a closed session was priced at, and its session.
|
|
202
|
+
const spotBasis = available ? surfaceSpotBasisLabel(snapshot) : null;
|
|
176
203
|
const stored = snapshot.stored ?? null;
|
|
177
204
|
const axis = args.options.axis as SurfaceAxis;
|
|
178
205
|
const tab = (SURFACE_TABS as readonly string[]).includes(String(args.options.tab)) ? args.options.tab as SurfaceTab : "surface";
|
|
179
|
-
const available = snapshot.expiries.some((expiry) => expiry.fit);
|
|
180
206
|
const expiryWarnings = snapshot.expiries.flatMap((expiry) => expiry.warnings.map((warning) =>
|
|
181
207
|
({ expiry: expiryLabel(expiry.expiration), warning })));
|
|
182
208
|
const perExpiry = new Set(expiryWarnings.map((row) => row.warning));
|
|
@@ -197,9 +223,11 @@ export const volSurfaceHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
197
223
|
],
|
|
198
224
|
complete: available && snapshot.failures.length === 0 && snapshot.expiries.every((expiry) => expiry.state === "ready"),
|
|
199
225
|
unavailableSymbols: available ? [] : [symbol],
|
|
200
|
-
errors: [...
|
|
201
|
-
|
|
202
|
-
...(stored || tab === "skew" ? { notes: [
|
|
226
|
+
errors: [...fate?.errors ?? loadErrors, ...smile?.errors ?? []],
|
|
227
|
+
...(fate?.empty ? { empty: fate.empty } : {}),
|
|
228
|
+
...(stored || spotBasis || tab === "skew" ? { notes: [
|
|
229
|
+
...stored ? storedNotes(snapshot, args.options) : spotBasis ? [`Spot ${formatPrice(snapshot.spot)}, ${spotBasis}.`] : [],
|
|
230
|
+
...tab === "skew" ? SKEW_NOTES : []] } : {}),
|
|
203
231
|
// A stored close is dated by its session, whichever view prints it.
|
|
204
232
|
...(stored ? { freshness: { status: "not-a-feed" as const, basis: "stored close capture", asOf: stored.sessionDate } }
|
|
205
233
|
: smile?.freshness ? { freshness: smile.freshness } : {}),
|
|
@@ -99,10 +99,23 @@ export interface SurfaceFailure {
|
|
|
99
99
|
reasonCode?: string;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* What a surface's spot is (`optionModelSpot`): the official close of the
|
|
104
|
+
* session the chain was quoted in (`close`, that session's New York date),
|
|
105
|
+
* or the latest price (`last`, with the extended session it printed in).
|
|
106
|
+
*/
|
|
107
|
+
interface SurfaceSpotBasis {
|
|
108
|
+
basis: "close" | "last";
|
|
109
|
+
session: "pre-market" | "after hours" | "overnight" | null;
|
|
110
|
+
sessionDate: string | null;
|
|
111
|
+
}
|
|
112
|
+
|
|
102
113
|
export interface SurfaceSnapshot {
|
|
103
114
|
symbol: string;
|
|
104
115
|
spot: number;
|
|
105
116
|
spotAsOf?: string | number | null;
|
|
117
|
+
/** Absent when the caller gave a bare spot, as a stored close does. */
|
|
118
|
+
spotBasis?: SurfaceSpotBasis | null;
|
|
106
119
|
phase: "loading" | "partial" | "ready" | "error";
|
|
107
120
|
settings: SurfaceSettings;
|
|
108
121
|
catalogue: number[];
|
|
@@ -401,11 +414,16 @@ export function buildSurfaceExpiry(input: BuildSurfaceExpiryInput): SurfaceExpir
|
|
|
401
414
|
}
|
|
402
415
|
|
|
403
416
|
/**
|
|
404
|
-
* A fitted expiry's skew in decimal IV
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
417
|
+
* A fitted expiry's skew in decimal IV, measured from its forward: `atm` is
|
|
418
|
+
* the IV at the forward (ATMF), RR the 25-delta call minus put, BF their
|
|
419
|
+
* average minus ATMF, 90/110 the IV at 90% of the forward minus 110%. The
|
|
420
|
+
* spot only enters through the 25-delta strikes' spot delta, whose carry is
|
|
421
|
+
* the parity forward's, so a pre-market print against the close's chain does
|
|
422
|
+
* not move a fly, and a long-dated fly is not dragged below zero by the skew
|
|
423
|
+
* between spot and a forward several percent above it. The 25-delta strikes
|
|
424
|
+
* are found on the fit inside the quoted strikes, as the Table's delta
|
|
425
|
+
* columns find them, so a fit that cannot price a far wing it was never
|
|
426
|
+
* quoted at does not blank a quoted expiry's skew.
|
|
409
427
|
*/
|
|
410
428
|
export function surfaceExpirySkew(expiry: SurfaceExpiry, spot: number): SkewMetrics {
|
|
411
429
|
const smile = (strike: number) => evaluateSurfaceSmile(expiry, strike);
|
|
@@ -413,8 +431,9 @@ export function surfaceExpirySkew(expiry: SurfaceExpiry, spot: number): SkewMetr
|
|
|
413
431
|
const strike = deltaStrike(expiry, spot, delta);
|
|
414
432
|
return strike == null ? null : smile(strike);
|
|
415
433
|
};
|
|
416
|
-
const
|
|
417
|
-
const
|
|
434
|
+
const forward = expiry.forward;
|
|
435
|
+
const put25 = at(-0.25), call25 = at(0.25), atm = positive(forward) ? smile(forward) : null;
|
|
436
|
+
const low = positive(forward) ? smile(forward * 0.9) : null, high = positive(forward) ? smile(forward * 1.1) : null;
|
|
418
437
|
const both = put25 != null && call25 != null;
|
|
419
438
|
return { atm, put25, call25, putCallSkew: both ? put25 - call25 : null, riskReversal: both ? call25 - put25 : null,
|
|
420
439
|
butterfly: both && atm != null ? (put25 + call25) / 2 - atm : null,
|
|
@@ -433,12 +452,13 @@ export function surfaceCalendarWarnings(expiries: readonly SurfaceExpiry[]): str
|
|
|
433
452
|
return count > 0 ? [`${count} calendar arbitrage ${count === 1 ? "warning" : "warnings"}`] : [];
|
|
434
453
|
}
|
|
435
454
|
|
|
455
|
+
/** The ATM-forward IV change per year to the next expiry that has one: spot plays no part in it. */
|
|
436
456
|
export function withSurfaceTermSlopes(expiries: readonly SurfaceExpiry[]): SurfaceExpiry[] {
|
|
437
457
|
const sorted = [...expiries].sort((a, b) => a.years - b.years);
|
|
438
458
|
return sorted.map((expiry, index) => {
|
|
439
|
-
const next = sorted.slice(index + 1).find((item) => item.
|
|
440
|
-
return { ...expiry, termSlope: expiry.
|
|
441
|
-
? volatilityTermSlope({ years: expiry.years, volatility: expiry.
|
|
459
|
+
const next = sorted.slice(index + 1).find((item) => item.skew.atm != null);
|
|
460
|
+
return { ...expiry, termSlope: expiry.skew.atm != null && next?.skew.atm != null
|
|
461
|
+
? volatilityTermSlope({ years: expiry.years, volatility: expiry.skew.atm }, { years: next.years, volatility: next.skew.atm }) : null };
|
|
442
462
|
});
|
|
443
463
|
}
|
|
444
464
|
|
|
@@ -593,8 +613,10 @@ export function buildSurfaceGrid(snapshot: SurfaceSnapshot, options: SurfaceGrid
|
|
|
593
613
|
: axis === "strike" ? coordinate : deltaNeutralStrike(targetForward, tenor.years, (k) => at(k)?.volatility ?? null);
|
|
594
614
|
if (strike === null) return unavailable();
|
|
595
615
|
if (axis === "delta" && coordinate !== 0) {
|
|
596
|
-
|
|
597
|
-
|
|
616
|
+
// The quoted strikes against each expiry's forward as it is now, the one its smile is read on: a report's
|
|
617
|
+
// forward is rounded after the points were placed, and the stored log-moneyness would land past the quotes.
|
|
618
|
+
let low = Math.min(...available.map((expiry) => logForwardMoneyness(expiry.points[0]!.strike, expiry.forward!)!));
|
|
619
|
+
let high = Math.max(...available.map((expiry) => logForwardMoneyness(expiry.points.at(-1)!.strike, expiry.forward!)!));
|
|
598
620
|
const delta = (k: number) => {
|
|
599
621
|
const value = at(k);
|
|
600
622
|
return value == null ? null : optionDelta({ spot: snapshot.spot, years: tenor.years,
|
|
@@ -39,7 +39,7 @@ import { VolatilitySurface } from "./surface";
|
|
|
39
39
|
import { SmileChart, TermChart } from "./charts";
|
|
40
40
|
import { surfaceCoordinateLabel } from "./headless";
|
|
41
41
|
import { expiryLabel, formatIv, formatPrice, formatVolPoints, HIDDEN_SLOPE_TEXT, HIDDEN_YIELD_TEXT, selectSurfaceExpiry, surfaceForwardRow,
|
|
42
|
-
surfaceSkewRow } from "./tables";
|
|
42
|
+
surfaceSkewRow, surfaceSpotBasisLabel } from "./tables";
|
|
43
43
|
import { findListedExpiry, unlistedExpiryText } from "../../../utils/option-expiry";
|
|
44
44
|
|
|
45
45
|
const TABS = [
|
|
@@ -95,17 +95,19 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
95
95
|
const spotAvailable = !!quote && quote.price > 0 && Number.isFinite(quote.price) && !quote.stale;
|
|
96
96
|
const spotAsOfRef = useRef(quote?.lastUpdated ?? null);
|
|
97
97
|
spotAsOfRef.current = quote?.lastUpdated ?? null;
|
|
98
|
-
const
|
|
99
|
-
|
|
98
|
+
const quoteRef = useRef(quote ?? null);
|
|
99
|
+
quoteRef.current = quote ?? null;
|
|
100
100
|
const requestKey = JSON.stringify([target?.cacheKey, symbol, axis, tenors, ivSource, priceSide, spread, age, limit, spotAvailable, requestedExpiration]);
|
|
101
101
|
// Every load reads the spot at the moment it starts; a reload in session
|
|
102
102
|
// therefore uses the current stream price, not the one from the first load.
|
|
103
|
+
// A chain from a closed session is priced at that session's close, which
|
|
104
|
+
// the quote carries, so a pre-market print does not move it.
|
|
103
105
|
const surfaceRequest = useCallback((force: boolean, signal: AbortSignal): SurfaceLoadRequest => {
|
|
104
106
|
const instrument = target?.instrument;
|
|
105
107
|
return {
|
|
106
108
|
instrument: { symbol: target?.effectiveTicker ?? symbol!, exchange: target?.effectiveExchange ?? "",
|
|
107
109
|
brokerId: instrument?.brokerId, brokerInstanceId: instrument?.brokerInstanceId, instrument },
|
|
108
|
-
spot:
|
|
110
|
+
spot: quoteRef.current?.price ?? 0, spotAsOf: spotAsOfRef.current, quote: quoteRef.current, limit, forceRefresh: force, signal,
|
|
109
111
|
requiredExpiries: expirationRef.current == null ? [] : [expirationRef.current],
|
|
110
112
|
settings: { ...DEFAULT_SURFACE_SETTINGS, ivSource, priceSide, maxRelativeSpread: Number(spread), maxStaleSessions: Number(age) },
|
|
111
113
|
};
|
|
@@ -153,6 +155,14 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
153
155
|
const underlying = (target?.effectiveTicker ?? symbol ?? "").toUpperCase();
|
|
154
156
|
const datesLoader = useCallback(async () => (await loadSurfaceDates(underlying)).dates, [underlying]);
|
|
155
157
|
const dates = useAsyncResource(underlying ? datesLoader : null);
|
|
158
|
+
// A symbol with no current price, or no option chain at all, says what became of it when something
|
|
159
|
+
// did, as `quote` says it: TWTR stopped trading, FB is a fund now and Meta trades as META.
|
|
160
|
+
const noChain = !historyDate && !!quote && (!spotAvailable
|
|
161
|
+
|| (!!resource.data && !resource.loading && resource.data.catalogue.length === 0));
|
|
162
|
+
const fateExchange = target?.effectiveExchange ?? "";
|
|
163
|
+
const fateLoader = useCallback(async () => (await getSharedMarketDataCoordinator()
|
|
164
|
+
?.loadListingFate({ symbol: underlying, exchange: fateExchange }))?.note ?? null, [underlying, fateExchange]);
|
|
165
|
+
const fateNote = useAsyncResource(underlying && noChain ? fateLoader : null).data ?? null;
|
|
156
166
|
const ivRank = useIvRank(underlying || null);
|
|
157
167
|
useEffect(() => () => controller.current?.abort(), [request]);
|
|
158
168
|
const incremental = partial?.key === requestKey ? partial.snapshot : null;
|
|
@@ -229,6 +239,11 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
229
239
|
const nearestRow = (years: number | undefined) => years == null || !denseGrid?.tenors.length ? -1
|
|
230
240
|
: denseGrid.tenors.reduce((best, value, index) => Math.abs(value - years) < Math.abs(denseGrid.tenors[best]! - years) ? index : best, 0);
|
|
231
241
|
const selectedExpiry = snapshot ? selectSurfaceExpiry(snapshot, expiration) : null;
|
|
242
|
+
// Another date loads under the query bar, which keeps the last surface's expiries until it answers.
|
|
243
|
+
const lastShown = useRef<{ underlying: string; snapshot: DatedSurfaceSnapshot } | null>(null);
|
|
244
|
+
if (snapshot) lastShown.current = { underlying, snapshot };
|
|
245
|
+
const barSnapshot = snapshot ?? (lastShown.current?.underlying === underlying ? lastShown.current.snapshot : null);
|
|
246
|
+
const barExpiry = barSnapshot ? selectSurfaceExpiry(barSnapshot, expiration) : null;
|
|
232
247
|
const openChain = useCallback(() => {
|
|
233
248
|
if (!snapshot) return;
|
|
234
249
|
const selected = pinned ?? selectedExpiry?.expiration;
|
|
@@ -334,7 +349,7 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
334
349
|
for (const entry of snapshot?.expiries ?? []) {
|
|
335
350
|
for (const warning of entry.warnings) expiryWarnings.set(warning, [...expiryWarnings.get(warning) ?? [], entry.expiration]);
|
|
336
351
|
}
|
|
337
|
-
const notices = [...(snapshot?.warnings ?? []).filter((warning) => !expiryWarnings.has(warning)), ...failures,
|
|
352
|
+
const notices = fateNote ? [] : [...(snapshot?.warnings ?? []).filter((warning) => !expiryWarnings.has(warning)), ...failures,
|
|
338
353
|
...(activeTab === "surface" && sheet?.omitted.length ? [`3D sheet omits ${sheet.omitted.map((entry) => expiryLabel(entry.expiration)).join(", ")}: smile fit fell back to interpolation (shown in Table)`] : []),
|
|
339
354
|
...[...expiryWarnings].map(([warning, expirations]) => `${expirations.length > 1 && expirations.length === snapshot?.expiries.length
|
|
340
355
|
? "All expiries" : expirations.map(expiryLabel).join(", ")}: ${warning}`),
|
|
@@ -345,6 +360,7 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
345
360
|
&& !snapshot.failures.some((failure) => failure.expiration === pinned)
|
|
346
361
|
? [`${expiryLabel(pinned)}: ${unlistedExpiryText(pinned, snapshot.catalogue)}`] : []),
|
|
347
362
|
...(active.error ? [active.error] : [])];
|
|
363
|
+
const spotBasis = snapshot && !snapshot.stored ? surfaceSpotBasisLabel(snapshot) : null;
|
|
348
364
|
// What the quotes are and when they were observed; a reload moves the time.
|
|
349
365
|
const freshness = !snapshot ? null : snapshot.stored ? `stored close ${snapshot.stored.sessionDate}`
|
|
350
366
|
: surfaceFreshnessLabel(snapshot, CLOUD_QUOTE_DELAY_MINUTES);
|
|
@@ -447,24 +463,28 @@ export function VolSurfacePane({ focused, width, height }: PaneProps) {
|
|
|
447
463
|
useEffect(() => setTableOnScreen(tableShown), [tableShown]);
|
|
448
464
|
return <Box flexDirection="column" width={width} overflow="hidden" {...(nativePaneChrome ? FILL_REST : { height })}>
|
|
449
465
|
{tabStrip}
|
|
450
|
-
{!symbol ? <EmptyState title="Choose an underlying ticker." /> :
|
|
451
|
-
|
|
452
|
-
<QueryBar width={width}
|
|
466
|
+
{!symbol ? <EmptyState title="Choose an underlying ticker." /> : <>
|
|
467
|
+
{barSnapshot ? <QueryBar width={width}
|
|
453
468
|
filters={[
|
|
454
|
-
{ id: "expiry", label: "Expiry", value: String(pinned ??
|
|
455
|
-
options:
|
|
469
|
+
{ id: "expiry", label: "Expiry", value: String(pinned ?? barExpiry?.expiration ?? ""),
|
|
470
|
+
options: barSnapshot.catalogue.map((value) => ({ value: String(value), label: expiryLabel(value) })),
|
|
456
471
|
onChange: (value: string) => setExpiration(Number(value)) },
|
|
457
472
|
...(storedDates.length ? [{ id: "date", label: "Date", value: shownDate ?? "", defaultValue: "",
|
|
458
473
|
options: [{ value: "", label: "Live" }, ...storedDates.map((date) => ({ value: date, label: date }))],
|
|
459
474
|
onChange: (value: string) => setHistoryDate(value || null) }] : []),
|
|
460
475
|
]}
|
|
461
|
-
meta={snapshot
|
|
476
|
+
meta={!snapshot ? undefined : snapshot.stored
|
|
462
477
|
? `Stored close · spot ${formatPrice(snapshot.spot)} · captured ${formatCaptureTime(snapshot.stored.capturedAt)} New York`
|
|
463
|
-
: [`Spot ${formatPrice(snapshot
|
|
478
|
+
: [`Spot ${formatPrice(snapshot.spot)}${quote?.currency ? ` ${quote.currency}` : ""}`,
|
|
479
|
+
// The close a closed session's chain is priced at dates the chain too.
|
|
480
|
+
spotBasis, snapshot.spotBasis?.basis === "close" ? null : selectedExpiry?.asOf?.slice(0, 10)].filter(Boolean).join(" · ")} /> : null}
|
|
481
|
+
<PaneStatusBody loading={active.loading && !snapshot && !fateNote}
|
|
482
|
+
error={!snapshot && !fateNote ? active.error : null} empty={!!fateNote || !snapshot && !active.loading}
|
|
483
|
+
emptyTitle={fateNote ?? undefined} subject="volatility surface">
|
|
464
484
|
<StatGrid items={ivStats} width={width} />
|
|
465
485
|
{/* The terminal sizes the view in the rows under the bar and figures; the desktop fills what is left. */}
|
|
466
486
|
{nativePaneChrome ? <Box flexDirection="column" overflow="hidden" {...FILL_REST}>{content}</Box> : content}
|
|
467
|
-
</PaneStatusBody
|
|
487
|
+
</PaneStatusBody></>}
|
|
468
488
|
</Box>;
|
|
469
489
|
}
|
|
470
490
|
|
|
@@ -3,7 +3,10 @@ import { logForwardMoneyness, type ExpectedMove, type SkewMetrics, type SmileFit
|
|
|
3
3
|
import { ivSymbol, loadStoredSurface, loadSurfaceDates, type ImpliedVolatilityApi, type StoredSurfacePayload } from "../iv-history/client";
|
|
4
4
|
import { ApiRequestError } from "../../../api-client/errors";
|
|
5
5
|
import { CLOUD_QUOTE_DELAY_MINUTES } from "../../../api-client/plan-rules";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
evaluateSurfaceSmile, normalizeSurfaceSettings, surfaceExpirySkew, withSurfaceTermSlopes,
|
|
8
|
+
type SurfaceExpiry, type SurfaceFilterCounts, type SurfaceSnapshot,
|
|
9
|
+
} from "./model";
|
|
7
10
|
import { isFiniteNumber } from "../../../utils/guards";
|
|
8
11
|
import { dateOptionError, readCalendarDate } from "../../../utils/calendar-date";
|
|
9
12
|
|
|
@@ -63,6 +66,10 @@ function storedExpiry(entry: StoredExpiry, spot: number, capturedAt: number, sou
|
|
|
63
66
|
}
|
|
64
67
|
expiry.points.sort((a, b) => a.strike - b.strike);
|
|
65
68
|
for (const point of expiry.points) point.fitResidual = point.volatility - (evaluateSurfaceSmile(expiry, point.strike) ?? point.volatility);
|
|
69
|
+
// The skew is read off the stored fit as the live surface reads it, not taken as stored: a capture
|
|
70
|
+
// that searched the far wings for its 25-delta strikes left a quoted monthly blank, and an older one
|
|
71
|
+
// measured its fly from the spot.
|
|
72
|
+
if (expiry.fit) expiry.skew = surfaceExpirySkew(expiry, spot);
|
|
66
73
|
return expiry;
|
|
67
74
|
}
|
|
68
75
|
|
|
@@ -120,13 +127,37 @@ export async function loadDatedSurface(symbol: string, date: string, options: {
|
|
|
120
127
|
throw new Error(storedSurfaceMiss(bare, date, dates.value.dates));
|
|
121
128
|
}
|
|
122
129
|
|
|
130
|
+
/** A figure to the decimals a stored close keeps it at. */
|
|
131
|
+
const toDecimals = (value: number | null, digits: number) => value == null || !Number.isFinite(value) ? null : Number(value.toFixed(digits));
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* A live surface at the precision a stored close keeps its figures (the
|
|
135
|
+
* platform's compact capture: years to 8 decimals, forwards and mids to 4,
|
|
136
|
+
* rates, yields, IVs and the term slope to 6), so a report of the live chain
|
|
137
|
+
* and one of a stored close (`--date`) export the same digits. The fit and
|
|
138
|
+
* the skew are kept whole, as a capture keeps them; residuals are measured
|
|
139
|
+
* again from the rounded IVs, as a stored close measures them.
|
|
140
|
+
*/
|
|
141
|
+
export function atCapturePrecision(snapshot: SurfaceSnapshot): SurfaceSnapshot {
|
|
142
|
+
return { ...snapshot, expiries: snapshot.expiries.map((expiry) => {
|
|
143
|
+
const rounded: SurfaceExpiry = { ...expiry, years: toDecimals(expiry.years, 8) ?? expiry.years, rate: toDecimals(expiry.rate, 6),
|
|
144
|
+
forward: toDecimals(expiry.forward, 4), dividendYield: toDecimals(expiry.dividendYield, 6), atmIV: toDecimals(expiry.atmIV, 6),
|
|
145
|
+
termSlope: toDecimals(expiry.termSlope, 6),
|
|
146
|
+
points: expiry.points.map((point) => ({ ...point, volatility: toDecimals(point.volatility, 6) ?? point.volatility, mid: toDecimals(point.mid, 4) ?? point.mid })) };
|
|
147
|
+
for (const point of rounded.points) {
|
|
148
|
+
if (point.fitResidual != null) point.fitResidual = point.volatility - (evaluateSurfaceSmile(rounded, point.strike) ?? point.volatility);
|
|
149
|
+
}
|
|
150
|
+
return rounded;
|
|
151
|
+
}) };
|
|
152
|
+
}
|
|
153
|
+
|
|
123
154
|
/** A stored close surface in the shape the live OVDV views render: mid quotes, recomputed IV. */
|
|
124
155
|
export function storedSurfaceSnapshot(payload: StoredSurfacePayload): DatedSurfaceSnapshot {
|
|
125
156
|
const surface = payload.surface as unknown as StoredSurface;
|
|
126
157
|
if (!surface || surface.version !== 1 || !Array.isArray(surface.expiries)) throw new Error("Unsupported stored surface format");
|
|
127
158
|
const capturedAt = Date.parse(payload.capturedAt);
|
|
128
|
-
const expiries = surface.expiries.map((entry) => storedExpiry(entry, payload.spot, capturedAt, surface.source))
|
|
129
|
-
.filter((entry) => entry.points.length > 0)
|
|
159
|
+
const expiries = withSurfaceTermSlopes(surface.expiries.map((entry) => storedExpiry(entry, payload.spot, capturedAt, surface.source))
|
|
160
|
+
.filter((entry) => entry.points.length > 0));
|
|
130
161
|
const rateDates = expiries.flatMap((entry) => entry.rateAsOf).sort();
|
|
131
162
|
return {
|
|
132
163
|
symbol: payload.symbol, spot: payload.spot, spotAsOf: surface.spotAsOf ?? payload.capturedAt, phase: "ready",
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { findListedExpiry } from "../../../utils/option-expiry";
|
|
2
2
|
import { evaluateSurfaceSmile, type SurfaceExpiry, type SurfaceSnapshot } from "./model";
|
|
3
|
+
import { modelSpotStamp } from "../options/model-spot";
|
|
3
4
|
|
|
4
5
|
export const formatIv = (value: number | null | undefined) => value == null || !Number.isFinite(value) ? "--" : `${(value * 100).toFixed(2)}%`;
|
|
5
6
|
export const formatPrice = (value: number | null | undefined) => value == null || !Number.isFinite(value) ? "--" : value.toFixed(2);
|
|
6
7
|
export const expiryLabel = (expiration: number) => new Date(expiration * 1000).toISOString().slice(0, 10);
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* The shared stamp for the spot a surface was fitted at (`modelSpotStamp`):
|
|
11
|
+
* `close Mon 19 Oct` for the official close of the session a closed chain was
|
|
12
|
+
* quoted in, `pre-market Tue 20 Oct 12:21 UTC` for an extended-session print.
|
|
13
|
+
* Null for the regular session's price or a bare spot.
|
|
14
|
+
*/
|
|
15
|
+
export function surfaceSpotBasisLabel(snapshot: Pick<SurfaceSnapshot, "spotBasis" | "spotAsOf">): string | null {
|
|
16
|
+
const basis = snapshot.spotBasis;
|
|
17
|
+
if (!basis) return null;
|
|
18
|
+
const observedAt = typeof snapshot.spotAsOf === "number" ? snapshot.spotAsOf : Date.parse(String(snapshot.spotAsOf));
|
|
19
|
+
return modelSpotStamp({ basis: basis.basis, session: basis.session, observedAt });
|
|
20
|
+
}
|
|
21
|
+
|
|
8
22
|
/** A one-day front expiry is the noisiest smile on the board; the default selection is the first at least four weeks out. */
|
|
9
23
|
const DEFAULT_EXPIRY_MIN_DAYS = 28;
|
|
10
24
|
/** Annualising a few days of parity carry produces meaningless yields. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PERIOD_BASE_MAX_GAP_DAYS, periodBaseDay } from "../../../market-data/market/period-return";
|
|
1
2
|
import type { CloudFredObservationPayload, CloudFredSeriesInfoPayload } from "../../../api-client";
|
|
2
3
|
import type { PricePoint } from "../../../types/financials";
|
|
3
4
|
import { VOLATILITY_CURVE_INDICES, VOLATILITY_INDICES } from "../shared/volatility-indices";
|
|
@@ -354,21 +355,15 @@ export interface VolatilityCurveLookback {
|
|
|
354
355
|
values: Partial<Record<string, number>>;
|
|
355
356
|
}
|
|
356
357
|
|
|
357
|
-
/** A week back is seven calendar days; a month back is the same day of the previous month, or its last day. */
|
|
358
|
+
/** A week back is seven calendar days; a month back is the same day of the previous month, or its last day (periodBaseDay). */
|
|
358
359
|
export function volatilityLookbackDate(date: string, id: VolatilityLookbackId): string {
|
|
359
|
-
|
|
360
|
-
const target = new Date(`${date}T00:00:00.000Z`);
|
|
361
|
-
const day = target.getUTCDate();
|
|
362
|
-
target.setUTCDate(1);
|
|
363
|
-
target.setUTCMonth(target.getUTCMonth() - 1);
|
|
364
|
-
target.setUTCDate(Math.min(day, new Date(Date.UTC(target.getUTCFullYear(), target.getUTCMonth() + 1, 0)).getUTCDate()));
|
|
365
|
-
return target.toISOString().slice(0, 10);
|
|
360
|
+
return periodBaseDay(date, id);
|
|
366
361
|
}
|
|
367
362
|
|
|
368
363
|
/**
|
|
369
364
|
* The curve a week and a month before its date, read from the same daily
|
|
370
365
|
* histories and aligned the same way: the last date on or before the look-back
|
|
371
|
-
* where the 30D and 3M both closed, else where two tenors did, within
|
|
366
|
+
* where the 30D and 3M both closed, else where two tenors did, within a market closure of it (PERIOD_BASE_MAX_GAP_DAYS).
|
|
372
367
|
* A tenor without a close on that date is a gap, never a neighbouring day.
|
|
373
368
|
*/
|
|
374
369
|
export function volatilityCurveLookbacks(data: Pick<VolatilityData, "curve" | "board" | "fred">): VolatilityCurveLookback[] {
|
|
@@ -382,7 +377,7 @@ export function volatilityCurveLookbacks(data: Pick<VolatilityData, "curve" | "b
|
|
|
382
377
|
}));
|
|
383
378
|
return (["1W", "1M"] as const).map((id) => {
|
|
384
379
|
const target = volatilityLookbackDate(curve.date!, id);
|
|
385
|
-
const floor = new Date(Date.parse(target) -
|
|
380
|
+
const floor = new Date(Date.parse(target) - PERIOD_BASE_MAX_GAP_DAYS * DAY_MS).toISOString().slice(0, 10);
|
|
386
381
|
const counts = new Map<string, number>();
|
|
387
382
|
for (const history of histories.values()) for (const day of history.keys()) {
|
|
388
383
|
if (day >= floor && day <= target) counts.set(day, (counts.get(day) ?? 0) + 1);
|
|
@@ -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";
|