gloomberb 0.18.4 → 0.19.0
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/patches/electrobun@1.18.1.patch +169 -5
- package/src/account/auth-model.ts +7 -3
- package/src/api-client/auth.ts +9 -4
- package/src/api-client/catalysts.ts +2 -1
- package/src/api-client/cot.ts +6 -2
- package/src/api-client/credit-documents.ts +6 -0
- package/src/api-client/data.ts +31 -6
- package/src/api-client/equity-screener.ts +24 -0
- package/src/api-client/fund-facts.ts +45 -4
- package/src/api-client/index.ts +171 -11
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/market-movers.ts +7 -0
- package/src/api-client/members.ts +13 -1
- package/src/api-client/perps.ts +43 -0
- package/src/api-client/request.ts +222 -41
- package/src/api-client/research-activity.ts +6 -12
- package/src/api-client/types.ts +74 -0
- package/src/app/keybindings/index.ts +3 -0
- package/src/app/keybindings/labels.ts +18 -1
- package/src/app/keybindings/resolve.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +9 -5
- package/src/app/runtime/broker-import.ts +42 -27
- package/src/app/runtime/plugin-bindings.ts +73 -56
- package/src/architecture/core-builtin-allowlist.json +1 -1
- package/src/architecture/pane-tabs-allowlist.json +3 -0
- package/src/architecture/ttl-caches-allowlist.json +19 -0
- package/src/brokers/sync-broker-instance.ts +2 -8
- package/src/capabilities/chart-series.ts +1 -1
- package/src/cli/commands/crypto-hints.ts +40 -24
- package/src/cli/commands/fred-series.ts +5 -0
- package/src/cli/commands/keybindings.ts +23 -0
- package/src/cli/commands/market.ts +138 -46
- package/src/cli/commands/options-chain.ts +107 -10
- package/src/cli/commands/options-leaps.ts +9 -3
- package/src/cli/commands/overview.ts +176 -39
- package/src/cli/commands/search.ts +39 -3
- package/src/cli/commands/themes.ts +11 -2
- package/src/cli/commands/ticker.ts +57 -35
- package/src/cli/company-name-hint.ts +41 -0
- package/src/cli/earnings-calendar.ts +1 -1
- package/src/cli/errors.ts +10 -2
- package/src/cli/export-source.ts +29 -1
- package/src/cli/glossary.ts +73 -1
- package/src/cli/history-rows.ts +87 -16
- package/src/cli/index.ts +2 -0
- package/src/cli/known-gaps.ts +5 -2
- package/src/cli/listing-arg.ts +195 -56
- package/src/cli/output-file.ts +68 -0
- package/src/cli/pane-functions/capabilities.ts +3 -0
- package/src/cli/pane-functions/catalog.ts +80 -7
- package/src/cli/pane-functions/dom.ts +13 -3
- package/src/cli/pane-functions/freshness.ts +111 -16
- package/src/cli/pane-functions/function-help.ts +23 -13
- package/src/cli/pane-functions/headless.ts +56 -12
- package/src/cli/pane-functions/index.ts +58 -16
- package/src/cli/pane-functions/market-session.ts +81 -9
- package/src/cli/pane-functions/options.ts +19 -1
- package/src/cli/pane-functions/report.ts +5 -1
- package/src/cli/pane-functions/resolver.ts +35 -8
- package/src/cli/pane-functions/screenshot-assessment.ts +6 -4
- package/src/cli/pane-functions/screenshot-types.ts +5 -0
- package/src/cli/quote-answer.ts +30 -13
- package/src/cli/report-tables.ts +18 -7
- package/src/cli/restore-plugins.ts +13 -1
- package/src/cli/result.ts +57 -5
- package/src/cli/ticker-resolution.ts +3 -2
- package/src/components/chart/composite/composite-chart.tsx +26 -4
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +6 -0
- package/src/components/chart/composite/legend.tsx +45 -7
- package/src/components/chart/composite/levels.ts +2 -0
- package/src/components/chart/composite/panel-gestures.ts +33 -0
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +61 -5
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +24 -13
- package/src/components/chart/composite/scene.ts +46 -7
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- package/src/components/chart/composite/series-cues.ts +14 -0
- package/src/components/chart/composite/text-renderer.ts +9 -2
- package/src/components/chart/composite/tool-catalog.ts +36 -0
- package/src/components/chart/composite/tools.ts +203 -44
- package/src/components/chart/composite/types.ts +4 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +11 -4
- package/src/components/command-bar/assist/inventory.ts +2 -1
- package/src/components/command-bar/commands/direct/index.ts +28 -13
- package/src/components/command-bar/pane-templates/items.ts +3 -2
- package/src/components/command-bar/panel/prompt-binding.ts +0 -8
- package/src/components/command-bar/workflow/alert.ts +1 -1
- package/src/components/command-bar/workflow/collection-actions.ts +3 -3
- package/src/components/layout/header.tsx +26 -40
- package/src/components/layout/pane/footer/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +27 -0
- package/src/components/onboarding/onboarding-frame.tsx +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +4 -1
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +14 -9
- package/src/components/onboarding/wizard-broker-sync.ts +0 -1
- package/src/components/onboarding/wizard-positions.ts +3 -3
- package/src/components/ticker/list-table-view.tsx +4 -1
- package/src/components/ui/choice-dialog.tsx +23 -18
- package/src/components/ui/choice-groups.ts +18 -0
- package/src/components/ui/data-table/opentui/index.tsx +9 -7
- package/src/components/ui/data-table/opentui/model.ts +26 -1
- package/src/components/ui/data-table/types.ts +2 -0
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/list-view.tsx +8 -4
- package/src/components/ui/query-bar-keys.tsx +2 -0
- package/src/components/ui/query-bar.tsx +1 -0
- package/src/components/ui/select-button.tsx +5 -1
- package/src/components/ui/select-field.tsx +1 -0
- package/src/components/ui/table-layout.ts +8 -5
- package/src/core/app-runtime.ts +2 -0
- package/src/core/app-services.ts +2 -2
- package/src/core/state/app/layout.ts +2 -0
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- package/src/data/config/chart-settings.ts +1 -1
- package/src/data/json-ticker-repository.ts +17 -8
- package/src/data/saved-copies.ts +55 -16
- package/src/data/ticker-repository.ts +16 -9
- package/src/data/ticker-writes.ts +81 -0
- package/src/data/ttl-cache.ts +165 -0
- package/src/docs/snapshot.json +427 -216
- package/src/i18n/es.ts +19 -3
- package/src/i18n/ja.ts +19 -3
- package/src/i18n/ko.ts +19 -3
- package/src/i18n/zh-cn.ts +19 -3
- package/src/i18n/zh-tw.ts +19 -3
- package/src/market-data/coordinator/financials.ts +10 -2
- package/src/market-data/coordinator/index.ts +3 -1
- package/src/market-data/coordinator/quotes.ts +4 -2
- package/src/market-data/depositary-pair.ts +2 -2
- package/src/market-data/fund-facts.ts +50 -0
- package/src/market-data/market/change-basis.ts +48 -7
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/format.ts +25 -0
- package/src/market-data/market/freshness.ts +2 -1
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/status.ts +16 -4
- package/src/market-data/options-alternatives.ts +141 -4
- package/src/market-data/quotes/contributions.ts +20 -2
- package/src/market-data/quotes/resolution.ts +3 -0
- package/src/market-data/selectors.ts +3 -0
- package/src/news/aggregator.ts +113 -9
- package/src/news/cloud-session.ts +21 -0
- package/src/news/hooks.ts +1 -0
- package/src/news/news-model.ts +1 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/notification-log.ts +6 -4
- package/src/plugins/builtin/alerts/alert-engine.ts +25 -2
- package/src/plugins/builtin/alerts/alert-log.ts +33 -0
- package/src/plugins/builtin/alerts/calendar-events.ts +57 -6
- package/src/plugins/builtin/alerts/cli-forms.ts +216 -0
- package/src/plugins/builtin/alerts/cli.ts +380 -82
- package/src/plugins/builtin/alerts/command.ts +31 -0
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- package/src/plugins/builtin/alerts/events-pane.tsx +19 -4
- package/src/plugins/builtin/alerts/fired-log.ts +113 -8
- package/src/plugins/builtin/alerts/format.ts +80 -4
- package/src/plugins/builtin/alerts/headless.ts +30 -7
- package/src/plugins/builtin/alerts/history-rows.ts +7 -3
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +135 -22
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +134 -0
- package/src/plugins/builtin/alerts/metric-data.ts +111 -0
- package/src/plugins/builtin/alerts/metric-model.ts +324 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +90 -39
- package/src/plugins/builtin/alerts/quotes.ts +6 -0
- package/src/plugins/builtin/alerts/storage.ts +37 -10
- package/src/plugins/builtin/alerts/types.ts +7 -0
- package/src/plugins/builtin/analytics/index.tsx +2 -1
- package/src/plugins/builtin/analytics/risk-client.ts +16 -5
- package/src/plugins/builtin/analytics/risk-fx.ts +70 -15
- package/src/plugins/builtin/analytics/risk-headless.ts +27 -0
- package/src/plugins/builtin/analytics/risk-model.ts +55 -9
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
- package/src/plugins/builtin/attention/index.tsx +2 -1
- package/src/plugins/builtin/attention/listing.ts +14 -0
- package/src/plugins/builtin/backtest/headless.ts +10 -5
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -3
- package/src/plugins/builtin/broker-manager/index.tsx +10 -5
- package/src/plugins/builtin/broker-manager/model.ts +6 -1
- package/src/plugins/builtin/broker-trading/controller.ts +22 -12
- package/src/plugins/builtin/broker-trading/index.tsx +13 -1
- package/src/plugins/builtin/broker-trading/order-feed.ts +9 -4
- package/src/plugins/builtin/broker-trading/pane.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +12 -4
- package/src/plugins/builtin/buildout/format.ts +38 -0
- package/src/plugins/builtin/buildout/model/normalizers.ts +36 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +4 -1
- package/src/plugins/builtin/buildout/table-model.ts +23 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +7 -3
- package/src/plugins/builtin/catalysts/model.ts +2 -1
- package/src/plugins/builtin/changelog/index.tsx +9 -6
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +6 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +1 -1
- package/src/plugins/builtin/chart-composer/cli-options.ts +9 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +12 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -2
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +7 -5
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +21 -4
- package/src/plugins/builtin/chart-composer/headless.ts +19 -3
- package/src/plugins/builtin/chart-composer/index.tsx +1 -1
- package/src/plugins/builtin/chart-composer/pane.tsx +53 -9
- package/src/plugins/builtin/chart-composer/presets.ts +50 -15
- package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
- package/src/plugins/builtin/chart-composer/session-history.ts +18 -9
- package/src/plugins/builtin/chart-composer/settings.ts +27 -0
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +40 -26
- package/src/plugins/builtin/chat/content/command-suggestions.ts +93 -0
- package/src/plugins/builtin/chat/content/composer.tsx +13 -6
- package/src/plugins/builtin/chat/content/footer.tsx +6 -3
- package/src/plugins/builtin/chat/content/index.tsx +50 -21
- package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
- package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
- package/src/plugins/builtin/chat/index.tsx +23 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
- package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
- package/src/plugins/builtin/chat/pane-links/commands.ts +271 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +8 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
- package/src/plugins/builtin/clinical-trials/model.ts +0 -9
- package/src/plugins/builtin/clinical-trials/pane.tsx +15 -22
- package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +8 -6
- package/src/plugins/builtin/cloud/askg/manifest.ts +2 -0
- package/src/plugins/builtin/cloud/plugin.tsx +1 -1
- package/src/plugins/builtin/company-attention/building.tsx +5 -1
- package/src/plugins/builtin/company-attention/client.ts +8 -9
- package/src/plugins/builtin/company-attention/evidence.ts +4 -1
- package/src/plugins/builtin/company-attention/moves.tsx +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +9 -2
- package/src/plugins/builtin/company-attention/signals.tsx +5 -1
- package/src/plugins/builtin/correlation/headless.ts +13 -5
- package/src/plugins/builtin/correlation/history.ts +22 -0
- package/src/plugins/builtin/cot/client.ts +22 -18
- package/src/plugins/builtin/cot/headless.ts +15 -10
- package/src/plugins/builtin/cot/model.ts +14 -1
- package/src/plugins/builtin/cot/pane.tsx +22 -14
- package/src/plugins/builtin/credit-boards/client.ts +6 -10
- package/src/plugins/builtin/credit-conditions/headless.ts +8 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +5 -1
- package/src/plugins/builtin/credit-conditions/model.ts +4 -0
- package/src/plugins/builtin/credit-conditions/series.ts +3 -1
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -2
- package/src/plugins/builtin/credit-documents/export.ts +173 -0
- package/src/plugins/builtin/credit-documents/headless.ts +7 -7
- package/src/plugins/builtin/credit-documents/model.ts +104 -14
- package/src/plugins/builtin/credit-documents/pane.tsx +12 -5
- package/src/plugins/builtin/custom-view/sources.ts +2 -0
- package/src/plugins/builtin/dividend-yield/client.ts +131 -23
- package/src/plugins/builtin/dividend-yield/headless.ts +44 -16
- package/src/plugins/builtin/dividend-yield/model.ts +8 -5
- package/src/plugins/builtin/dividend-yield/pane.tsx +38 -13
- package/src/plugins/builtin/dividend-yield/ranking.ts +37 -14
- package/src/plugins/builtin/dividend-yield/types.ts +20 -2
- package/src/plugins/builtin/dividend-yield/view.ts +30 -2
- package/src/plugins/builtin/docs/targets.ts +5 -1
- package/src/plugins/builtin/earnings/board-model.ts +16 -15
- package/src/plugins/builtin/earnings/board.tsx +62 -71
- package/src/plugins/builtin/earnings/headless.ts +40 -4
- package/src/plugins/builtin/earnings/scope.ts +31 -43
- package/src/plugins/builtin/earnings-calls/calendar.tsx +2 -2
- package/src/plugins/builtin/earnings-calls/format.ts +31 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +7 -2
- package/src/plugins/builtin/earnings-calls/model.ts +6 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +5 -4
- package/src/plugins/builtin/econ/calendar-model.ts +14 -9
- package/src/plugins/builtin/econ/figures.ts +72 -0
- package/src/plugins/builtin/econ/index.tsx +33 -3
- package/src/plugins/builtin/econ/types.ts +4 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +6 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +85 -35
- package/src/plugins/builtin/econ-statistics/stats.ts +37 -9
- package/src/plugins/builtin/econ-statistics/view.ts +3 -0
- package/src/plugins/builtin/equity-screener/categories.ts +179 -0
- package/src/plugins/builtin/equity-screener/client.ts +4 -2
- package/src/plugins/builtin/equity-screener/headless.ts +144 -13
- package/src/plugins/builtin/equity-screener/ideas.ts +49 -0
- package/src/plugins/builtin/equity-screener/model.ts +99 -10
- package/src/plugins/builtin/equity-screener/pane.tsx +70 -15
- package/src/plugins/builtin/exposure/charts.tsx +2 -2
- package/src/plugins/builtin/exposure/model.ts +13 -1
- package/src/plugins/builtin/exposure/pane.tsx +4 -4
- package/src/plugins/builtin/fixed-income/pane.tsx +2 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +2 -1
- package/src/plugins/builtin/futures/table.tsx +2 -2
- package/src/plugins/builtin/futures/use-board-terms.ts +42 -28
- package/src/plugins/builtin/futures/use-front-returns.ts +45 -28
- package/src/plugins/builtin/fx-matrix/client.ts +11 -3
- package/src/plugins/builtin/fx-matrix/headless.ts +6 -3
- package/src/plugins/builtin/fx-matrix/index.tsx +16 -4
- package/src/plugins/builtin/fx-matrix/live-legs.ts +54 -3
- package/src/plugins/builtin/gpu/headless.ts +8 -2
- package/src/plugins/builtin/help/function-index.ts +4 -1
- package/src/plugins/builtin/help/index.tsx +1 -0
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- package/src/plugins/builtin/help/shortcut-model.ts +1 -1
- package/src/plugins/builtin/holders/fund-holders.ts +51 -0
- package/src/plugins/builtin/holders/headless.ts +18 -1
- package/src/plugins/builtin/iv-history/client.ts +52 -11
- package/src/plugins/builtin/iv-history/format.ts +36 -23
- package/src/plugins/builtin/iv-history/headless.ts +36 -18
- package/src/plugins/builtin/iv-history/index.tsx +2 -2
- package/src/plugins/builtin/iv-history/model.ts +163 -27
- package/src/plugins/builtin/iv-history/pane.tsx +10 -6
- package/src/plugins/builtin/iv-history/screen-pane.tsx +22 -15
- package/src/plugins/builtin/iv-history/universe.ts +5 -1
- package/src/plugins/builtin/jobs/client.ts +25 -29
- package/src/plugins/builtin/kelly-sizer/model.ts +12 -8
- package/src/plugins/builtin/kelly-sizer/pane.tsx +9 -9
- package/src/plugins/builtin/kelly-sizer/sections.tsx +19 -10
- package/src/plugins/builtin/kelly-sizer/types.ts +10 -4
- package/src/plugins/builtin/macro-day/pane.tsx +7 -5
- package/src/plugins/builtin/macro-day/release-table.ts +2 -2
- package/src/plugins/builtin/market-heatmap/data.ts +8 -33
- package/src/plugins/builtin/market-movers/client.ts +25 -7
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- package/src/plugins/builtin/market-movers/headless.ts +32 -12
- package/src/plugins/builtin/market-movers/index.tsx +26 -14
- package/src/plugins/builtin/market-movers/min-float.ts +74 -0
- package/src/plugins/builtin/market-movers/model.ts +4 -1
- package/src/plugins/builtin/market-movers/screener.ts +14 -0
- package/src/plugins/builtin/market-movers/session-body.tsx +13 -8
- package/src/plugins/builtin/market-movers/session-table.ts +4 -3
- package/src/plugins/builtin/market-movers/table.ts +17 -5
- package/src/plugins/builtin/members/breadth-pane.tsx +82 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +20 -7
- package/src/plugins/builtin/members/index.tsx +9 -9
- package/src/plugins/builtin/members/model.ts +23 -4
- package/src/plugins/builtin/members/pane.tsx +25 -15
- package/src/plugins/builtin/news/index.tsx +1 -0
- package/src/plugins/builtin/news/wire/categories.ts +19 -3
- package/src/plugins/builtin/news/wire/industry-pane.tsx +1 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +31 -5
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +6 -1
- package/src/plugins/builtin/news/wire/news/table.tsx +2 -2
- package/src/plugins/builtin/openfda/client.ts +14 -2
- package/src/plugins/builtin/openfda/index.tsx +3 -2
- package/src/plugins/builtin/openfda/model.ts +9 -0
- package/src/plugins/builtin/openfda/pane.tsx +42 -6
- package/src/plugins/builtin/options/analytics.ts +54 -6
- package/src/plugins/builtin/options/enrichment.ts +17 -5
- package/src/plugins/builtin/options/model-spot.ts +5 -2
- package/src/plugins/builtin/options/strike-window.ts +2 -1
- package/src/plugins/builtin/options/table.ts +6 -9
- package/src/plugins/builtin/options/types.ts +2 -0
- package/src/plugins/builtin/options/view.tsx +42 -12
- package/src/plugins/builtin/options-positioning/client.ts +30 -0
- package/src/plugins/builtin/options-positioning/headless.ts +74 -21
- package/src/plugins/builtin/options-positioning/index.tsx +4 -4
- package/src/plugins/builtin/options-positioning/model.ts +122 -14
- package/src/plugins/builtin/options-positioning/pane.tsx +87 -42
- package/src/plugins/builtin/options-scenario/client.ts +116 -47
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +142 -10
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +206 -55
- package/src/plugins/builtin/options-scenario/csp-screen.ts +63 -23
- package/src/plugins/builtin/options-scenario/csp.ts +8 -2
- package/src/plugins/builtin/options-scenario/index.tsx +9 -7
- package/src/plugins/builtin/options-scenario/strategy-screen.ts +532 -0
- package/src/plugins/builtin/pe-band/model.ts +12 -49
- package/src/plugins/builtin/perps/cascade-tabs.tsx +161 -0
- package/src/plugins/builtin/perps/cascade.ts +236 -0
- package/src/plugins/builtin/perps/client.ts +56 -2
- package/src/plugins/builtin/perps/freshness.ts +12 -10
- package/src/plugins/builtin/perps/headless.ts +65 -9
- package/src/plugins/builtin/perps/index.tsx +7 -5
- package/src/plugins/builtin/perps/live-rows.ts +10 -3
- package/src/plugins/builtin/perps/model.ts +18 -4
- package/src/plugins/builtin/perps/pane.tsx +32 -31
- package/src/plugins/builtin/perps/status-line.ts +25 -0
- package/src/plugins/builtin/plugin-module.ts +5 -1
- package/src/plugins/builtin/portfolio-list/cached-account.ts +3 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +2 -8
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +4 -4
- package/src/plugins/builtin/portfolio-list/cli/render.ts +12 -7
- package/src/plugins/builtin/portfolio-list/headless.ts +1 -1
- package/src/plugins/builtin/portfolio-list/pane/futures-front.ts +40 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +4 -1
- package/src/plugins/builtin/portfolio-list/pane/streaming.ts +5 -2
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +3 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +3 -1
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
- package/src/plugins/builtin/portfolio-list/table.tsx +11 -3
- package/src/plugins/builtin/primary-dealers/client.ts +13 -38
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- package/src/plugins/builtin/realized-vol/index.tsx +2 -2
- package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
- package/src/plugins/builtin/relative-rotation/client.ts +18 -4
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +2 -1
- package/src/plugins/builtin/relative-rotation/model.ts +16 -40
- package/src/plugins/builtin/relative-rotation/pane.tsx +3 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +3 -2
- package/src/plugins/builtin/research/event-model.ts +10 -8
- package/src/plugins/builtin/research/headless.ts +1 -1
- package/src/plugins/builtin/research/relative-valuation-headless.ts +5 -1
- package/src/plugins/builtin/research/relative-valuation-model.ts +31 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +11 -9
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -3
- package/src/plugins/builtin/reverse-dcf/model.ts +61 -6
- package/src/plugins/builtin/reverse-dcf/pane.tsx +7 -4
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/flow-model.ts +50 -4
- package/src/plugins/builtin/scanner/flow-pane.tsx +367 -65
- package/src/plugins/builtin/scanner/flow-session.ts +146 -0
- package/src/plugins/builtin/scanner/headless.ts +204 -35
- package/src/plugins/builtin/scanner/index.ts +40 -6
- package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
- package/src/plugins/builtin/scanner/live-feed.ts +168 -0
- package/src/plugins/builtin/scanner/live-headless.ts +138 -0
- package/src/plugins/builtin/scanner/live-model.ts +362 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
- package/src/plugins/builtin/scanner/live-track.ts +186 -0
- package/src/plugins/builtin/scanner/lock-note.ts +3 -2
- package/src/plugins/builtin/seasonality/headless.ts +10 -1
- package/src/plugins/builtin/sec/fund-facts-view.tsx +5 -2
- package/src/plugins/builtin/sec/fund-facts.ts +116 -34
- package/src/plugins/builtin/sec/headless.ts +2 -1
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +3 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +4 -3
- package/src/plugins/builtin/shared/earnings-calendar.ts +6 -2
- package/src/plugins/builtin/shared/earnings-report.ts +2 -2
- package/src/plugins/builtin/shared/job-posting.ts +1 -0
- package/src/plugins/builtin/shared/macro-releases.ts +65 -0
- package/src/plugins/builtin/shared/members-menu.tsx +3 -2
- package/src/plugins/builtin/shared/pro-lock-note.ts +12 -12
- package/src/plugins/builtin/shared/report-freshness.ts +3 -2
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/ticker-choice.tsx +2 -1
- package/src/plugins/builtin/shared/ticker-company.ts +77 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +10 -3
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -8
- package/src/plugins/builtin/shared/volatility/pricing.ts +26 -1
- package/src/plugins/builtin/shared/wall-view-lifecycle.ts +3 -1
- package/src/plugins/builtin/themes/headless.ts +6 -4
- package/src/plugins/builtin/themes/model.ts +17 -8
- package/src/plugins/builtin/themes/pane.tsx +7 -7
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +43 -18
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +3 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +62 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +83 -46
- package/src/plugins/builtin/ticker-detail/headless.ts +31 -16
- package/src/plugins/builtin/ticker-detail/overview/model.ts +1 -1
- package/src/plugins/builtin/ticker-detail/pane.tsx +3 -2
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +6 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/settings.ts +1 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -19
- package/src/plugins/builtin/treasury-daily/client.ts +41 -5
- package/src/plugins/builtin/treasury-daily/headless.ts +2 -2
- package/src/plugins/builtin/treasury-daily/index.tsx +1 -1
- package/src/plugins/builtin/treasury-daily/model.ts +50 -3
- package/src/plugins/builtin/treasury-daily/pane.tsx +81 -2
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +9 -17
- package/src/plugins/builtin/vol-surface/headless.ts +63 -14
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +22 -7
- package/src/plugins/builtin/vol-surface/pane.tsx +48 -9
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -2
- package/src/plugins/builtin/volatility/pane.tsx +4 -4
- package/src/plugins/builtin/volatility/series.ts +26 -0
- package/src/plugins/builtin/world-indices/footer.ts +1 -1
- package/src/plugins/builtin/world-venue-map/headless.ts +3 -3
- package/src/plugins/catalog-browser.ts +13 -8
- package/src/plugins/catalog-manifest.ts +2 -1
- package/src/plugins/marketplace/model.ts +18 -5
- package/src/portfolio/column-values.ts +5 -5
- package/src/portfolio/futures-positions.ts +6 -3
- package/src/portfolio/position-quantity.ts +15 -9
- package/src/public/__snapshots__/public-api.test.ts.snap +1 -0
- package/src/remote/resources.ts +2 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +2 -55
- package/src/renderers/browser/main.tsx +7 -57
- package/src/renderers/dom/data-table/row.tsx +26 -0
- package/src/renderers/dom/desktop/list-view.tsx +13 -10
- package/src/renderers/dom/desktop/query-bar.tsx +4 -2
- package/src/renderers/dom/desktop/select-field.tsx +4 -2
- package/src/renderers/dom/host/chart-surface.tsx +21 -0
- package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +29 -7
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +7 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -0
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +173 -5
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +52 -0
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/index.ts +25 -1
- package/src/renderers/electrobun/shared/app-name.ts +30 -0
- package/src/renderers/electrobun/shared/protocol.ts +10 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +6 -0
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
- package/src/renderers/electrobun/view/main.tsx +24 -1
- package/src/renderers/electrobun/view/news-source.ts +3 -1
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +14 -7
- package/src/renderers/electrobun/view/view-ids.ts +85 -0
- package/src/renderers/opentui/start.tsx +5 -0
- package/src/renderers/opentui/toast-host.tsx +71 -43
- package/src/series/registry.ts +1 -0
- package/src/series/types.ts +6 -0
- package/src/series/validate.ts +1 -0
- package/src/sources/gloomberb-cloud/index.ts +1 -0
- package/src/sources/gloomberb-cloud/news.ts +47 -7
- package/src/sources/gloomberb-cloud/normalizers.ts +2 -0
- package/src/sources/provider-router/batches.ts +10 -2
- package/src/sources/provider-router/financial-routes.ts +3 -3
- package/src/sources/provider-router/financials.ts +15 -3
- package/src/sources/provider-router/history.ts +28 -7
- package/src/sources/provider-router/index.ts +149 -10
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/ticker-cleanup.ts +50 -0
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +70 -19
- package/src/sync/core-contributors.ts +90 -31
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/telemetry/stall-reports-dom.ts +38 -0
- package/src/telemetry/stall-reports-node.ts +75 -0
- package/src/telemetry/stall-reports.ts +214 -0
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/preload.ts +14 -0
- package/src/theme/colors.ts +8 -0
- package/src/theme/themes.ts +10 -0
- package/src/tickers/company-name.ts +103 -3
- package/src/tickers/listing-venues.ts +38 -3
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/index.ts +36 -7
- package/src/tickers/search/ranking.ts +10 -1
- package/src/tickers/search/types.ts +5 -0
- package/src/tickers/terminal-codes.ts +19 -0
- package/src/time-series/alignment.ts +1 -1
- package/src/time-series/base-series.ts +13 -5
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +18 -4
- package/src/time-series/field-catalog.ts +2 -4
- package/src/time-series/filed-trailing-eps.ts +197 -0
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +198 -7
- package/src/time-series/hooks.ts +1 -0
- package/src/time-series/ice-credit.ts +3 -0
- package/src/time-series/price-comparison.ts +30 -2
- package/src/time-series/price-units.ts +72 -2
- package/src/time-series/resolve-context.ts +7 -1
- package/src/time-series/resolve.ts +116 -15
- package/src/time-series/series-presentation.ts +40 -6
- package/src/time-series/session-bar.ts +11 -0
- package/src/time-series/spec.ts +5 -3
- package/src/time-series/studies.ts +278 -74
- package/src/time-series/total-return.ts +160 -0
- package/src/time-series/transforms.ts +3 -3
- package/src/time-series/types.ts +27 -1
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/data-provider.ts +9 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/financials.ts +73 -2
- package/src/types/headless.ts +61 -5
- package/src/types/instrument.ts +3 -0
- package/src/types/news-source.ts +1 -0
- package/src/types/plugin.ts +10 -1
- package/src/ui/host.tsx +3 -0
- package/src/updater/command-names.ts +12 -7
- package/src/updater/failure.ts +4 -1
- package/src/utils/cli-output.ts +42 -1
- package/src/utils/crypto-pair.ts +44 -0
- package/src/utils/financial-statements.ts +6 -1
- package/src/utils/forward-dividend.ts +2 -0
- package/src/utils/fundamentals.ts +24 -3
- package/src/utils/fx-market-hours.ts +26 -3
- package/src/utils/main-thread-stall.ts +35 -2
- package/src/utils/market-capitalization.ts +24 -1
- package/src/utils/network-failure.ts +9 -6
- package/src/utils/option-expiry.ts +48 -1
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-history.ts +12 -1
- package/src/utils/shell-word.ts +8 -0
- package/src/utils/trailing-dividend.ts +53 -4
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +0 -17
- package/src/renderers/browser/first-screen.ts +0 -193
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import type { HeadlessPaneDefinition, HeadlessPaneEntry } from "../../../types/plugin";
|
|
2
|
+
import { formatStrikeLabel } from "../../../utils/options";
|
|
2
3
|
import { expirationOptionSeconds, expiryIsoDate, OPTION_EXPIRATION_FORMAT, OPTION_EXPIRATION_PLACEHOLDER } from "../../../utils/option-expiry";
|
|
3
4
|
import { formatUtcTime } from "../../../utils/utc-time";
|
|
4
5
|
import { loadGamma, loadOpenInterest, positioningSymbol, type GammaPayload, type OpenInterestPayload } from "./client";
|
|
5
6
|
import { listingFateReport, loadListingFate } from "../../../tickers/listing-fate";
|
|
6
7
|
import { resolveHeadlessInstrument } from "../shared/headless-market-data";
|
|
8
|
+
import { coinOptionsAlias, coinWithoutOptionsRefusal } from "../../../market-data/options-alternatives";
|
|
7
9
|
import {
|
|
8
10
|
ALL_EXPIRIES,
|
|
9
11
|
expiryLabel,
|
|
12
|
+
expiryWithTimeLabel,
|
|
13
|
+
formatContracts,
|
|
14
|
+
isCoinContract,
|
|
15
|
+
settlementTime,
|
|
16
|
+
wallsByExpiry,
|
|
10
17
|
formatCount,
|
|
11
18
|
formatCountChange,
|
|
12
19
|
formatDistance,
|
|
13
20
|
formatGamma,
|
|
21
|
+
formatGammaTimes,
|
|
14
22
|
formatLevel,
|
|
15
23
|
formatPositioningSpot,
|
|
16
24
|
formatPayout,
|
|
17
25
|
formatRatio,
|
|
18
|
-
formatStrike,
|
|
19
26
|
GAMMA_UNIT,
|
|
20
27
|
gammaWalls,
|
|
21
28
|
netGammaByExpiry,
|
|
@@ -25,8 +32,9 @@ import {
|
|
|
25
32
|
|
|
26
33
|
const METHODOLOGY = "https://gloom.sh/docs/options-positioning";
|
|
27
34
|
const UNIT_TEXT = "$ of dealer delta per 1% move";
|
|
28
|
-
const strike = (value: unknown) => typeof value === "number" ?
|
|
35
|
+
const strike = (value: unknown) => typeof value === "number" ? formatStrikeLabel(value) : "--";
|
|
29
36
|
const count = (value: unknown) => formatCount(typeof value === "number" ? value : null);
|
|
37
|
+
const coinCount = (value: unknown) => formatContracts(typeof value === "number" ? value : null, true);
|
|
30
38
|
const change = (value: unknown) => formatCountChange(typeof value === "number" ? value : null);
|
|
31
39
|
const gamma = (value: unknown) => formatGamma(typeof value === "number" ? value : null);
|
|
32
40
|
const failure = (error: unknown) => error instanceof Error ? error : new Error(String(error));
|
|
@@ -34,27 +42,47 @@ const time = (value: string | null) => value ? formatUtcTime(value) : "--";
|
|
|
34
42
|
const level = (value: number | null, spot: number | null, none = "--") =>
|
|
35
43
|
value == null ? none : `${formatLevel(value)}, ${formatDistance(value, spot)} vs spot`;
|
|
36
44
|
const wall = (value: number | null, spot: number | null) =>
|
|
37
|
-
value == null ? "--" : `${
|
|
45
|
+
value == null ? "--" : `${formatStrikeLabel(value)}, ${formatDistance(value, spot)} vs spot`;
|
|
38
46
|
|
|
39
47
|
/**
|
|
40
|
-
* What the report opens with: spot
|
|
41
|
-
*
|
|
42
|
-
*
|
|
48
|
+
* What the report opens with: spot, the instant gamma is evaluated at and
|
|
49
|
+
* when the quotes behind its volatilities were taken, apart from the open
|
|
50
|
+
* interest session, then the figures the GEX tab shows. Exports keep each
|
|
51
|
+
* figure whole; the text says them as the pane does.
|
|
43
52
|
*/
|
|
44
53
|
function summary(openInterest: OpenInterestPayload, dealer: GammaPayload | null): { entries: HeadlessPaneEntry[]; textEntries: HeadlessPaneEntry[] } {
|
|
45
54
|
// Gamma is priced at its own read of spot; the figures and their distances use that one.
|
|
46
55
|
const spot = dealer?.spot ?? openInterest.spot;
|
|
47
56
|
const spotAsOf = dealer ? dealer.spotAsOf : openInterest.spotAsOf;
|
|
57
|
+
const spotBasis = dealer ? dealer.spotBasis : openInterest.spotBasis;
|
|
58
|
+
const venue = openInterest.venue;
|
|
59
|
+
// Older servers send no gamma time: their quote time stands alone, as it did.
|
|
60
|
+
const gammaTimes = dealer ? formatGammaTimes(dealer.gammaAsOf, dealer.quotesAsOf) : null;
|
|
61
|
+
// A venue that publishes open interest live (Deribit) dates it to the read, not to a session.
|
|
62
|
+
const oiAsOf = venue && openInterest.oiAsOf ? openInterest.oiAsOf : null;
|
|
63
|
+
const contract = openInterest.contract;
|
|
64
|
+
const settles = settlementTime(openInterest.expiries[0]?.expiresAt);
|
|
48
65
|
const entries: HeadlessPaneEntry[] = [
|
|
66
|
+
...(venue ? [{ key: "venue", label: "Venue", value: venue }] : []),
|
|
49
67
|
{ key: "spot", label: "Spot", value: spot },
|
|
50
68
|
{ key: "spotAsOf", label: "Spot as of", value: spotAsOf },
|
|
51
|
-
|
|
52
|
-
{ key: "
|
|
69
|
+
// An index outside its session: spot is the close, spotAsOf its time.
|
|
70
|
+
...(spotBasis ? [{ key: "spotBasis", label: "Spot basis", value: spotBasis }] : []),
|
|
71
|
+
...(dealer && gammaTimes ? [{ key: "gammaAsOf", label: "Gamma at", value: dealer.gammaAsOf ?? null },
|
|
72
|
+
{ key: "quotesAsOf", label: "Vols from", value: dealer.quotesAsOf }]
|
|
73
|
+
: dealer ? [{ key: "quotesAsOf", label: "Quotes as of", value: dealer.quotesAsOf }] : []),
|
|
74
|
+
{ key: "oiDate", label: "Open interest as of", value: oiAsOf ?? openInterest.oiDate },
|
|
75
|
+
...(contract ? [{ key: "contract", label: "Contract", value: contract }] : []),
|
|
76
|
+
...(settles ? [{ key: "settles", label: "Expiries settle", value: settles }] : []),
|
|
53
77
|
];
|
|
54
78
|
const textEntries: HeadlessPaneEntry[] = [
|
|
55
|
-
{ label: "
|
|
56
|
-
|
|
57
|
-
{ label: "
|
|
79
|
+
...(venue ? [{ label: "Venue", value: venue }] : []),
|
|
80
|
+
{ label: "Spot", value: spot, formatted: formatPositioningSpot(spot, spotAsOf, venue, spotBasis) },
|
|
81
|
+
...(dealer && gammaTimes ? [{ label: "Gamma at", value: dealer.gammaAsOf ?? null, formatted: gammaTimes }]
|
|
82
|
+
: dealer ? [{ label: "Quotes as of", value: dealer.quotesAsOf, formatted: time(dealer.quotesAsOf) }] : []),
|
|
83
|
+
{ label: "Open interest as of", value: oiAsOf ?? openInterest.oiDate, formatted: oiAsOf ? `${time(oiAsOf)}, live` : openInterest.oiDate ?? "--" },
|
|
84
|
+
...(contract ? [{ label: "Contract", value: contract, formatted: `${contract.size} ${contract.unit}; OI counts ${contract.unit}` }] : []),
|
|
85
|
+
...(settles ? [{ label: "Expiries settle", value: settles, formatted: `${settles}, the day each expiry names` }] : []),
|
|
58
86
|
];
|
|
59
87
|
if (!dealer?.total) return { entries, textEntries };
|
|
60
88
|
const { callWall, putWall } = gammaWalls(dealer.strikes);
|
|
@@ -86,8 +114,10 @@ function summary(openInterest: OpenInterestPayload, dealer: GammaPayload | null)
|
|
|
86
114
|
export const optionsPositioningHeadless = (initialTab: PositioningTab): HeadlessPaneDefinition<"bundle"> => ({
|
|
87
115
|
shape: "bundle",
|
|
88
116
|
freshness: { status: "not-a-feed", basis: "daily open interest", cadence: "daily" },
|
|
89
|
-
argument: { kind: "ticker", optional: true, description: "US option underlying, or SPX; SPY when omitted" },
|
|
117
|
+
argument: { kind: "ticker", optional: true, description: "US option underlying, BTC-USD or ETH-USD, or SPX; SPY when omitted" },
|
|
90
118
|
usListingsOnly: "Options data",
|
|
119
|
+
symbolAlias: coinOptionsAlias(initialTab === "gex" ? "GEX" : "OPX"),
|
|
120
|
+
refuseSymbol: coinWithoutOptionsRefusal(initialTab === "gex" ? "GEX" : "OPX"),
|
|
91
121
|
describe: (args) => `${initialTab === "gex" ? "GEX" : "OPX"} ${args.symbols[0] ?? "SPY"}`,
|
|
92
122
|
discovery: {
|
|
93
123
|
aliases: initialTab === "gex" ? ["GEX"] : ["OPX", "MAXPAIN"],
|
|
@@ -97,6 +127,7 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
97
127
|
"Open interest is about two sessions old; the Expiries heading names its date.",
|
|
98
128
|
"Dealer gamma assumes dealers are long every call and short every put.",
|
|
99
129
|
"NDX and RUT index options are not covered; use QQQ and IWM.",
|
|
130
|
+
"BTC-USD and ETH-USD are Deribit's options: open interest is live and counted in coins, and expiries settle at 08:00 UTC.",
|
|
100
131
|
],
|
|
101
132
|
},
|
|
102
133
|
options: [
|
|
@@ -135,34 +166,52 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
135
166
|
: listingFateReport(await loadListingFate(await resolveHeadlessInstrument(ctx, symbol), ctx.marketData), { served: false }, loadErrors);
|
|
136
167
|
const errors = fate?.errors ?? loadErrors;
|
|
137
168
|
const changes = openInterest.previousOiDate != null;
|
|
169
|
+
const coin = isCoinContract(openInterest.contract);
|
|
170
|
+
const contracts = coin ? coinCount : count;
|
|
171
|
+
const unit = coin ? ` (${openInterest.contract!.unit})` : "";
|
|
172
|
+
// Each expiry's walls, from the all-expiries gamma; absent from older servers.
|
|
173
|
+
const expiryWalls = allExpiries instanceof Error ? null : wallsByExpiry(allExpiries);
|
|
174
|
+
const settles = openInterest.expiries.some((row) => settlementTime(row.expiresAt));
|
|
175
|
+
const oiStamp = openInterest.venue && openInterest.oiAsOf ? `${time(openInterest.oiAsOf)}, live` : openInterest.oiDate ?? "--";
|
|
138
176
|
const gammaShown = dealer instanceof Error || !dealer.total ? null : dealer;
|
|
139
177
|
const scope = dealer instanceof Error ? null : dealer.expiry ? expiryLabel(dealer.expiry) : "all expiries";
|
|
140
178
|
const walls = gammaShown ? gammaWalls(gammaShown.strikes) : null;
|
|
141
179
|
return {
|
|
142
180
|
// Open interest is counted once a day and arrives about two sessions late, dated in the heading and the summary;
|
|
143
181
|
// spot and the quotes have their own times in the summary.
|
|
144
|
-
|
|
182
|
+
// A venue's live book (Deribit's) is a feed: read a minute ago, or held back 15 minutes for delayed access.
|
|
183
|
+
freshness: openInterest.venue && openInterest.oiAsOf
|
|
184
|
+
? { asOf: openInterest.oiAsOf, status: openInterest.delayed ? "delayed" as const : "live" as const,
|
|
185
|
+
...(openInterest.delayed ? { delayMinutes: 15 } : {}) }
|
|
186
|
+
: { asOf: openInterest.oiDate },
|
|
145
187
|
sections: [
|
|
146
188
|
{ title: scope ? `Summary · ${scope}` : "Summary", ...summary(openInterest, dealer instanceof Error ? null : dealer) },
|
|
147
|
-
{ title: `Expiries · OI as of ${
|
|
148
|
-
{ key: "date", header: "Expiry" },
|
|
149
|
-
|
|
189
|
+
{ title: `Expiries · OI as of ${oiStamp}`, columns: [
|
|
190
|
+
{ key: "date", header: "Expiry" },
|
|
191
|
+
// Deribit's expiries settle at 08:00 UTC on the day they name.
|
|
192
|
+
...(settles ? [{ key: "settles", header: "Settles" }] : []),
|
|
193
|
+
{ key: "days", header: "Days" },
|
|
194
|
+
{ key: "callOI", header: `Call OI${unit}`, format: contracts }, { key: "putOI", header: `Put OI${unit}`, format: contracts },
|
|
150
195
|
{ key: "putCallRatio", header: "P/C", format: (value: unknown) => formatRatio(value as number | null) },
|
|
151
196
|
...(changes ? [{ key: "change", header: "OI chg", format: change }] : []),
|
|
152
197
|
{ key: "maxPain", header: "Max pain", format: strike },
|
|
153
198
|
{ key: "distance", header: "Vs spot" },
|
|
199
|
+
...(expiryWalls ? [{ key: "callWall", header: "Call wall", format: strike }, { key: "putWall", header: "Put wall", format: strike }] : []),
|
|
154
200
|
...(gammaColumn ? [{ key: "netGamma", header: "Net GEX $", format: gamma, unitKey: "netGammaUnit" }] : []),
|
|
155
201
|
], rows: openInterest.expiries.map((row) => ({
|
|
156
202
|
...row,
|
|
203
|
+
...(settles ? { settles: settlementTime(row.expiresAt) } : {}),
|
|
157
204
|
change: row.callChange == null ? null : row.callChange + (row.putChange ?? 0),
|
|
158
205
|
distance: formatDistance(row.maxPain, spot),
|
|
206
|
+
...(expiryWalls ? { callWall: expiryWalls.get(row.date)?.callWall ?? null, putWall: expiryWalls.get(row.date)?.putWall ?? null } : {}),
|
|
159
207
|
...(gammaColumn ? { netGamma: expiryGamma?.get(row.date) ?? null, netGammaUnit: GAMMA_UNIT } : {}),
|
|
160
208
|
})) },
|
|
161
|
-
{ title: `Strikes · ${openInterest.expiry
|
|
209
|
+
{ title: `Strikes · ${openInterest.expiry
|
|
210
|
+
? expiryWithTimeLabel(openInterest.expiries.find((row) => row.date === openInterest.expiry) ?? { date: openInterest.expiry }) : "--"}`, columns: [
|
|
162
211
|
{ key: "strike", header: "Strike", format: strike },
|
|
163
|
-
{ key: "callOI", header:
|
|
212
|
+
{ key: "callOI", header: `Call OI${unit}`, format: contracts },
|
|
164
213
|
...(changes ? [{ key: "callChange", header: "Call chg", format: change }] : []),
|
|
165
|
-
{ key: "putOI", header:
|
|
214
|
+
{ key: "putOI", header: `Put OI${unit}`, format: contracts },
|
|
166
215
|
...(changes ? [{ key: "putChange", header: "Put chg", format: change }] : []),
|
|
167
216
|
{ key: "payout", header: "Payout $", format: (value: unknown) => formatPayout(value as number | null) },
|
|
168
217
|
], rows: openInterest.strikes.map((row) => ({ ...row })) },
|
|
@@ -188,12 +237,16 @@ export const optionsPositioningHeadless = (initialTab: PositioningTab): Headless
|
|
|
188
237
|
previousOiDate: openInterest.previousOiDate,
|
|
189
238
|
spot,
|
|
190
239
|
spotAsOf: openInterest.spotAsOf,
|
|
240
|
+
...(openInterest.spotBasis ? { spotBasis: openInterest.spotBasis } : {}),
|
|
191
241
|
delayed: openInterest.delayed,
|
|
242
|
+
...(openInterest.venue ? { venue: openInterest.venue, oiAsOf: openInterest.oiAsOf ?? null, contract: openInterest.contract ?? null } : {}),
|
|
192
243
|
...(dealer instanceof Error ? {} : {
|
|
193
|
-
gamma: { expiry: dealer.expiry ?? ALL_EXPIRIES, spot: dealer.spot, spotAsOf: dealer.spotAsOf,
|
|
244
|
+
gamma: { expiry: dealer.expiry ?? ALL_EXPIRIES, spot: dealer.spot, spotAsOf: dealer.spotAsOf,
|
|
245
|
+
...(dealer.spotBasis ? { spotBasis: dealer.spotBasis } : {}), total: dealer.total, band: dealer.band,
|
|
194
246
|
bandWithBoxes: dealer.bandWithBoxes ?? null, boxes: dealer.boxes ?? [], flip: dealer.flip,
|
|
195
247
|
callWall: walls?.callWall ?? null, putWall: walls?.putWall ?? null,
|
|
196
|
-
unit: "dollars of dealer delta per 1% move", assumption: "dealers long calls, short puts",
|
|
248
|
+
unit: "dollars of dealer delta per 1% move", assumption: "dealers long calls, short puts",
|
|
249
|
+
gammaAsOf: dealer.gammaAsOf ?? null, quotesAsOf: dealer.quotesAsOf },
|
|
197
250
|
}),
|
|
198
251
|
methodology: METHODOLOGY,
|
|
199
252
|
},
|
|
@@ -56,16 +56,16 @@ export const optionsPositioningModule: PluginModule = {
|
|
|
56
56
|
positioningTemplate({
|
|
57
57
|
id: "options-positioning-pane",
|
|
58
58
|
label: "Options Positioning",
|
|
59
|
-
description: "Open interest by strike and expiry, max pain, and dealer gamma (GEX).",
|
|
60
|
-
keywords: ["opx", "open interest", "max pain", "put call", "expiry", "options"],
|
|
59
|
+
description: "Open interest by strike and expiry, max pain, walls and dealer gamma (GEX); BTC-USD and ETH-USD from Deribit.",
|
|
60
|
+
keywords: ["opx", "open interest", "max pain", "put call", "expiry", "options", "deribit", "bitcoin options", "ether options", "crypto options"],
|
|
61
61
|
shortcut: "OPX",
|
|
62
62
|
shortcutAliases: ["MAXPAIN"],
|
|
63
|
-
}, "strikes", "Options open interest by strike and expiry, max pain, and dealer gamma (GEX) for a US underlying."),
|
|
63
|
+
}, "strikes", "Options open interest by strike and expiry, max pain, and dealer gamma (GEX) for a US underlying, or Deribit's BTC-USD and ETH-USD options."),
|
|
64
64
|
positioningTemplate({
|
|
65
65
|
id: "options-positioning-gex",
|
|
66
66
|
label: "Dealer Gamma",
|
|
67
67
|
description: "Net dealer gamma by strike, its total, flip level, call and put walls and the range for the dealer assumption.",
|
|
68
|
-
keywords: ["gex", "gamma", "dealer gamma", "gamma exposure", "gamma flip", "call wall", "put wall"],
|
|
68
|
+
keywords: ["gex", "gamma", "dealer gamma", "gamma exposure", "gamma flip", "zero gamma", "gamma level", "call wall", "put wall", "0dte"],
|
|
69
69
|
shortcut: "GEX",
|
|
70
70
|
}, "gex"),
|
|
71
71
|
],
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { formatCompact, formatCompactAmount } from "../../../utils/format";
|
|
2
|
-
import { formatExpDate } from "../../../utils/options";
|
|
3
|
-
import {
|
|
2
|
+
import { formatExpDate, formatStrikeLabel } from "../../../utils/options";
|
|
3
|
+
import { formatUtcTime } from "../../../utils/utc-time";
|
|
4
|
+
import {
|
|
5
|
+
formatModelSpotPrice,
|
|
6
|
+
formatSpotTime,
|
|
7
|
+
modelSpotLabel,
|
|
8
|
+
modelSpotStamp,
|
|
9
|
+
modelSpotStampVariants,
|
|
10
|
+
observedModelSpot,
|
|
11
|
+
type OptionModelSpot,
|
|
12
|
+
} from "../options/model-spot";
|
|
4
13
|
|
|
5
14
|
export type PositioningTab = "strikes" | "expiries" | "gex";
|
|
6
15
|
export const POSITIONING_TABS: { value: PositioningTab; label: string }[] = [
|
|
@@ -46,13 +55,44 @@ export function netGammaByExpiry(
|
|
|
46
55
|
return new Map(payload.byExpiry.map((row) => [row.expiry, row.net]));
|
|
47
56
|
}
|
|
48
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Each expiry's call and put walls, from an all-expiries gamma answer: the
|
|
60
|
+
* strikes of that expiry with the most call and put gamma. Null when the
|
|
61
|
+
* answer is for one expiry or the server is older than the fields.
|
|
62
|
+
*/
|
|
63
|
+
export function wallsByExpiry(
|
|
64
|
+
payload: { expiry: string | null; byExpiry?: readonly { expiry: string; callWall?: number | null; putWall?: number | null }[] } | null | undefined,
|
|
65
|
+
): Map<string, { callWall: number | null; putWall: number | null }> | null {
|
|
66
|
+
if (!payload || payload.expiry != null || !payload.byExpiry?.some((row) => "callWall" in row)) return null;
|
|
67
|
+
return new Map(payload.byExpiry.map((row) => [row.expiry, { callWall: row.callWall ?? null, putWall: row.putWall ?? null }]));
|
|
68
|
+
}
|
|
69
|
+
|
|
49
70
|
const dateSeconds = (date: string) => Date.parse(`${date}T00:00:00Z`) / 1000;
|
|
50
71
|
/** Oct 16 '26, as OMON names its expiries. */
|
|
51
72
|
export const expiryLabel = (date: string) => formatExpDate(dateSeconds(date));
|
|
52
73
|
|
|
53
|
-
|
|
54
|
-
|
|
74
|
+
/** `08:00 UTC`: the time an expiry settles, when the venue states one apart from its day (Deribit); null otherwise. */
|
|
75
|
+
export function settlementTime(expiresAt: string | null | undefined): string | null {
|
|
76
|
+
const at = expiresAt ? Date.parse(expiresAt) : Number.NaN;
|
|
77
|
+
if (!Number.isFinite(at) || at % 86_400_000 === 0) return null;
|
|
78
|
+
return `${new Date(at).toISOString().slice(11, 16)} UTC`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** `Oct 30 '26 08:00 UTC` for an expiry with a settlement time, `Oct 30 '26` for one without. */
|
|
82
|
+
export function expiryWithTimeLabel(row: { date: string; expiresAt?: string }): string {
|
|
83
|
+
const time = settlementTime(row.expiresAt);
|
|
84
|
+
return time ? `${expiryLabel(row.date)} ${time}` : expiryLabel(row.date);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Whether open interest counts contracts on a coin (1 BTC each), whose counts run to tenths. */
|
|
88
|
+
export const isCoinContract = (contract: { unit: string } | null | undefined) => !!contract && contract.unit !== "shares";
|
|
89
|
+
|
|
90
|
+
/** A count of contracts: whole for a US listing's, to tenths for a coin's (Deribit's 0.1 BTC step). */
|
|
91
|
+
export function formatContracts(value: number | null | undefined, coin: boolean): string {
|
|
92
|
+
if (!coin) return formatCount(value);
|
|
93
|
+
return value == null || !Number.isFinite(value) ? "--" : value.toLocaleString("en-US", { maximumFractionDigits: 1 });
|
|
55
94
|
}
|
|
95
|
+
|
|
56
96
|
export function formatCount(value: number | null | undefined): string {
|
|
57
97
|
return value == null || !Number.isFinite(value) ? "--" : Math.round(value).toLocaleString("en-US");
|
|
58
98
|
}
|
|
@@ -64,30 +104,95 @@ export function formatCountChange(value: number | null | undefined): string {
|
|
|
64
104
|
export function formatRatio(value: number | null | undefined): string {
|
|
65
105
|
return value == null || !Number.isFinite(value) ? "--" : value.toFixed(2);
|
|
66
106
|
}
|
|
107
|
+
/** A price level (spot, the gamma flip) written as OMON and OVDV write spot. */
|
|
67
108
|
export function formatLevel(value: number | null | undefined): string {
|
|
68
|
-
return value == null || !Number.isFinite(value) ? "--" : value
|
|
109
|
+
return value == null || !Number.isFinite(value) ? "--" : formatModelSpotPrice(value);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The spot of a positioning answer as the options panes stamp theirs: the
|
|
113
|
+
* regular session's close when the server says so (a cash index outside its
|
|
114
|
+
* session, which has no extended hours), otherwise the session its time
|
|
115
|
+
* falls in.
|
|
116
|
+
*/
|
|
117
|
+
function positioningModelSpot(spot: number, at: number, basis?: "close"): OptionModelSpot {
|
|
118
|
+
return basis === "close"
|
|
119
|
+
? { price: spot, observedAt: at, valuationTime: at, basis: "close", session: null }
|
|
120
|
+
: observedModelSpot(spot, at);
|
|
69
121
|
}
|
|
122
|
+
|
|
70
123
|
/**
|
|
71
124
|
* The spot Gloom Cloud read the distances and dealer gamma at, stamped as
|
|
72
125
|
* every options pane stamps its spot (`modelSpotStamp`), as a stat cell
|
|
73
|
-
* carries it: `pre-market Wed 21 Oct 09:35 UTC`,
|
|
74
|
-
*
|
|
75
|
-
* the regular
|
|
126
|
+
* carries it: `pre-market Wed 21 Oct 09:35 UTC`, `close Tue 20 Oct` for an
|
|
127
|
+
* index outside its session, their shorter forms, then none, so the band
|
|
128
|
+
* keeps the columns it has in regular hours. Nothing for the regular
|
|
129
|
+
* session's price.
|
|
76
130
|
*/
|
|
77
|
-
export function positioningSpotDetail(spot: number | null | undefined, spotAsOf: string | null | undefined):
|
|
131
|
+
export function positioningSpotDetail(spot: number | null | undefined, spotAsOf: string | null | undefined, venue?: string, basis?: "close"):
|
|
78
132
|
{ detail?: string; detailVariants?: string[] } {
|
|
79
133
|
const at = spotAsOf ? Date.parse(spotAsOf) : Number.NaN;
|
|
80
134
|
if (spot == null || !Number.isFinite(at)) return {};
|
|
81
|
-
|
|
135
|
+
// A coin trades around the clock: its spot is the venue's index at a time, with no session.
|
|
136
|
+
if (venue) {
|
|
137
|
+
const time = `${new Date(at).toISOString().slice(11, 16)} UTC`;
|
|
138
|
+
return { detail: `index ${time}`, detailVariants: [`index ${time}`, time, ""] };
|
|
139
|
+
}
|
|
140
|
+
const observed = positioningModelSpot(spot, at, basis);
|
|
82
141
|
const stamp = modelSpotStamp(observed);
|
|
83
142
|
return stamp ? { detail: stamp, detailVariants: [...modelSpotStampVariants(observed), ""] } : {};
|
|
84
143
|
}
|
|
85
144
|
|
|
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 {
|
|
145
|
+
/** 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`, `7,722.60 close Tue 27 Oct`. */
|
|
146
|
+
export function formatPositioningSpot(spot: number | null | undefined, spotAsOf: string | null | undefined, venue?: string, basis?: "close"): string {
|
|
88
147
|
const at = spotAsOf ? Date.parse(spotAsOf) : Number.NaN;
|
|
89
148
|
if (spot == null || !Number.isFinite(spot)) return "--";
|
|
90
|
-
return Number.isFinite(at) ? `${formatLevel(spot)} ${
|
|
149
|
+
if (venue) return Number.isFinite(at) ? `${formatLevel(spot)} ${venue} index ${formatUtcTime(new Date(at).toISOString())}` : formatLevel(spot);
|
|
150
|
+
return Number.isFinite(at) ? `${formatLevel(spot)} ${modelSpotLabel(positioningModelSpot(spot, at, basis))}` : formatLevel(spot);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const instant = (value: string | null | undefined) => {
|
|
154
|
+
const at = value ? Date.parse(value) : Number.NaN;
|
|
155
|
+
return Number.isFinite(at) ? at : null;
|
|
156
|
+
};
|
|
157
|
+
/** `Wed 08:34 UTC`. */
|
|
158
|
+
const dayAndTime = (at: number) => formatSpotTime(at).replace(/^(\w{3}) \d{1,2} \w{3} /, "$1 ");
|
|
159
|
+
/** `08:34 UTC`. */
|
|
160
|
+
const timeOnly = (at: number) => `${new Date(at).toISOString().slice(11, 16)} UTC`;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* When dealer gamma is evaluated and when the quotes behind its volatilities
|
|
164
|
+
* were taken, as a report line: `Wed 28 Oct 08:34 UTC, vols from Tue 27 Oct
|
|
165
|
+
* 20:14 UTC`. Before the open that is the pre-market spot's time with the last
|
|
166
|
+
* session's volatilities. Null without a gamma time (an older server, which
|
|
167
|
+
* dates its quotes alone).
|
|
168
|
+
*/
|
|
169
|
+
export function formatGammaTimes(gammaAsOf: string | null | undefined, quotesAsOf: string | null | undefined): string | null {
|
|
170
|
+
const gamma = instant(gammaAsOf);
|
|
171
|
+
if (gamma == null) return null;
|
|
172
|
+
const quotes = instant(quotesAsOf);
|
|
173
|
+
return quotes == null ? formatSpotTime(gamma) : `${formatSpotTime(gamma)}, vols from ${formatSpotTime(quotes)}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The same as a GEX figure: `Gamma at Wed 08:34 UTC`, detail `vols from Tue
|
|
178
|
+
* 20:14 UTC` (the day left out when it is the gamma's), with shorter forms
|
|
179
|
+
* that keep the quote time. An older server's answer, with no gamma time,
|
|
180
|
+
* dates its quotes alone. Null with neither.
|
|
181
|
+
*/
|
|
182
|
+
export function gammaTimesFigure(gammaAsOf: string | null | undefined, quotesAsOf: string | null | undefined):
|
|
183
|
+
{ label: string; value: string; detail?: string; detailVariants?: string[] } | null {
|
|
184
|
+
const gamma = instant(gammaAsOf);
|
|
185
|
+
const quotes = instant(quotesAsOf);
|
|
186
|
+
if (gamma == null) return quotes == null ? null : { label: "Quotes as of", value: dayAndTime(quotes) };
|
|
187
|
+
if (quotes == null) return { label: "Gamma at", value: dayAndTime(gamma) };
|
|
188
|
+
const sameDay = new Date(gamma).toISOString().slice(0, 10) === new Date(quotes).toISOString().slice(0, 10);
|
|
189
|
+
const quoted = sameDay ? timeOnly(quotes) : dayAndTime(quotes);
|
|
190
|
+
return {
|
|
191
|
+
label: "Gamma at",
|
|
192
|
+
value: dayAndTime(gamma),
|
|
193
|
+
detail: `vols from ${quoted}`,
|
|
194
|
+
detailVariants: [`vols from ${quoted}`, `vols ${quoted}`, `vols ${quoted.replace(/ UTC$/, "")}`],
|
|
195
|
+
};
|
|
91
196
|
}
|
|
92
197
|
|
|
93
198
|
/** Where a level sits against spot: +0.6%. */
|
|
@@ -169,6 +274,9 @@ export function chartWindow<T extends { strike: number }>(
|
|
|
169
274
|
/** One full-width numeric domain the chart reads as time; strikes are never labelled as dates. */
|
|
170
275
|
const COORDINATE_SPAN = 1_000_000_000_000;
|
|
171
276
|
|
|
277
|
+
/** Where a chart date made by `toDate` sits across the plot, 0 to 1. */
|
|
278
|
+
export const axisRatioOfDate = (date: Date) => date.getTime() / COORDINATE_SPAN;
|
|
279
|
+
|
|
172
280
|
export interface NumericAxis {
|
|
173
281
|
/** Where x sits across the plot, 0 at the left edge and 1 at the right. */
|
|
174
282
|
ratio: (x: number) => number;
|
|
@@ -200,7 +308,7 @@ export function strikeAxis(strikes: readonly number[]): NumericAxis {
|
|
|
200
308
|
const step = niceStep(span, Math.floor(plotWidth / 8));
|
|
201
309
|
const ticks: Array<{ label: string; ratio: number }> = [];
|
|
202
310
|
for (let value = Math.ceil(min / step) * step; value <= max + 1e-9; value += step) {
|
|
203
|
-
ticks.push({ label:
|
|
311
|
+
ticks.push({ label: formatStrikeLabel(Number(value.toFixed(6))), ratio: ratio(value) });
|
|
204
312
|
}
|
|
205
313
|
return ticks;
|
|
206
314
|
},
|