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
|
@@ -29,9 +29,10 @@ export interface NotesFilesIO {
|
|
|
29
29
|
* Every note's key (its `.md` file name without the extension) and when it
|
|
30
30
|
* was last written. A folder that does not exist yet, or a note gone before
|
|
31
31
|
* it was looked at, lists nothing. Any other failure is logged and that part
|
|
32
|
-
* left out, or, with `strict`, rejects.
|
|
32
|
+
* left out, or, with `strict`, rejects. A `skipped` callback receives an
|
|
33
|
+
* unreadable note instead of rejecting the whole listing.
|
|
33
34
|
*/
|
|
34
|
-
listKeys(options?:
|
|
35
|
+
listKeys(options?: NotesListOptions): Promise<Array<[string, number]>>;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
const QUICK_NOTES_INDEX_FILE = "__quick-notes-index__.json";
|
|
@@ -108,8 +109,9 @@ export function diskNotesFilesIO(dataDir: string): NotesFilesIO {
|
|
|
108
109
|
} catch (error) {
|
|
109
110
|
// A note deleted since the folder was listed is simply gone.
|
|
110
111
|
if ((error as NodeJS.ErrnoException)?.code === "ENOENT") continue;
|
|
111
|
-
if (options?.strict) throw error;
|
|
112
|
+
if (options?.strict && !options.skipped) throw error;
|
|
112
113
|
logFailure("notes.files", "Read when a note was last written failed")(error);
|
|
114
|
+
options?.skipped?.(name.slice(0, -3), error);
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
117
|
return keys;
|
|
@@ -200,7 +202,16 @@ export function remoteNotesFilesIO(
|
|
|
200
202
|
read: async (file) => await invoke("read", { dataDir, file }) as string | null,
|
|
201
203
|
write: async (file, text) => { await invoke("write", { dataDir, file, text }); },
|
|
202
204
|
delete: async (file) => { await invoke("delete", { dataDir, file }); },
|
|
203
|
-
|
|
205
|
+
async listKeys(options) {
|
|
206
|
+
const result = await invoke("listKeys", {
|
|
207
|
+
dataDir, ...(options?.strict ? { strict: true } : {}),
|
|
208
|
+
...(options?.skipped ? { reportSkipped: true } : {}),
|
|
209
|
+
});
|
|
210
|
+
if (!options?.skipped) return result as Array<[string, number]>;
|
|
211
|
+
const { keys, skipped } = result as { keys: Array<[string, number]>; skipped: Array<{ key: string; reason: string }> };
|
|
212
|
+
for (const { key, reason } of skipped) options.skipped(key, new Error(reason));
|
|
213
|
+
return keys;
|
|
214
|
+
},
|
|
204
215
|
};
|
|
205
216
|
}
|
|
206
217
|
|
|
@@ -245,7 +256,7 @@ export class NotesFiles implements NotesStore {
|
|
|
245
256
|
|
|
246
257
|
/** Every stored note, ticker notes and quick notes alike, newest first. */
|
|
247
258
|
async list(options: NotesListOptions = {}): Promise<NoteFileEntry[]> {
|
|
248
|
-
const { entries } = await this.readEach(await this.io.listKeys(
|
|
259
|
+
const { entries } = await this.readEach(await this.io.listKeys(options), options.skipped);
|
|
249
260
|
return entries.sort((left, right) => right.updatedAt - left.updatedAt);
|
|
250
261
|
}
|
|
251
262
|
|
|
@@ -127,7 +127,7 @@ function DrugReportDetail({ record, width }: { record: DrugReport; width: number
|
|
|
127
127
|
<KeyValueRow labelWidth={LABEL_WIDTH} label="Outcome" value={record.outcomes.length > 0 ? record.outcomes.join(", ") : record.outcome ?? "Not coded"} width={width} />
|
|
128
128
|
{labelerText(record) ? <KeyValueRow labelWidth={LABEL_WIDTH} label="Labeler" value={labelerText(record)!} width={width} /> : null}
|
|
129
129
|
{record.reporter ? <KeyValueRow labelWidth={LABEL_WIDTH} label="Reporter" value={record.reporter} width={width} /> : null}
|
|
130
|
-
{record.country ? <KeyValueRow labelWidth={LABEL_WIDTH} label="Country" value={record.country} width={width} /> : null}
|
|
130
|
+
{record.country ? <KeyValueRow labelWidth={LABEL_WIDTH} label="Country" value={record.country} country={record.country} width={width} /> : null}
|
|
131
131
|
<KeyValueRow labelWidth={LABEL_WIDTH} label="Report" value={record.id.slice("drug:".length)} width={width} />
|
|
132
132
|
<Section title="Reactions" width={width}>
|
|
133
133
|
<Prose text={record.reactions.join(", ") || "None coded."} width={width} figures={false} />
|
|
@@ -4,7 +4,7 @@ import { optionSpread } from "./market-reference";
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* What holding a contract costs in time value, read the same way by the OMON
|
|
7
|
-
* columns and the LEAPS screen (`
|
|
7
|
+
* columns and the LEAPS screen (`gloom options --leaps`):
|
|
8
8
|
*
|
|
9
9
|
* intrinsic = max(0, spot - strike) for a call, max(0, strike - spot) for a put
|
|
10
10
|
* extrinsic = midpoint - intrinsic, the midpoint of a two-sided quote
|
|
@@ -50,7 +50,7 @@ export function optionCarry(
|
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Extrinsic per year net of financing and dividends, a fraction of spot per
|
|
53
|
-
* year (`
|
|
53
|
+
* year (`gloom options --leaps --columns carry-net`):
|
|
54
54
|
*
|
|
55
55
|
* call: (extrinsic - strike x rate x years + spot x dividend yield x years) / spot / years
|
|
56
56
|
* put: (extrinsic + strike x rate x years - spot x dividend yield x years) / spot / years
|
|
@@ -4,7 +4,7 @@ import { buildOptionsKey, resolveEntryData } from "../../../market-data/selector
|
|
|
4
4
|
import type { OptionsChain } from "../../../types/financials";
|
|
5
5
|
import { normalizeSymbol, parsePublicTickerKey } from "../../../utils/exchanges";
|
|
6
6
|
import { daysToExpiryFrom, volatilityTermSlope, type ExpectedMove } from "../shared/volatility";
|
|
7
|
-
import { buildSurfaceExpiry,
|
|
7
|
+
import { buildSurfaceExpiry, type SurfaceExpiry } from "../vol-surface/model";
|
|
8
8
|
import type { YieldPoint } from "../yield-curve/treasury-data";
|
|
9
9
|
|
|
10
10
|
export interface OptionsEnrichmentSelection {
|
|
@@ -97,8 +97,8 @@ export function optionsEnrichmentSelectionIssue(input: OptionsEnrichmentSelectio
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Models kept between projections of one selection. The adjacent expiry does
|
|
100
|
-
* not stream, so a live re-projection refits only the selected smile and
|
|
101
|
-
* the adjacent ATM level
|
|
100
|
+
* not stream, so a live re-projection refits only the selected smile and keeps
|
|
101
|
+
* the adjacent fit, whose ATM-forward level does not move with the spot.
|
|
102
102
|
*/
|
|
103
103
|
export interface OptionsEnrichmentCache {
|
|
104
104
|
neighbour?: { chain: OptionsChain; curve: readonly YieldPoint[] | undefined; model: SurfaceExpiry };
|
|
@@ -134,17 +134,18 @@ export function projectOptionsEnrichment(input: OptionsEnrichmentProjection, cac
|
|
|
134
134
|
else if (neighbourChain) {
|
|
135
135
|
const cached = cache?.neighbour?.chain === neighbourChain && cache.neighbour.curve === input.curve
|
|
136
136
|
? cache.neighbour.model : null;
|
|
137
|
-
const neighbour = cached
|
|
138
|
-
:
|
|
139
|
-
curve: input.curve ?? [], now: input.now, source: input.neighbourEntry?.source });
|
|
137
|
+
const neighbour = cached ?? buildSurfaceExpiry({ chain: neighbourChain, expiration: neighbourExpiration, spot: input.spot,
|
|
138
|
+
curve: input.curve ?? [], now: input.now, source: input.neighbourEntry?.source });
|
|
140
139
|
if (cache && !cached) cache.neighbour = { chain: neighbourChain, curve: input.curve, model: neighbour };
|
|
141
140
|
result.rateAsOf = [...new Set([...result.rateAsOf, ...neighbour.rateAsOf])];
|
|
142
141
|
result.warnings.push(...neighbour.warnings
|
|
143
142
|
.filter((warning) => !(input.curveLoading && warning === "Treasury rate unavailable"))
|
|
144
143
|
.map((warning) => `Adjacent expiry: ${warning}`));
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
// The slope runs between the two expiries' IVs at their forwards, as OVDV's does, so a print
|
|
145
|
+
// against a closed session's chain does not tilt it.
|
|
146
|
+
if (selected.skew.atm != null && neighbour.skew.atm != null) {
|
|
147
|
+
Object.assign(result, optionsEnrichmentTermSlope({ years: selected.years, volatility: selected.skew.atm },
|
|
148
|
+
{ years: neighbour.years, volatility: neighbour.skew.atm }));
|
|
148
149
|
if (new Date(selected.asOf!).toISOString().slice(0, 10) !== new Date(neighbour.asOf!).toISOString().slice(0, 10)) {
|
|
149
150
|
result.warnings.push("Term slope uses option observations from different dates");
|
|
150
151
|
}
|
|
@@ -135,7 +135,7 @@ export const optionsModule: PluginModule = {
|
|
|
135
135
|
paneId: "options",
|
|
136
136
|
label: "Options",
|
|
137
137
|
description: "Options chain for the selected ticker.",
|
|
138
|
-
// Where a put seller picks the strike; OSA
|
|
138
|
+
// Where a put seller picks the strike; CSP and OSA own the exact put-selling phrases and rank first on them.
|
|
139
139
|
keywords: ["options", "chain", "calls", "puts", "omon", "cash-secured puts", "selling puts", "short-put strikes", "csp strikes", "wheel strikes"],
|
|
140
140
|
shortcut: "OMON",
|
|
141
141
|
settings: (_symbol, _context, options) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getExtendedSessionDisplay, type ExtendedSession } from "../../../market-data/market/status";
|
|
1
2
|
import { getPublishedUsEquitySession } from "../../../market-data/published-us-sessions";
|
|
2
3
|
import type { OptionsChain, Quote } from "../../../types/financials";
|
|
3
4
|
import { zonedWallClockToUtcMs } from "../../../utils/zoned-date-time";
|
|
@@ -82,10 +83,75 @@ export function formatSpotTime(time: number): string {
|
|
|
82
83
|
return `${WEEKDAYS[date.getUTCDay()]} ${date.getUTCDate()} ${MONTHS[date.getUTCMonth()]} ${date.toISOString().slice(11, 16)} UTC`;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
type SpotStampInput = Pick<OptionModelSpot, "basis" | "session" | "observedAt">;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The stamp every options pane puts beside the spot it priced a chain with
|
|
90
|
+
* (docs/research-data.md#greeks-spot-and-time): `close Tue 20 Oct` for the
|
|
91
|
+
* official close of the session the chain was quoted in, `pre-market Wed 21
|
|
92
|
+
* Oct 09:35 UTC` (`after hours`, `overnight`) for an extended-session print.
|
|
93
|
+
* Null for the regular session's latest price, which the pane's live or
|
|
94
|
+
* delayed status already dates.
|
|
95
|
+
*/
|
|
96
|
+
export function modelSpotStamp(spot: SpotStampInput): string | null {
|
|
97
|
+
const dated = Number.isFinite(spot.observedAt);
|
|
98
|
+
if (spot.basis === "close") return dated ? `close ${formatCalendarDay(newYorkDate.format(spot.observedAt))}` : "close";
|
|
99
|
+
return spot.session && dated ? `${spot.session} ${formatSpotTime(spot.observedAt)}` : null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The stamp's shorter forms, longest first, for a figure with less room
|
|
104
|
+
* (`StatItem.detailVariants`): `pre-market 09:35 UTC`, then `pre-market`;
|
|
105
|
+
* `close`. Empty when there is no stamp.
|
|
106
|
+
*/
|
|
107
|
+
export function modelSpotStampVariants(spot: SpotStampInput): string[] {
|
|
108
|
+
if (!modelSpotStamp(spot)) return [];
|
|
109
|
+
if (spot.basis === "close") return ["close"];
|
|
110
|
+
return [`${spot.session} ${new Date(spot.observedAt).toISOString().slice(11, 16)} UTC`, spot.session!];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The stamp where a report or footer always dates the spot: `last Wed 21 Oct 14:05 UTC` for the regular session's price. */
|
|
114
|
+
export function modelSpotLabel(spot: SpotStampInput): string {
|
|
115
|
+
return modelSpotStamp(spot) ?? `last ${formatSpotTime(spot.observedAt)}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const HOUR_MS = 60 * 60_000;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A spot known only by its price and when it was observed, such as the one
|
|
122
|
+
* Gloom Cloud prices dealer gamma at: the session that time falls in on the
|
|
123
|
+
* listing's calendar. Pre-market from 04:00 New York to the open, after hours
|
|
124
|
+
* for four hours from the close, overnight between; a day the calendar does
|
|
125
|
+
* not know reads as the latest price.
|
|
126
|
+
*/
|
|
127
|
+
export function observedModelSpot(price: number, observedAt: number, exchange?: string): OptionModelSpot {
|
|
128
|
+
const day = Number.isFinite(observedAt) ? getPublishedUsEquitySession(exchange || "NYSE", newYorkDate.format(observedAt)) : null;
|
|
129
|
+
const session: OptionModelSpot["session"] = day?.kind !== "session" ? null
|
|
130
|
+
: observedAt < day.open ? (observedAt >= day.open - 5.5 * HOUR_MS ? "pre-market" : "overnight")
|
|
131
|
+
: observedAt < day.close ? null
|
|
132
|
+
: observedAt < day.close + 4 * HOUR_MS ? "after hours" : "overnight";
|
|
133
|
+
return { price, observedAt, valuationTime: observedAt, basis: "last", session };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const EXTENDED_SESSION_WORDS: Record<ExtendedSession, NonNullable<OptionModelSpot["session"]>> = {
|
|
137
|
+
PRE: "pre-market", POST: "after hours", OVERNIGHT: "overnight",
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The underlying's extended-session print beside a spot priced at the close,
|
|
142
|
+
* named by its session as the stamp names it: `pre-market 770.65`, `after
|
|
143
|
+
* hours mid 771.10`. Null when the spot is not the close, nothing traded
|
|
144
|
+
* outside the session, or the print is the spot.
|
|
145
|
+
*/
|
|
146
|
+
export function modelSpotExtendedPrint(
|
|
147
|
+
quote: Quote | null | undefined,
|
|
148
|
+
spot: Pick<OptionModelSpot, "basis" | "price">,
|
|
149
|
+
format: (price: number) => string = formatModelSpotPrice,
|
|
150
|
+
): string | null {
|
|
151
|
+
if (spot.basis !== "close") return null;
|
|
152
|
+
const print = getExtendedSessionDisplay(quote);
|
|
153
|
+
if (!print || !positive(print.price) || format(print.price) === format(spot.price)) return null;
|
|
154
|
+
return `${EXTENDED_SESSION_WORDS[print.session]}${print.mark ? " mid" : ""} ${format(print.price)}`;
|
|
89
155
|
}
|
|
90
156
|
|
|
91
157
|
/** A price to the cent, or to the tick it was quoted at below a dollar. */
|
|
@@ -5,9 +5,10 @@ import { colors, priceColor } from "../../../theme/colors";
|
|
|
5
5
|
import { isPlainKey } from "../../../utils/keyboard";
|
|
6
6
|
import { formatCompact, formatPercentRaw } from "../../../utils/format";
|
|
7
7
|
import { formatMarketPrice, formatSignedMarketPrice, liveQuoteFormatOptions } from "../../../market-data/market/format";
|
|
8
|
+
import { getRegularSessionDisplay } from "../../../market-data/market/status";
|
|
8
9
|
import { chainOptionContract, formatExpDate, optionContractName, resolveOptionsTarget } from "../../../utils/options";
|
|
9
10
|
import {
|
|
10
|
-
expiryIsoDate, findListedExpiry, formatDaysToExpiry, daysToExpiry, missingExpiryMessage, missingExpiryText, readOptionExpiration,
|
|
11
|
+
expiryIsoDate, findListedExpiry, formatDaysToExpiry, daysToExpiry, isLiveOptionExpiry, missingExpiryMessage, missingExpiryText, readOptionExpiration,
|
|
11
12
|
} from "../../../utils/option-expiry";
|
|
12
13
|
import { canonicalTickerKey } from "../../../utils/exchanges";
|
|
13
14
|
import { isOptionsUnavailableError, listedOptionsAlternative, optionsUnavailableTitle } from "../../../market-data/options-alternatives";
|
|
@@ -68,7 +69,7 @@ import { signedPositionDirection } from "../../../portfolio/position-metrics";
|
|
|
68
69
|
import { optionMarketReference } from "./market-reference";
|
|
69
70
|
import { useOptionsEnrichment } from "./enrichment";
|
|
70
71
|
import type { OptionsEnrichmentSnapshot } from "./enrichment-model";
|
|
71
|
-
import {
|
|
72
|
+
import { optionMid, type OptionSide } from "../shared/volatility";
|
|
72
73
|
import type { TickerRecord } from "../../../types/ticker";
|
|
73
74
|
import type { TickerFinancials } from "../../../types/financials";
|
|
74
75
|
import type { IvStats } from "../iv-history/client";
|
|
@@ -76,7 +77,10 @@ import { useIvRank } from "../iv-history/rank";
|
|
|
76
77
|
import { useOptionsSessionOpen, useThrottledValue } from "../shared/volatility/live-session";
|
|
77
78
|
import { useRemoteUiNode } from "../../../remote/semantic-tree";
|
|
78
79
|
import { optionCarry, optionCostOfSpot } from "./carry";
|
|
79
|
-
import {
|
|
80
|
+
import {
|
|
81
|
+
formatModelSpotPrice, modelSpotExtendedPrint, modelSpotLabel, modelSpotStamp, modelSpotStampVariants, optionModelSpot,
|
|
82
|
+
type OptionModelSpot,
|
|
83
|
+
} from "./model-spot";
|
|
80
84
|
import { chainOpenInterestAsOf, loadListedOpenInterest, openInterestAsOfLabel, statedOpenInterestAsOf } from "./open-interest-as-of";
|
|
81
85
|
import { useAsyncResource } from "../../../react/async-resource";
|
|
82
86
|
import {
|
|
@@ -113,13 +117,35 @@ function transientTicker(symbol: string, exchange: string, currency: string): Ti
|
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
/**
|
|
116
|
-
* The underlying's price
|
|
117
|
-
*
|
|
120
|
+
* The underlying's price: the level every strike is read against. A chain
|
|
121
|
+
* priced at a session's close or an extended-session print shows that spot
|
|
122
|
+
* with its stamp (`modelSpotStamp`), and any extended print after it named by
|
|
123
|
+
* its session; the regular session's live price shows its day change. A stale
|
|
124
|
+
* quote stays on screen, muted, while the footer says why.
|
|
118
125
|
*/
|
|
119
|
-
function spotItem(
|
|
126
|
+
function spotItem(
|
|
127
|
+
underlying: TickerFinancials | null | undefined,
|
|
128
|
+
assetCategory: string | undefined,
|
|
129
|
+
modelSpot: OptionModelSpot | null,
|
|
130
|
+
): StatItem {
|
|
120
131
|
const quote = underlying?.quote;
|
|
121
132
|
if (!quote || !Number.isFinite(quote.price)) return { id: "spot", label: "Spot", value: "--" };
|
|
122
133
|
const options = liveQuoteFormatOptions(quote, quote.currency, assetCategory, underlying?.quoteMetadata?.instrumentType);
|
|
134
|
+
const stamp = modelSpot ? modelSpotStamp(modelSpot) : null;
|
|
135
|
+
if (modelSpot && stamp) {
|
|
136
|
+
const move = modelSpot.basis === "close" ? getRegularSessionDisplay(quote)?.change : quote.change;
|
|
137
|
+
const extended = modelSpotExtendedPrint(quote, modelSpot, (price) => formatMarketPrice(price, options));
|
|
138
|
+
// The band keeps its columns: the extended print, then the stamp's day, give way first.
|
|
139
|
+
const shorter = modelSpotStampVariants(modelSpot);
|
|
140
|
+
return {
|
|
141
|
+
id: "spot",
|
|
142
|
+
label: "Spot",
|
|
143
|
+
value: formatMarketPrice(modelSpot.price, options),
|
|
144
|
+
detail: extended ? `${stamp} · ${extended}` : stamp,
|
|
145
|
+
detailVariants: extended ? [stamp, ...shorter] : shorter,
|
|
146
|
+
color: quote.stale ? colors.textDim : priceColor(Number.isFinite(move) ? move! : 0),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
123
149
|
const change = Number.isFinite(quote.change) ? quote.change : 0;
|
|
124
150
|
return {
|
|
125
151
|
id: "spot",
|
|
@@ -243,10 +269,10 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
243
269
|
const strikeWindowText = strikeWindowValue(strikeWindow);
|
|
244
270
|
const initialChainEntry = useOptionsQuery(baseRequest);
|
|
245
271
|
const initialChain = useResolvedEntryValue(initialChainEntry);
|
|
246
|
-
// A listing can still carry a date whose
|
|
272
|
+
// A listing can still carry a date whose last session has closed. The chain
|
|
247
273
|
// never opens there, nor on a saved date that has since passed: it takes the nearest live one.
|
|
248
274
|
const now = Date.now();
|
|
249
|
-
const liveExpiration = (expiration: number) =>
|
|
275
|
+
const liveExpiration = (expiration: number) => isLiveOptionExpiry(expiration, now, effectiveExchange);
|
|
250
276
|
const listedExpirations = initialChain?.expirationDates ?? [];
|
|
251
277
|
const openingExpirations = listedExpirations.some(liveExpiration) ? listedExpirations.filter(liveExpiration) : listedExpirations;
|
|
252
278
|
const initialExpiration = openingExpirations.length === 0 ? undefined : openingExpirations.reduce((best, expiration) => (
|
|
@@ -295,10 +321,10 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
295
321
|
const expirationDates = useMemo(() => {
|
|
296
322
|
const listed = selectedExpirationMissing
|
|
297
323
|
? [...availableExpirations, selectedExpiration!].sort((left, right) => left - right) : availableExpirations;
|
|
298
|
-
// A date
|
|
299
|
-
const current = (expiration: number) =>
|
|
324
|
+
// A date whose last session has closed has no contracts left to show; the strip leaves it out, unless every date has.
|
|
325
|
+
const current = (expiration: number) => isLiveOptionExpiry(expiration, Date.now(), effectiveExchange);
|
|
300
326
|
return listed.some(current) ? listed.filter((expiration) => expiration === selectedExpiration || current(expiration)) : listed;
|
|
301
|
-
}, [availableExpirations, selectedExpiration, selectedExpirationMissing]);
|
|
327
|
+
}, [availableExpirations, effectiveExchange, selectedExpiration, selectedExpirationMissing]);
|
|
302
328
|
// Keep the date strip stable while a mouse press focuses this pane. A new
|
|
303
329
|
// tab list asks the web host to reveal the active tab and can move the date
|
|
304
330
|
// being clicked before mouse-up, cancelling selection of an offscreen expiry.
|
|
@@ -418,7 +444,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
418
444
|
const chainAsOfMs = asOfChain?.asOf ? Date.parse(asOfChain.asOf) : Number.NaN;
|
|
419
445
|
const expiryAsOfMs = Number.isFinite(chainAsOfMs) ? chainAsOfMs : Date.now();
|
|
420
446
|
const expiryDate = selectedExpiration == null ? "" : expiryIsoDate(selectedExpiration);
|
|
421
|
-
const expiryDays = selectedExpiration == null ? "" : formatDaysToExpiry(selectedExpiration, expiryAsOfMs);
|
|
447
|
+
const expiryDays = selectedExpiration == null ? "" : formatDaysToExpiry(selectedExpiration, expiryAsOfMs, effectiveExchange);
|
|
422
448
|
useRemoteUiNode(expiryDate && chain && !expirationUnavailable ? {
|
|
423
449
|
role: "report-notice",
|
|
424
450
|
label: "Expiry",
|
|
@@ -448,7 +474,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
448
474
|
...(chainDelay > 0 ? { delayMinutes: chainDelay } : {}),
|
|
449
475
|
}),
|
|
450
476
|
} : null);
|
|
451
|
-
// A report of the pane (`
|
|
477
|
+
// A report of the pane (`gloom fn OMON`) says how many strikes it lists of how many the expiry has.
|
|
452
478
|
useRemoteUiNode(strikeChain ? {
|
|
453
479
|
role: "report-notice",
|
|
454
480
|
label: "Strike window",
|
|
@@ -552,10 +578,10 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
552
578
|
putGreeks: volatilities ? calculateOptionGreeks(put, "put", greeksSpot, dividendYield, volatilities) : undefined,
|
|
553
579
|
callExtrinsicPerYear: call && volatilities ? optionCarry(call, "call", greeksSpot, volatilities.valuationTime)?.extrinsicPerYear ?? null : null,
|
|
554
580
|
putExtrinsicPerYear: put && volatilities ? optionCarry(put, "put", greeksSpot, volatilities.valuationTime)?.extrinsicPerYear ?? null : null,
|
|
555
|
-
putCostOfSpot: put ? optionCostOfSpot(put,
|
|
581
|
+
putCostOfSpot: put ? optionCostOfSpot(put, greeksSpot) : null,
|
|
556
582
|
isPositionStrike: !!parsed && strike === parsed.strike,
|
|
557
583
|
};
|
|
558
|
-
}), [callsByStrike, dividendYield, greeksSpot, parsed, putsByStrike,
|
|
584
|
+
}), [callsByStrike, dividendYield, greeksSpot, parsed, putsByStrike, strikes, volatilities]);
|
|
559
585
|
// The open interest's session: the chain's own, or for a chain that does not say, OPX's listing of the
|
|
560
586
|
// same expiry, stated only when the counts are OPX's.
|
|
561
587
|
const statedOpenInterest = useMemo(() => strikeChain ? statedOpenInterestAsOf(strikeChain) : undefined, [strikeChain]);
|
|
@@ -566,7 +592,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
566
592
|
const openInterestAsOf = useMemo(() => statedOpenInterest
|
|
567
593
|
?? (strikeChain && listedOpenInterest.data ? chainOpenInterestAsOf(strikeChain, listedOpenInterest.data) : null),
|
|
568
594
|
[statedOpenInterest, strikeChain, listedOpenInterest.data]);
|
|
569
|
-
// A report of the pane (`
|
|
595
|
+
// A report of the pane (`gloom fn OMON`) names them too.
|
|
570
596
|
useRemoteUiNode(modelSpot ? {
|
|
571
597
|
role: "report-notice",
|
|
572
598
|
label: "Greeks spot",
|
|
@@ -584,10 +610,12 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
584
610
|
} : null);
|
|
585
611
|
// What IV and the Greeks are valued at, and the open interest's date. In a
|
|
586
612
|
// crowded footer it shortens, then gives way to the contract under the cursor.
|
|
587
|
-
|
|
613
|
+
// A stamped spot (a close, an extended print) is already the Spot figure's.
|
|
614
|
+
const footerSpot = modelSpot && !modelSpotStamp(modelSpot) ? modelSpot : null;
|
|
615
|
+
const basisText = [footerSpot ? `spot ${formatModelSpotPrice(footerSpot.price)} ${modelSpotLabel(footerSpot)}` : null,
|
|
588
616
|
strikeChain && !listedOpenInterest.loading ? openInterestAsOfLabel(openInterestAsOf) : null].filter(Boolean).join(" · ");
|
|
589
|
-
const shortBasisText = [
|
|
590
|
-
+ `${new Date(
|
|
617
|
+
const shortBasisText = [footerSpot ? `${formatModelSpotPrice(footerSpot.price)} last `
|
|
618
|
+
+ `${new Date(footerSpot.observedAt).toISOString().slice(11, 16)} UTC` : null,
|
|
591
619
|
strikeChain && !listedOpenInterest.loading ? openInterestAsOf?.date ? `OI ${openInterestAsOf.date.slice(5)}` : "OI undated" : null]
|
|
592
620
|
.filter(Boolean).join(" · ");
|
|
593
621
|
usePaneFooter("options-basis", () => ({ info: basisText ? [{ id: "greeks-basis",
|
|
@@ -597,9 +625,9 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
597
625
|
// busy stream reads as a steady strip rather than flicker.
|
|
598
626
|
// A new expiry, a refreshed snapshot or the underlying price arriving or
|
|
599
627
|
// going stale shows at once; only the stream itself is paced.
|
|
600
|
-
const summaryResetKey = useMemo(() => ({}), [strikeSelectionKey, strikeChain,
|
|
628
|
+
const summaryResetKey = useMemo(() => ({}), [strikeSelectionKey, strikeChain, greeksSpot == null]);
|
|
601
629
|
const summaryInput = useThrottledValue(
|
|
602
|
-
useMemo(() => ({ chain: liveChain, spot, volatilities }), [liveChain,
|
|
630
|
+
useMemo(() => ({ chain: liveChain, spot: greeksSpot, volatilities }), [liveChain, greeksSpot, volatilities]),
|
|
603
631
|
OPTIONS_SUMMARY_THROTTLE_MS,
|
|
604
632
|
summaryResetKey,
|
|
605
633
|
);
|
|
@@ -613,7 +641,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
613
641
|
instrument: baseRequest?.instrument ?? null, expiration: selectedExpiration,
|
|
614
642
|
selectedEntry: strikeChain === expirationChain ? expirationChainEntry
|
|
615
643
|
: strikeChain === initialChain ? initialChainEntry : null,
|
|
616
|
-
catalogue: availableExpirations, spot, spotAsOf:
|
|
644
|
+
catalogue: availableExpirations, spot: greeksSpot, spotAsOf: modelSpot?.observedAt,
|
|
617
645
|
liveChain: liveChain !== strikeChain ? liveChain : null,
|
|
618
646
|
});
|
|
619
647
|
const enrichment = expirationUnavailable ? null : enrichmentState.snapshot;
|
|
@@ -901,7 +929,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
901
929
|
// The root insets the terminal body, so the band gets the width inside it.
|
|
902
930
|
const statWidth = Math.max(1, width - (nativePaneChrome ? 0 : 2));
|
|
903
931
|
const figures = optionsSummaryItems({
|
|
904
|
-
spot: spotItem(underlying, isOpt ? undefined : ticker.metadata.assetCategory),
|
|
932
|
+
spot: spotItem(underlying, isOpt ? undefined : ticker.metadata.assetCategory, modelSpot),
|
|
905
933
|
summary, enrichment, currency: underlying?.quote?.currency || ticker.metadata.currency || "",
|
|
906
934
|
ivRank: showIvRank ? { stats: ivRank } : null,
|
|
907
935
|
});
|
|
@@ -9,18 +9,56 @@ import { createCalculatorSurfaceDependencies, loadCalculatorSurfaceVol, type Cal
|
|
|
9
9
|
const number = (value: number) => Number.isFinite(value) ? value.toFixed(6) : "--";
|
|
10
10
|
const metric = (label: string, value: number, suffix = ""): HeadlessPaneEntry => ({ label, value, formatted: `${number(value)}${suffix}` });
|
|
11
11
|
|
|
12
|
+
/** What was typed for each input, by option key: the CLI's strings, a pane's settings. */
|
|
13
|
+
type EnteredInputs = Readonly<Record<string, unknown>>;
|
|
14
|
+
const PLAIN_DECIMAL = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/;
|
|
15
|
+
/** A computed number without float noise or padding: 73.15, 30, 60. */
|
|
16
|
+
const plain = (value: number) => Number.isFinite(value) ? String(Number(value.toPrecision(12))) : "--";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* An input echoed as it was entered: the typed text when it was a plain
|
|
20
|
+
* decimal of this value (73.15 stays 73.15, 73.150 stays 73.150), else the
|
|
21
|
+
* number without padding. Percent inputs (`scale` 100) compare the typed
|
|
22
|
+
* percent with the decimal the model reads.
|
|
23
|
+
*/
|
|
24
|
+
function enteredText(entered: EnteredInputs, key: string, value: number, scale = 1): string {
|
|
25
|
+
const raw = entered[key];
|
|
26
|
+
const text = typeof raw === "string" ? raw.trim() : "";
|
|
27
|
+
if (PLAIN_DECIMAL.test(text) && Number(plain(Number(text) / scale)) === Number(plain(value))) return text.replace(/^\+/, "");
|
|
28
|
+
return plain(value * scale);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A price or day count, at the precision it was entered. */
|
|
32
|
+
const input = (entered: EnteredInputs, label: string, key: string, value: number): HeadlessPaneEntry => (
|
|
33
|
+
{ label, value, formatted: enteredText(entered, key, value) }
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/** A volatility or rate in percent, as the options ask for it: 60%, never 0.600000. */
|
|
37
|
+
const percentInput = (entered: EnteredInputs, label: string, key: string, value: number): HeadlessPaneEntry => {
|
|
38
|
+
const text = enteredText(entered, key, value, 100);
|
|
39
|
+
return { label, value: Number(text), unit: "%", formatted: `${text}%` };
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** A volatility read off the surface was not typed, so it reads to the hundredth of a point. */
|
|
43
|
+
const surfacePercent = (label: string, value: number): HeadlessPaneEntry => {
|
|
44
|
+
const percent = Number((value * 100).toFixed(2));
|
|
45
|
+
return { label, value: percent, unit: "%", formatted: `${percent}%` };
|
|
46
|
+
};
|
|
47
|
+
|
|
12
48
|
function report(draft: OptionCalcDraft, valuation: OptionValuation | null,
|
|
13
49
|
implied: { volatility: number | null; note: string | null }, surface: CalculatorSurfaceVol | null,
|
|
14
|
-
errors: string[], effectiveTreeSteps: number | null = null): HeadlessBundleResult {
|
|
50
|
+
errors: string[], effectiveTreeSteps: number | null = null, entered: EnteredInputs = {}): HeadlessBundleResult {
|
|
15
51
|
const model = draft.pricingModel ?? "european";
|
|
16
52
|
return {
|
|
17
53
|
sections: [
|
|
18
54
|
{ title: "Inputs", entries: [
|
|
19
55
|
...(draft.symbol ? [{ label: "Underlying", value: draft.symbol }] : []),
|
|
20
56
|
{ label: "Model", value: model }, { label: "Side", value: draft.side },
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
57
|
+
input(entered, "Spot", "spot", draft.spot), input(entered, "Strike", "strike", draft.strike),
|
|
58
|
+
input(entered, "Days to expiry", "days", draft.daysToExpiry),
|
|
59
|
+
surface?.volatility != null ? surfacePercent("Volatility", draft.volatility) : percentInput(entered, "Volatility", "volatility", draft.volatility),
|
|
60
|
+
percentInput(entered, "Annual rate", "rate", draft.rate),
|
|
61
|
+
percentInput(entered, "Annual dividend yield", "dividendYield", draft.dividendYield),
|
|
24
62
|
...(model === "american" ? [{ label: "Requested tree steps", value: draft.steps ?? 400 }] : []),
|
|
25
63
|
...(effectiveTreeSteps != null && effectiveTreeSteps !== (draft.steps ?? 400)
|
|
26
64
|
? [{ label: "Effective tree steps", value: effectiveTreeSteps }] : []),
|
|
@@ -68,7 +106,8 @@ export const optionsCalculatorHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
68
106
|
{ key: "marketPrice", aliases: ["market-price"], type: "string", description: "Observed premium per unit for implied volatility inversion" },
|
|
69
107
|
],
|
|
70
108
|
async load(args, ctx) {
|
|
71
|
-
const
|
|
109
|
+
const entered = { ...ctx.settings, ...args.options };
|
|
110
|
+
const draft = draftFromCalculatorInputs(entered);
|
|
72
111
|
const dividends = draft.dividends ?? [];
|
|
73
112
|
if (draft.pricingModel !== "american" && dividends.some((dividend) => dividend.amount > 0)) {
|
|
74
113
|
throw new Error("Discrete cash dividends require the American CRR model.");
|
|
@@ -83,7 +122,7 @@ export const optionsCalculatorHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
83
122
|
spot: draft.spot, strike: draft.strike, daysToExpiry: draft.daysToExpiry, signal: ctx.signal,
|
|
84
123
|
}, createCalculatorSurfaceDependencies(ctx.marketData, ctx.apiClient));
|
|
85
124
|
if (surface.volatility == null || surface.error) return report(draft, null,
|
|
86
|
-
{ volatility: null, note: "Surface volatility unavailable" }, surface, [surface.error ?? "Surface volatility unavailable"]);
|
|
125
|
+
{ volatility: null, note: "Surface volatility unavailable" }, surface, [surface.error ?? "Surface volatility unavailable"], null, entered);
|
|
87
126
|
valuedDraft = { ...draft, volatility: surface.volatility };
|
|
88
127
|
}
|
|
89
128
|
ctx.signal.throwIfAborted();
|
|
@@ -93,6 +132,6 @@ export const optionsCalculatorHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
93
132
|
const implied = valuedDraft.marketPrice > 0 ? valuedDraft.pricingModel === "american"
|
|
94
133
|
? solveBinomialImpliedVolatility(valuedDraft, valuedDraft.marketPrice, tree)
|
|
95
134
|
: solveImpliedVolatility(valuedDraft, valuedDraft.marketPrice) : { volatility: null, note: null };
|
|
96
|
-
return report(valuedDraft, valuation, implied, surface, [], effectiveTreeSteps);
|
|
135
|
+
return report(valuedDraft, valuation, implied, surface, [], effectiveTreeSteps, entered);
|
|
97
136
|
},
|
|
98
137
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { unavailableText } from "../../../components/ui/status";
|
|
1
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
3
|
import { delayedFooterSegment, FieldGrid, KeyValueRow, QueryBar, usePaneFooter, usePaneNoticeFooter, type GridField } from "../../../components";
|
|
3
4
|
import { CompositeChart } from "../../../components/chart/composite/composite-chart";
|
|
@@ -194,7 +195,7 @@ export function OptionsCalculatorPane({ focused, width, height }: PaneProps) {
|
|
|
194
195
|
const calculation = useMemo(() => {
|
|
195
196
|
const unavailable = seedError ?? (american ? dividendInput.error : null)
|
|
196
197
|
?? (surfaceSource && !draft.symbol ? "Choose an underlying ticker for surface IV." : null)
|
|
197
|
-
?? (surfaceSource && !surfaceResource.loading && surface?.volatility == null ? surface?.error ?? surfaceResource.error ?? "Surface IV
|
|
198
|
+
?? (surfaceSource && !surfaceResource.loading && surface?.volatility == null ? surface?.error ?? surfaceResource.error ?? unavailableText("Surface IV") : null);
|
|
198
199
|
if (unavailable || surfaceSource && surface?.volatility == null) {
|
|
199
200
|
return { valuation: null, implied: { volatility: null, note: null }, problem: unavailable };
|
|
200
201
|
}
|
|
@@ -400,7 +401,7 @@ function ContractPremiumChart({
|
|
|
400
401
|
width: number;
|
|
401
402
|
focused: boolean;
|
|
402
403
|
}) {
|
|
403
|
-
const empty = unavailable ? "Premium history
|
|
404
|
+
const empty = unavailable ? unavailableText("Premium history") : series.length < 1 ? "No premium history." : undefined;
|
|
404
405
|
return (
|
|
405
406
|
<Box flexDirection="column" paddingX={1} height={PREMIUM_CHART_ROWS} flexShrink={0}>
|
|
406
407
|
{empty && !loading ? (
|
|
@@ -2,6 +2,8 @@ import type { HeadlessPaneDefinition, HeadlessPaneEntry } from "../../../types/p
|
|
|
2
2
|
import { expirationOptionSeconds, expiryIsoDate, OPTION_EXPIRATION_FORMAT, OPTION_EXPIRATION_PLACEHOLDER } from "../../../utils/option-expiry";
|
|
3
3
|
import { formatUtcTime } from "../../../utils/utc-time";
|
|
4
4
|
import { loadGamma, loadOpenInterest, positioningSymbol, type GammaPayload, type OpenInterestPayload } from "./client";
|
|
5
|
+
import { listingFateReport, loadListingFate } from "../../../tickers/listing-fate";
|
|
6
|
+
import { resolveHeadlessInstrument } from "../shared/headless-market-data";
|
|
5
7
|
import {
|
|
6
8
|
ALL_EXPIRIES,
|
|
7
9
|
expiryLabel,
|
|
@@ -10,6 +12,7 @@ import {
|
|
|
10
12
|
formatDistance,
|
|
11
13
|
formatGamma,
|
|
12
14
|
formatLevel,
|
|
15
|
+
formatPositioningSpot,
|
|
13
16
|
formatPayout,
|
|
14
17
|
formatRatio,
|
|
15
18
|
formatStrike,
|
|
@@ -49,7 +52,7 @@ function summary(openInterest: OpenInterestPayload, dealer: GammaPayload | null)
|
|
|
49
52
|
{ key: "oiDate", label: "Open interest as of", value: openInterest.oiDate },
|
|
50
53
|
];
|
|
51
54
|
const textEntries: HeadlessPaneEntry[] = [
|
|
52
|
-
{ label: "Spot", value: spot, formatted:
|
|
55
|
+
{ label: "Spot", value: spot, formatted: formatPositioningSpot(spot, spotAsOf) },
|
|
53
56
|
...(dealer ? [{ label: "Quotes as of", value: dealer.quotesAsOf, formatted: time(dealer.quotesAsOf) }] : []),
|
|
54
57
|
{ label: "Open interest as of", value: openInterest.oiDate, formatted: openInterest.oiDate ?? "--" },
|
|
55
58
|
];
|
|
@@ -118,7 +121,7 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
118
121
|
// VIX has no dealer gamma, so its expiries have no column for it.
|
|
119
122
|
const expiryGamma = !(allExpiries instanceof Error) && allExpiries.total ? netGammaByExpiry(allExpiries) : null;
|
|
120
123
|
const gammaColumn = allExpiries instanceof Error || !!allExpiries.total;
|
|
121
|
-
const
|
|
124
|
+
const loadErrors = [
|
|
122
125
|
...openInterest.warnings,
|
|
123
126
|
...(dealer instanceof Error ? [`Dealer gamma: ${dealer.message}`] : [
|
|
124
127
|
...dealer.warnings,
|
|
@@ -126,6 +129,11 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
126
129
|
]),
|
|
127
130
|
...(everyExpiry instanceof Error ? [`Net GEX by expiry: ${everyExpiry.message}`] : []),
|
|
128
131
|
];
|
|
132
|
+
// A symbol with no listed open interest says what became of it when something did (TWTR stopped
|
|
133
|
+
// trading, FB is a fund now) in place of the load's errors.
|
|
134
|
+
const fate = openInterest.expiries.length || expiry ? null
|
|
135
|
+
: listingFateReport(await loadListingFate(await resolveHeadlessInstrument(ctx, symbol), ctx.marketData), { served: false }, loadErrors);
|
|
136
|
+
const errors = fate?.errors ?? loadErrors;
|
|
129
137
|
const changes = openInterest.previousOiDate != null;
|
|
130
138
|
const gammaShown = dealer instanceof Error || !dealer.total ? null : dealer;
|
|
131
139
|
const scope = dealer instanceof Error ? null : dealer.expiry ? expiryLabel(dealer.expiry) : "all expiries";
|
|
@@ -173,7 +181,7 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
173
181
|
],
|
|
174
182
|
complete: !!openInterest.expiries.length && !(dealer instanceof Error) && errors.length === 0,
|
|
175
183
|
unavailableSymbols: openInterest.expiries.length ? [] : [symbol],
|
|
176
|
-
errors,
|
|
184
|
+
errors, ...(fate?.notes.length ? { notes: fate.notes } : {}),
|
|
177
185
|
metadata: {
|
|
178
186
|
underlying: openInterest.underlying,
|
|
179
187
|
oiDate: openInterest.oiDate,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatCompact, formatCompactAmount } from "../../../utils/format";
|
|
2
2
|
import { formatExpDate } from "../../../utils/options";
|
|
3
|
+
import { modelSpotLabel, modelSpotStamp, modelSpotStampVariants, observedModelSpot } from "../options/model-spot";
|
|
3
4
|
|
|
4
5
|
export type PositioningTab = "strikes" | "expiries" | "gex";
|
|
5
6
|
export const POSITIONING_TABS: { value: PositioningTab; label: string }[] = [
|
|
@@ -66,6 +67,29 @@ export function formatRatio(value: number | null | undefined): string {
|
|
|
66
67
|
export function formatLevel(value: number | null | undefined): string {
|
|
67
68
|
return value == null || !Number.isFinite(value) ? "--" : value.toFixed(2);
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* The spot Gloom Cloud read the distances and dealer gamma at, stamped as
|
|
72
|
+
* every options pane stamps its spot (`modelSpotStamp`), as a stat cell
|
|
73
|
+
* carries it: `pre-market Wed 21 Oct 09:35 UTC`, its shorter forms, then
|
|
74
|
+
* none, so the band keeps the columns it has in regular hours. Nothing for
|
|
75
|
+
* the regular session's price.
|
|
76
|
+
*/
|
|
77
|
+
export function positioningSpotDetail(spot: number | null | undefined, spotAsOf: string | null | undefined):
|
|
78
|
+
{ detail?: string; detailVariants?: string[] } {
|
|
79
|
+
const at = spotAsOf ? Date.parse(spotAsOf) : Number.NaN;
|
|
80
|
+
if (spot == null || !Number.isFinite(at)) return {};
|
|
81
|
+
const observed = observedModelSpot(spot, at);
|
|
82
|
+
const stamp = modelSpotStamp(observed);
|
|
83
|
+
return stamp ? { detail: stamp, detailVariants: [...modelSpotStampVariants(observed), ""] } : {};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The spot as a report says it: `770.88 pre-market Wed 21 Oct 09:35 UTC`, `770.10 last Wed 21 Oct 14:05 UTC`. */
|
|
87
|
+
export function formatPositioningSpot(spot: number | null | undefined, spotAsOf: string | null | undefined): string {
|
|
88
|
+
const at = spotAsOf ? Date.parse(spotAsOf) : Number.NaN;
|
|
89
|
+
if (spot == null || !Number.isFinite(spot)) return "--";
|
|
90
|
+
return Number.isFinite(at) ? `${formatLevel(spot)} ${modelSpotLabel(observedModelSpot(spot, at))}` : formatLevel(spot);
|
|
91
|
+
}
|
|
92
|
+
|
|
69
93
|
/** Where a level sits against spot: +0.6%. */
|
|
70
94
|
export function formatDistance(level: number | null | undefined, spot: number | null | undefined): string {
|
|
71
95
|
if (level == null || spot == null || !(spot > 0)) return "--";
|