gloomberb 0.16.4 → 0.16.6
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 +14 -91
- package/package.json +5 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/central-bank-rates.ts +6 -1
- package/src/api-client/chat.ts +26 -0
- package/src/api-client/credit-boards.ts +2 -0
- package/src/api-client/data.ts +73 -3
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/europe-energy.ts +106 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +13 -1
- package/src/api-client/market-discovery.ts +13 -1
- package/src/api-client/normalizers.ts +32 -0
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/perps.ts +8 -0
- package/src/api-client/request.ts +9 -2
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/socket.ts +29 -0
- package/src/api-client/themes.ts +22 -1
- package/src/api-client/types.ts +78 -2
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +50 -2
- package/src/app/keybindings/actions.ts +12 -1
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
- package/src/app/runtime/desktop-deeplink.ts +10 -5
- package/src/app/runtime/startup.ts +1 -1
- package/src/app.tsx +6 -0
- package/src/architecture/core-builtin-allowlist.json +8 -26
- package/src/ask-gloom/pane-context.ts +114 -0
- package/src/ask-gloom/pane-request.ts +70 -0
- package/src/ask-gloom/pane-text.ts +201 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +19 -2
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/central-bank-events.ts +23 -0
- package/src/cli/command-options.ts +17 -5
- package/src/cli/commands/crypto-hints.ts +35 -2
- package/src/cli/commands/fred-series.ts +146 -0
- package/src/cli/commands/market.ts +501 -115
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +132 -26
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +317 -13
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +155 -18
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +76 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +7 -5
- package/src/cli/exit-codes.ts +8 -0
- package/src/cli/export-source.ts +58 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +483 -0
- package/src/cli/help.ts +10 -0
- package/src/cli/helpers.ts +2 -5
- package/src/cli/history-rows.ts +118 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +29 -9
- package/src/cli/known-gaps.ts +84 -0
- package/src/cli/listing-arg.ts +551 -97
- package/src/cli/not-a-ticker.ts +24 -9
- package/src/cli/pane-functions/access-gate.ts +13 -2
- package/src/cli/pane-functions/capabilities.ts +4 -3
- package/src/cli/pane-functions/catalog.ts +214 -40
- package/src/cli/pane-functions/data.ts +42 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +37 -8
- package/src/cli/pane-functions/freshness.ts +393 -49
- package/src/cli/pane-functions/function-help.ts +31 -15
- package/src/cli/pane-functions/headless.ts +98 -30
- package/src/cli/pane-functions/index.ts +101 -19
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +71 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +74 -19
- package/src/cli/pane-functions/screenshot.ts +250 -27
- package/src/cli/perpetual-contract.ts +60 -0
- package/src/cli/registry.ts +3 -1
- package/src/cli/report-tables.ts +26 -7
- package/src/cli/result.ts +45 -11
- package/src/cli/series-search.ts +111 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +27 -0
- package/src/cli/symbol-list.ts +154 -0
- package/src/cli/symbol-rows.ts +154 -0
- package/src/cli/ticker-resolution.ts +311 -27
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +14 -3
- package/src/components/chart/composite/composite-chart.tsx +71 -11
- package/src/components/chart/composite/crosshair-readout.tsx +150 -0
- package/src/components/chart/composite/downsample.ts +1 -1
- package/src/components/chart/composite/format.ts +29 -0
- package/src/components/chart/composite/interactions.ts +9 -2
- package/src/components/chart/composite/legend.tsx +100 -33
- package/src/components/chart/composite/panel-bitmap.ts +70 -35
- package/src/components/chart/composite/panel-labels.ts +18 -17
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +46 -21
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +50 -8
- package/src/components/chart/composite/scene.ts +2 -1
- package/src/components/chart/composite/time-scale.ts +26 -9
- package/src/components/chart/composite/types.ts +18 -0
- package/src/components/chart/composite/use-composite-viewport.ts +30 -2
- package/src/components/chart/native/raster/crosshair.ts +8 -3
- package/src/components/chart/native/raster/primitives.ts +85 -21
- package/src/components/chart/native/surface/manager.ts +33 -8
- package/src/components/chart/surface3d/chart.tsx +1 -1
- package/src/components/command-bar/action-runtime.ts +1 -1
- package/src/components/command-bar/commands/collection-list.ts +210 -0
- package/src/components/command-bar/commands/collection.ts +40 -1
- package/src/components/command-bar/commands/direct/index.ts +4 -0
- package/src/components/command-bar/commands/registry.ts +8 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/routing/actions.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +42 -17
- package/src/components/layout/detached-pane-shell.tsx +68 -39
- package/src/components/layout/floating-pane.tsx +10 -1
- package/src/components/layout/header.tsx +25 -5
- package/src/components/layout/missing-pane.tsx +3 -3
- package/src/components/layout/pane/capture-stamp.ts +41 -0
- package/src/components/layout/pane/capture-status.ts +12 -0
- package/src/components/layout/pane/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/keyboard.ts +3 -0
- package/src/components/layout/pane/footer/model.ts +41 -1
- package/src/components/layout/pane/header.tsx +50 -1
- package/src/components/layout/pane/index.tsx +21 -3
- package/src/components/layout/pane/sidebar.tsx +88 -21
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/cursor-occlusion.ts +2 -1
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +84 -65
- package/src/components/layout/shell/menu.ts +14 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +32 -10
- package/src/components/layout/shell/pane/ask.ts +131 -0
- package/src/components/layout/shell/pane/capture.ts +162 -0
- package/src/components/layout/shell/pane/layers.tsx +218 -50
- package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
- package/src/components/layout/shell/shortcuts.ts +21 -4
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +8 -1
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/reader/article-reader.tsx +642 -0
- package/src/components/reader/article-text.ts +527 -0
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +43 -2
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +18 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +6 -1
- package/src/components/ui/query-bar.tsx +10 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/config/store/portfolio-as-of-column.ts +57 -0
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7555 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +65 -5
- package/src/i18n/ja.ts +65 -5
- package/src/i18n/ko.ts +65 -5
- package/src/i18n/zh-cn.ts +65 -5
- package/src/i18n/zh-tw.ts +65 -5
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/layout-marketplace/gallery.tsx +1 -1
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +84 -20
- package/src/market-data/market/session-close-note.ts +3 -2
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +5 -0
- package/src/market-data/quotes/metadata.ts +19 -24
- package/src/market-data/quotes/resolution.ts +5 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -0
- package/src/notifications/app-notifier.ts +17 -1
- package/src/notifications/notification-log.ts +180 -0
- package/src/plugins/auto-update-node.ts +2 -2
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/catalysts.ts +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/focus.ts +27 -0
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +47 -11
- package/src/plugins/builtin/alerts/pane.tsx +27 -1
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -3
- package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/headless.ts +88 -18
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/model.ts +41 -1
- package/src/plugins/builtin/awards/pane.tsx +22 -13
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/headless.ts +2 -2
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +1 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +49 -12
- package/src/plugins/builtin/cds/headless.ts +119 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +214 -32
- package/src/plugins/builtin/cds/pane.tsx +58 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
- package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
- package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
- package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
- package/src/plugins/builtin/chart-composer/headless.ts +70 -5
- package/src/plugins/builtin/chart-composer/index.tsx +15 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +5 -1
- package/src/plugins/builtin/chat/content/footer.tsx +12 -0
- package/src/plugins/builtin/chat/content/index.tsx +89 -5
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
- package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
- package/src/plugins/builtin/chat/content/scroll.ts +127 -27
- package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
- package/src/plugins/builtin/chat/content/types.ts +1 -0
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/index.ts +123 -1
- package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
- package/src/plugins/builtin/chat/controller/messages.ts +7 -2
- package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
- package/src/plugins/builtin/chat/controller/send.ts +61 -1
- package/src/plugins/builtin/chat/controller/state.ts +8 -0
- package/src/plugins/builtin/chat/ghost-user.ts +20 -0
- package/src/plugins/builtin/chat/index.tsx +23 -5
- package/src/plugins/builtin/chat/layout.ts +78 -5
- package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
- package/src/plugins/builtin/chat/message/header.tsx +16 -4
- package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
- package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
- package/src/plugins/builtin/chat/message/render-state.ts +18 -2
- package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
- package/src/plugins/builtin/chat/message/types.ts +12 -0
- package/src/plugins/builtin/chat/reactions.ts +197 -0
- package/src/plugins/builtin/chat/share/flow.tsx +87 -0
- package/src/plugins/builtin/chat/share/targets.ts +27 -0
- package/src/plugins/builtin/chat/status-widget.tsx +6 -3
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
- package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
- package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
- package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
- package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
- package/src/plugins/builtin/cloud/plugin.tsx +19 -2
- package/src/plugins/builtin/cloud/team/model.ts +5 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/team/store.ts +8 -3
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +21 -7
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/headless.ts +97 -10
- package/src/plugins/builtin/company-kpis/model.ts +24 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +1 -1
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/cpi/headless.ts +3 -3
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
- package/src/plugins/builtin/credit-boards/client.ts +6 -2
- package/src/plugins/builtin/credit-boards/headless.ts +108 -31
- package/src/plugins/builtin/credit-boards/index.tsx +2 -0
- package/src/plugins/builtin/credit-boards/model.ts +11 -1
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-conditions/client.ts +12 -9
- package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
- package/src/plugins/builtin/credit-conditions/model.ts +19 -11
- package/src/plugins/builtin/credit-conditions/series.ts +16 -0
- package/src/plugins/builtin/credit-documents/headless.ts +33 -3
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/client.ts +3 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/dividend-yield/types.ts +2 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/headless.ts +12 -8
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings/index.tsx +9 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/headless.ts +3 -3
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
- package/src/plugins/builtin/exposure/drivers.ts +13 -0
- package/src/plugins/builtin/exposure/headless.ts +205 -13
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/index.tsx +1 -0
- package/src/plugins/builtin/exposure/model.ts +23 -3
- package/src/plugins/builtin/exposure/pane.tsx +14 -12
- package/src/plugins/builtin/fear-greed/index.tsx +18 -10
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +71 -10
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/client.ts +63 -0
- package/src/plugins/builtin/fx-matrix/export.ts +2 -1
- package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +58 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +101 -16
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/function-index.ts +2 -0
- package/src/plugins/builtin/help/index.tsx +31 -9
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +26 -9
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
- package/src/plugins/builtin/iv-history/client.ts +20 -6
- package/src/plugins/builtin/iv-history/format.ts +9 -0
- package/src/plugins/builtin/iv-history/headless.ts +56 -21
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +143 -8
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +26 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
- package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +8 -3
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +6 -8
- package/src/plugins/builtin/mna/distress/headless.ts +4 -4
- package/src/plugins/builtin/mna/headless.ts +18 -6
- package/src/plugins/builtin/money-markets/headless.ts +5 -4
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/index.tsx +0 -2
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
- package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +3 -0
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +4 -3
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +90 -16
- package/src/plugins/builtin/perps/equity-row.tsx +52 -17
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +47 -32
- package/src/plugins/builtin/perps/index.tsx +23 -4
- package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/open-market.ts +15 -0
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
- package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
- package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
- package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
- package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
- package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +63 -10
- package/src/plugins/builtin/power/headless.ts +77 -9
- package/src/plugins/builtin/power/index.tsx +28 -3
- package/src/plugins/builtin/power/model.ts +73 -2
- package/src/plugins/builtin/power/pane.tsx +37 -9
- package/src/plugins/builtin/power/prices-client.ts +139 -0
- package/src/plugins/builtin/power/prices-headless.ts +137 -0
- package/src/plugins/builtin/power/prices-model.ts +103 -0
- package/src/plugins/builtin/power/prices.tsx +179 -0
- package/src/plugins/builtin/rate-path/headless.ts +46 -18
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/research/index.tsx +2 -0
- package/src/plugins/builtin/research-search/article.ts +65 -0
- package/src/plugins/builtin/research-search/document-view.tsx +33 -215
- package/src/plugins/builtin/research-search/model.ts +0 -9
- package/src/plugins/builtin/research-search/pane.tsx +41 -30
- package/src/plugins/builtin/research-search/snippet.ts +0 -29
- package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/headless.ts +25 -3
- package/src/plugins/builtin/sec/index.tsx +2 -1
- package/src/plugins/builtin/series-inventory.ts +93 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/free-preview.ts +47 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +12 -1
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/volatility/options.ts +4 -1
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +2 -1
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/headless.ts +43 -11
- package/src/plugins/builtin/supply-chain/model.ts +13 -0
- package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
- package/src/plugins/builtin/themes/headless.ts +74 -10
- package/src/plugins/builtin/themes/model.ts +71 -4
- package/src/plugins/builtin/themes/pane.tsx +22 -5
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +2 -1
- package/src/plugins/builtin/time-sales/index.tsx +2 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
- package/src/plugins/builtin/vol-surface/headless.ts +51 -17
- package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
- package/src/plugins/builtin/vol-surface/model.ts +39 -6
- package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
- package/src/plugins/builtin/vol-surface/stored.ts +63 -3
- package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
- package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
- package/src/plugins/builtin/world-venue-map/model.ts +56 -19
- package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/installer.ts +2 -2
- package/src/plugins/loader.ts +15 -0
- package/src/plugins/manager-node.ts +1 -1
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
- package/src/plugins/registry/host-actions.ts +11 -0
- package/src/plugins/registry/index.ts +89 -4
- package/src/portfolio/collection-name.ts +31 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/portfolio/valuation-basis.ts +79 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +33 -1
- package/src/react/key-repeat.ts +86 -0
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +144 -7
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +65 -2
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +4 -3
- package/src/renderers/browser/research-entry.ts +4 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +30 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +16 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
- package/src/renderers/dom/host/box.tsx +8 -0
- package/src/renderers/dom/host/chart-surface.tsx +33 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/scroll-box.tsx +32 -0
- package/src/renderers/dom/host/size-observer.ts +41 -0
- package/src/renderers/dom/host/sticky-scroll.ts +128 -0
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/surface-3d.tsx +19 -7
- package/src/renderers/dom/host/surface-fit.ts +406 -0
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +1 -0
- package/src/renderers/dom/styles.css +102 -5
- package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
- package/src/renderers/electrobun/bun/index.ts +3 -2
- package/src/renderers/electrobun/shared/protocol.ts +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +5 -3
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
- package/src/renderers/opentui/chart-surface.tsx +1 -0
- package/src/renderers/opentui/frame-capture.ts +33 -0
- package/src/renderers/opentui/host.tsx +10 -13
- package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
- package/src/renderers/opentui/pane-image/glyphs.json +1 -0
- package/src/renderers/opentui/pane-image/index.ts +107 -0
- package/src/renderers/opentui/pane-image/raster.ts +428 -0
- package/src/renderers/opentui/start.tsx +3 -3
- package/src/renderers/opentui/test-utils.tsx +3 -0
- package/src/renderers/opentui/ui-host.tsx +29 -1
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +108 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +153 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/chat.ts +34 -0
- package/src/shares/dialog.tsx +295 -0
- package/src/shares/flow.tsx +56 -0
- package/src/shares/live.ts +14 -22
- package/src/shares/pane-image.ts +152 -0
- package/src/shares/personal-pane.ts +64 -0
- package/src/shares/portable-layout.ts +4 -2
- package/src/shares/prepare.ts +20 -0
- package/src/sources/gloomberb-cloud/index.ts +109 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
- package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/history-retention.ts +11 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/listing-target.ts +4 -0
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/index.ts +14 -0
- package/src/sources/provider-router/search.ts +1 -0
- package/src/state/hooks/inline-tickers.ts +49 -11
- package/src/sync/core-contributors.ts +1 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/theme-context.tsx +15 -1
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +34 -1
- package/src/tickers/listing-name.ts +34 -0
- package/src/tickers/listing-venues.ts +132 -0
- package/src/tickers/open-target.ts +13 -4
- package/src/tickers/perpetual-listing.ts +151 -0
- package/src/tickers/prediction-listing.ts +26 -0
- package/src/tickers/search/index.ts +72 -11
- package/src/tickers/search/ranking.ts +98 -20
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/ticker-changes.ts +213 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/economic.ts +2 -6
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/ice-credit.ts +39 -0
- package/src/time-series/resolve.ts +211 -29
- package/src/time-series/studies.ts +1 -0
- package/src/time-series/types.ts +12 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +10 -2
- package/src/types/data-provider.ts +11 -0
- package/src/types/financials.ts +62 -1
- package/src/types/headless.ts +113 -0
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +52 -2
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker-changes.ts +26 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/context-menu.tsx +13 -1
- package/src/ui/host.tsx +57 -3
- package/src/ui/live-resize.ts +91 -0
- package/src/ui/live-stretch.ts +153 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/sticky-scroll.ts +7 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/central-banks.ts +76 -0
- package/src/utils/cli-output.ts +131 -15
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/currency-units.ts +11 -0
- package/src/utils/datetime-format.ts +27 -6
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +439 -52
- package/src/utils/double-escape-close.ts +15 -1
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +143 -1
- package/src/utils/format.ts +35 -5
- package/src/utils/forward-dividend.ts +14 -0
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/fx-status.ts +6 -1
- package/src/utils/inline-content-tokenizer.ts +22 -3
- package/src/utils/market-capitalization.ts +8 -0
- package/src/utils/one-shot.ts +73 -0
- package/src/utils/options.ts +37 -8
- package/src/utils/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +63 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PluginModule } from "../plugin-module";
|
|
2
|
+
import { IV_SERIES } from "./series";
|
|
2
3
|
import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface";
|
|
3
4
|
import { ivHistoryHeadless, ivScreenHeadless } from "./headless";
|
|
4
5
|
import { IvHistoryPane } from "./pane";
|
|
@@ -6,6 +7,7 @@ import { IvScreenPane, VCA_SCOPE_OPTIONS } from "./screen-pane";
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
export const ivHistoryModule: PluginModule = {
|
|
10
|
+
series: IV_SERIES,
|
|
9
11
|
panes: [{
|
|
10
12
|
id: "iv-history", name: "Implied Volatility History", icon: "V", component: IvHistoryPane,
|
|
11
13
|
defaultPosition: "right", tickerFollower: true, defaultMode: "floating", defaultFloatingSize: { width: 118, height: 36 },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PricePoint } from "../../../types/financials";
|
|
2
2
|
import { rollingRealizedVolatility } from "../shared/volatility";
|
|
3
|
-
import type { IvHistoryPayload, IvMethod, IvPoint, IvScreenRow, IvStats } from "./client";
|
|
3
|
+
import type { IvCoverageStatus, IvHistoryPayload, IvMethod, IvPoint, IvScreenRow, IvStats } from "./client";
|
|
4
4
|
|
|
5
5
|
export const HV_WINDOWS = [20, 30] as const;
|
|
6
6
|
export type HvWindow = (typeof HV_WINDOWS)[number];
|
|
@@ -26,6 +26,44 @@ export interface IvStatRow {
|
|
|
26
26
|
}
|
|
27
27
|
/** Rank and percentile need this many prior sessions, matching the server. */
|
|
28
28
|
const MIN_RANK_SAMPLES = 120;
|
|
29
|
+
/**
|
|
30
|
+
* Minutes a symbol's first backfill usually takes from the request that
|
|
31
|
+
* queued it: nine in ten have history by then (docs/research-data.md).
|
|
32
|
+
*/
|
|
33
|
+
const FIRST_BACKFILL_MINUTES = 10;
|
|
34
|
+
const FIRST_BACKFILL_TEXT = `a first backfill usually takes under ${FIRST_BACKFILL_MINUTES} minutes`;
|
|
35
|
+
|
|
36
|
+
/** "06:41 UTC" today, with the date on another day: "2026-10-09 06:41 UTC". */
|
|
37
|
+
function utcClock(time: number, now: number): string {
|
|
38
|
+
const iso = new Date(time).toISOString();
|
|
39
|
+
return iso.slice(0, 10) === new Date(now).toISOString().slice(0, 10)
|
|
40
|
+
? `${iso.slice(11, 16)} UTC` : `${iso.slice(0, 16).replace("T", " ")} UTC`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** When a symbol was queued, or null when the answer does not say (older servers) or says a time still to come. */
|
|
44
|
+
function queuedTime(queuedAt: string | null | undefined, now: number): number | null {
|
|
45
|
+
const time = queuedAt ? Date.parse(queuedAt) : Number.NaN;
|
|
46
|
+
return Number.isFinite(time) && time <= now ? time : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* When to look again for history queued at `from`: "a first backfill usually
|
|
51
|
+
* takes under 10 minutes, try again after 06:41 UTC". One queued for longer
|
|
52
|
+
* than that is running late, and says so rather than give a time it cannot
|
|
53
|
+
* know. A view that checks again by itself (`retry: false`) needs no time to
|
|
54
|
+
* come back at.
|
|
55
|
+
*/
|
|
56
|
+
function firstBackfillText(from: number, now: number, retry: boolean): string {
|
|
57
|
+
const retryAt = from + FIRST_BACKFILL_MINUTES * 60_000;
|
|
58
|
+
if (retryAt <= now) return `longer than the usual ${FIRST_BACKFILL_MINUTES} minutes${retry ? ", try again shortly" : ""}`;
|
|
59
|
+
return retry ? `${FIRST_BACKFILL_TEXT}, try again after ${utcClock(retryAt, now)}` : FIRST_BACKFILL_TEXT;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** "queued for backfill since 06:31 UTC; a first backfill usually takes under 10 minutes, try again after 06:41 UTC" */
|
|
63
|
+
function queuedText(queuedAt: string | null | undefined, now: number): string {
|
|
64
|
+
const queued = queuedTime(queuedAt, now);
|
|
65
|
+
return `queued for backfill${queued == null ? "" : ` since ${utcClock(queued, now)}`}; ${firstBackfillText(queued ?? now, now, true)}`;
|
|
66
|
+
}
|
|
29
67
|
export interface IvHistoryModel {
|
|
30
68
|
symbol: string;
|
|
31
69
|
status: IvHistoryPayload["status"];
|
|
@@ -37,6 +75,16 @@ export interface IvHistoryModel {
|
|
|
37
75
|
quoteIv30: DatedValue[];
|
|
38
76
|
hv: DatedValue[];
|
|
39
77
|
spread: DatedValue[];
|
|
78
|
+
/**
|
|
79
|
+
* Each session's 30-day 25-delta put IV minus call IV from its quote
|
|
80
|
+
* capture (put-call: positive means puts are richer). The risk reversal,
|
|
81
|
+
* call minus put, is its negative.
|
|
82
|
+
*/
|
|
83
|
+
skew: DatedValue[];
|
|
84
|
+
/** First session with a stored skew; skew is blank before it. */
|
|
85
|
+
skewSince: string | null;
|
|
86
|
+
/** "skew from 2026-09-23", or why there is no skew at all. */
|
|
87
|
+
skewNote: string | null;
|
|
40
88
|
stats: IvStatRow[];
|
|
41
89
|
since: string | null;
|
|
42
90
|
/** Where the 1Y series starts and how deep it is, when that differs from the rest or leaves it unranked. */
|
|
@@ -86,6 +134,20 @@ function byMethod(series: readonly IvPoint[], method: IvMethod, field: "iv30" |
|
|
|
86
134
|
.sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
87
135
|
}
|
|
88
136
|
|
|
137
|
+
/**
|
|
138
|
+
* 25-delta skew per session, put minus call, from the quote captures: the
|
|
139
|
+
* only readings that store the wings. A server that sends no wing fields at
|
|
140
|
+
* all predates them, which is not the same as a symbol with no capture yet.
|
|
141
|
+
*/
|
|
142
|
+
function skewSeries(series: readonly IvPoint[]): { points: DatedValue[]; note: string | null } {
|
|
143
|
+
const points = series.filter((point) => point.method === "quote-mid" && point.put25_30 != null && point.call25_30 != null)
|
|
144
|
+
.map((point) => ({ date: utc(point.sessionDate), value: point.put25_30! - point.call25_30! }))
|
|
145
|
+
.sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
146
|
+
if (points[0]) return { points, note: `skew from ${day(points[0].date)}` };
|
|
147
|
+
if (!series.length) return { points, note: null };
|
|
148
|
+
return { points, note: series.every((point) => point.put25_30 === undefined) ? "skew unavailable from this server" : "no skew history yet" };
|
|
149
|
+
}
|
|
150
|
+
|
|
89
151
|
/**
|
|
90
152
|
* IV history against realized volatility of the same underlying. HV uses the
|
|
91
153
|
* adjusted daily closes behind HVG; the spread pairs each trade-close IV30
|
|
@@ -93,7 +155,7 @@ function byMethod(series: readonly IvPoint[], method: IvMethod, field: "iv30" |
|
|
|
93
155
|
*/
|
|
94
156
|
export function projectIvHistory(
|
|
95
157
|
payload: IvHistoryPayload, prices: readonly PricePoint[],
|
|
96
|
-
options: { lookback?: IvLookback; hvWindow?: HvWindow } = {},
|
|
158
|
+
options: { lookback?: IvLookback; hvWindow?: HvWindow; now?: number } = {},
|
|
97
159
|
): IvHistoryModel {
|
|
98
160
|
const lookback = options.lookback ?? "1Y";
|
|
99
161
|
const window = options.hvWindow ?? 20;
|
|
@@ -139,12 +201,16 @@ export function projectIvHistory(
|
|
|
139
201
|
seriesStat("spread", `IV 30d - HV ${window}`, "points", spreadAll, "trade-close"),
|
|
140
202
|
seriesStat("term", "IV 30d / 90d", "ratio", termAll, "trade-close"));
|
|
141
203
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
else if (payload.status === "
|
|
204
|
+
// Worded as VCA words each symbol (screenCoverage).
|
|
205
|
+
if (payload.status === "queued") warnings.push(`${payload.symbol} ${queuedText(payload.coverage?.addedAt, options.now ?? Date.now())}.`);
|
|
206
|
+
else if (payload.status === "backfilling") {
|
|
207
|
+
const through = payload.coverage?.backfilledThrough;
|
|
208
|
+
warnings.push(`${payload.symbol} backfilling${through ? ` through ${through}` : ""}.`);
|
|
209
|
+
} else if (payload.status === "unavailable" && !payload.warnings.length) warnings.push(`No options history for ${payload.symbol}.`);
|
|
145
210
|
if (!prices.length) warnings.push("Realized volatility unavailable: daily price history is missing.");
|
|
146
211
|
|
|
147
212
|
const tradeIv365 = byMethod(payload.series, "trade-close", "iv365");
|
|
213
|
+
const skew = skewSeries(payload.series);
|
|
148
214
|
const since = payload.coverage?.since ?? earliest;
|
|
149
215
|
const oneYearSince = payload.coverage?.iv365Since ?? (tradeIv365[0] ? day(tradeIv365[0].date) : null);
|
|
150
216
|
const oneYearNote = !oneYearSince ? (since ? "no IV1Y history yet" : null)
|
|
@@ -155,7 +221,8 @@ export function projectIvHistory(
|
|
|
155
221
|
symbol: payload.symbol, status: payload.status,
|
|
156
222
|
iv30: visible(tradeIv30), iv90: visible(byMethod(payload.series, "trade-close", "iv90")), iv365: visible(tradeIv365),
|
|
157
223
|
quoteIv30: visible(byMethod(payload.series, "quote-mid", "iv30")),
|
|
158
|
-
hv, spread: visible(spreadAll),
|
|
224
|
+
hv, spread: visible(spreadAll), skew: visible(skew.points),
|
|
225
|
+
skewSince: skew.points[0] ? day(skew.points[0].date) : null, skewNote: skew.note, stats,
|
|
159
226
|
since, oneYearNote, asOf: latestDate, warnings,
|
|
160
227
|
};
|
|
161
228
|
}
|
|
@@ -163,7 +230,14 @@ export function projectIvHistory(
|
|
|
163
230
|
export type RichCheap = "rich" | "cheap" | "fair" | null;
|
|
164
231
|
export interface RichCheapRow {
|
|
165
232
|
symbol: string;
|
|
166
|
-
|
|
233
|
+
/** Where the symbol's history stands, as HIVG reads it; an older server says only ready or queued. */
|
|
234
|
+
status: IvCoverageStatus;
|
|
235
|
+
/** When the symbol was queued for backfill, when the server says. */
|
|
236
|
+
queuedAt: string | null;
|
|
237
|
+
/** The last session its backfill has reached. */
|
|
238
|
+
backfilledThrough: string | null;
|
|
239
|
+
/** Why an unavailable symbol is not covered yet (demand coverage is full): not final, unlike one with no options history. */
|
|
240
|
+
warning: string | null;
|
|
167
241
|
iv30: number | null;
|
|
168
242
|
date: string | null;
|
|
169
243
|
method: IvMethod | null;
|
|
@@ -228,7 +302,9 @@ export function projectRichCheap(rows: readonly IvScreenRow[], hv: ReadonlyMap<s
|
|
|
228
302
|
const realized = hv.get(row.symbol) ?? null;
|
|
229
303
|
const percentile = row.iv30?.percentile ?? null;
|
|
230
304
|
return {
|
|
231
|
-
symbol: row.symbol, status: row.
|
|
305
|
+
symbol: row.symbol, status: row.coverageStatus ?? row.status, queuedAt: row.coverage?.addedAt ?? null,
|
|
306
|
+
backfilledThrough: row.coverage?.backfilledThrough ?? null, warning: row.warnings?.[0] ?? null,
|
|
307
|
+
iv30, date: latest?.date ?? null, method: latest?.method ?? null,
|
|
232
308
|
rank: row.iv30?.rank ?? null, percentile, rankDate: row.iv30?.date ?? null,
|
|
233
309
|
termSlope: iv30 != null && latest?.iv90 != null ? iv30 - latest.iv90 : null,
|
|
234
310
|
iv1y: latest?.iv365 ?? null,
|
|
@@ -240,6 +316,65 @@ export function projectRichCheap(rows: readonly IvScreenRow[], hv: ReadonlyMap<s
|
|
|
240
316
|
});
|
|
241
317
|
}
|
|
242
318
|
|
|
319
|
+
interface ScreenCoverage {
|
|
320
|
+
/** One line per state, each symbol dated: queued since when, backfilled through which session. */
|
|
321
|
+
notes: string[];
|
|
322
|
+
/** Symbols whose history is still to come or not covered yet: the screen is incomplete while there are any. */
|
|
323
|
+
pending: string[];
|
|
324
|
+
/** Those of them with no reading to show yet. */
|
|
325
|
+
missing: string[];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* What VCA says about symbols without a full history, in the report's notes
|
|
330
|
+
* and the pane's notices. A queued symbol says since when and, with `retry`,
|
|
331
|
+
* when to look again: ten minutes after the newest of them was queued. One
|
|
332
|
+
* backfilling says how far it has got. One that finished with no options
|
|
333
|
+
* history is final and leaves the screen complete; one demand coverage could
|
|
334
|
+
* not take is not final. An older server says only ready or queued, without
|
|
335
|
+
* dates, so its queued symbols are counted from now as before. A symbol in
|
|
336
|
+
* `explained` (a listing that stopped trading, which its row says) is not
|
|
337
|
+
* listed again as having no options history.
|
|
338
|
+
*/
|
|
339
|
+
export function screenCoverage(
|
|
340
|
+
rows: readonly RichCheapRow[],
|
|
341
|
+
options: { now?: number; retry?: boolean; explained?: ReadonlySet<string> } = {},
|
|
342
|
+
): ScreenCoverage {
|
|
343
|
+
const now = options.now ?? Date.now();
|
|
344
|
+
const queued = rows.filter((row) => row.status === "queued");
|
|
345
|
+
const backfilling = rows.filter((row) => row.status === "backfilling");
|
|
346
|
+
const final = rows.filter((row) => row.status === "unavailable" && !row.warning && !options.explained?.has(row.symbol));
|
|
347
|
+
const uncovered = rows.filter((row) => row.status === "unavailable" && row.warning);
|
|
348
|
+
const notes: string[] = [];
|
|
349
|
+
if (queued.length) {
|
|
350
|
+
const times = queued.map((row) => queuedTime(row.queuedAt, now));
|
|
351
|
+
const listed = queued.map((row, index) => times[index] == null ? row.symbol : `${row.symbol} since ${utcClock(times[index]!, now)}`);
|
|
352
|
+
const newest = Math.max(...times.map((time) => time ?? now));
|
|
353
|
+
notes.push(`Queued for backfill: ${listed.join(", ")}; ${firstBackfillText(newest, now, options.retry ?? true)}.`);
|
|
354
|
+
}
|
|
355
|
+
if (backfilling.length) {
|
|
356
|
+
notes.push(`Backfilling: ${backfilling.map((row) => row.backfilledThrough ? `${row.symbol} through ${row.backfilledThrough}` : row.symbol).join(", ")}.`);
|
|
357
|
+
}
|
|
358
|
+
if (final.length) notes.push(`No options history: ${final.map((row) => row.symbol).join(", ")}.`);
|
|
359
|
+
const reasons = new Map<string, string[]>();
|
|
360
|
+
for (const row of uncovered) reasons.set(row.warning!, [...(reasons.get(row.warning!) ?? []), row.symbol]);
|
|
361
|
+
for (const [reason, symbols] of reasons) notes.push(`Not queued: ${symbols.join(", ")}. ${reason}`);
|
|
362
|
+
const pending = [...queued, ...backfilling, ...uncovered];
|
|
363
|
+
return { notes, pending: pending.map((row) => row.symbol),
|
|
364
|
+
missing: pending.filter((row) => row.iv30 == null && row.date == null).map((row) => row.symbol) };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* The VCA pane's notices: the report's wording without a time to come back
|
|
369
|
+
* at, since the pane checks again by itself, and a count of ready symbols with
|
|
370
|
+
* no IV30, which is how an older server reports one that found no options.
|
|
371
|
+
*/
|
|
372
|
+
export function screenPaneNotices(rows: readonly RichCheapRow[], now = Date.now()): string[] {
|
|
373
|
+
const empty = rows.filter((row) => row.status === "ready" && row.iv30 == null).length;
|
|
374
|
+
return [...screenCoverage(rows, { now, retry: false }).notes,
|
|
375
|
+
...(empty ? [`${empty} symbol${empty === 1 ? " has" : "s have"} no stored implied volatility yet.`] : [])];
|
|
376
|
+
}
|
|
377
|
+
|
|
243
378
|
export const VCA_PRESETS = {
|
|
244
379
|
etfs: ["SPY", "QQQ", "IWM", "DIA", "EEM", "EFA", "FXI", "EWZ", "GLD", "SLV", "GDX", "USO", "TLT", "HYG",
|
|
245
380
|
"XLE", "XLF", "XLK", "XLV", "XLY", "XLP", "XLI", "XLU", "SMH", "XBI", "KRE"],
|
|
@@ -10,7 +10,7 @@ import { useAutoRefresh } from "../../../react/auto-refresh";
|
|
|
10
10
|
import { compareSortValues, nextHeaderSort, type SortDirection } from "../../../utils/sort-values";
|
|
11
11
|
import { loadIvScreen, loadRealizedVolatilities } from "./client";
|
|
12
12
|
import { formatPoints, formatRank, formatVol, readingLabel, sharedDates, shortDate, VCA_DEFINITIONS, verdictLabel } from "./format";
|
|
13
|
-
import { projectRichCheap, type RichCheapRow, richCheapDates, type VcaPreset } from "./model";
|
|
13
|
+
import { projectRichCheap, type RichCheapRow, richCheapDates, screenPaneNotices, type VcaPreset } from "./model";
|
|
14
14
|
import { vcaUniverse } from "./universe";
|
|
15
15
|
|
|
16
16
|
type SortId = keyof RichCheapRow;
|
|
@@ -78,12 +78,8 @@ export function IvScreenPane({ width, height, focused }: PaneProps) {
|
|
|
78
78
|
}
|
|
79
79
|
}), [rows, dates]);
|
|
80
80
|
const [selected, setSelected] = useState<string | null>(null);
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const notices = [universe.error, resource.error,
|
|
84
|
-
...(queued ? [`${queued} symbol${queued === 1 ? "" : "s"} queued for implied volatility history; they fill in after backfill.`] : []),
|
|
85
|
-
...(uncovered ? [`${uncovered} symbol${uncovered === 1 ? " has" : "s have"} no stored implied volatility yet.`] : [])]
|
|
86
|
-
.filter((value): value is string => !!value);
|
|
81
|
+
const coverageNotices = useMemo(() => screenPaneNotices(rows), [rows]);
|
|
82
|
+
const notices = [universe.error, resource.error, ...coverageNotices].filter((value): value is string => !!value);
|
|
87
83
|
usePaneNoticeFooter({ registrationId: "iv-screen-notices", notices, focused });
|
|
88
84
|
const openHistory = (row: RichCheapRow) => createPaneFromTemplate("iv-history-pane", { symbol: row.symbol });
|
|
89
85
|
// The full wording gives way to the short form in a pane too narrow to show the rank date.
|
|
@@ -102,8 +98,8 @@ export function IvScreenPane({ width, height, focused }: PaneProps) {
|
|
|
102
98
|
switch (id) {
|
|
103
99
|
case "symbol": return { text: row.symbol, color: colors.textBright };
|
|
104
100
|
case "iv30": return { text: formatVol(row.iv30), color: colors.warning };
|
|
105
|
-
case "date": return { text: row.date ? readingLabel(row.date, row.method, true)
|
|
106
|
-
color: colors.textDim };
|
|
101
|
+
case "date": return { text: row.date ? readingLabel(row.date, row.method, true)
|
|
102
|
+
: row.status === "queued" || row.status === "backfilling" ? row.status : "--", color: colors.textDim };
|
|
107
103
|
case "rankDate": return { text: row.rankDate ? `${shortDate(row.rankDate)} close` : "--", color: colors.textDim };
|
|
108
104
|
case "rank": return { text: formatRank(row.rank) };
|
|
109
105
|
case "percentile": return { text: formatRank(row.percentile) };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SeriesDefinition } from "../../../series/types";
|
|
2
|
+
import { loadIvHistory, type IvPoint } from "./client";
|
|
3
|
+
|
|
4
|
+
const TENORS: ReadonlyArray<readonly [key: "iv30" | "iv90" | "iv365", label: string]> = [
|
|
5
|
+
["iv30", "30-day"],
|
|
6
|
+
["iv90", "90-day"],
|
|
7
|
+
["iv365", "1-year"],
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
/** A ticker's at-the-money implied volatility by tenor, one close per session. */
|
|
11
|
+
export const IV_SERIES: readonly SeriesDefinition[] = TENORS.map(([key, label]): SeriesDefinition => ({
|
|
12
|
+
id: `implied-vol:${key}`,
|
|
13
|
+
name: `${label} implied volatility`,
|
|
14
|
+
unit: "%",
|
|
15
|
+
frequency: "daily",
|
|
16
|
+
group: "Volatility",
|
|
17
|
+
tags: ["IV", "implied volatility", "options", key],
|
|
18
|
+
input: "ticker",
|
|
19
|
+
load: async ({ ticker, signal }) => {
|
|
20
|
+
const payload = await loadIvHistory(ticker!, { ...(signal ? { signal } : {}) });
|
|
21
|
+
return {
|
|
22
|
+
points: payload.series.map((point: IvPoint) => ({
|
|
23
|
+
date: point.sessionDate,
|
|
24
|
+
value: point[key] == null ? null : point[key]! * 100,
|
|
25
|
+
})),
|
|
26
|
+
...(payload.warnings.length ? { warning: payload.warnings.join("; ") } : {}),
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
HeadlessBundleResult,
|
|
3
|
+
HeadlessPaneContext,
|
|
3
4
|
HeadlessPaneDefinition,
|
|
4
5
|
} from "../../../types/plugin";
|
|
6
|
+
import { cloudAccountNeed, cloudDeniedStatus, type CloudDeniedStatus } from "../shared/cloud-denied";
|
|
5
7
|
import { formatCompact, formatNumber } from "../../../utils/format";
|
|
6
8
|
import { fetchJobs, fetchJobsMovers, type JobsCloudClient, type JobsCompanyState } from "./client";
|
|
7
9
|
import {
|
|
@@ -13,8 +15,19 @@ import {
|
|
|
13
15
|
functionLabel,
|
|
14
16
|
} from "./model";
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* What a refused account needs, and the free preview to try instead: HIRE
|
|
20
|
+
* reads the same careers systems, and is named only when it answers for this
|
|
21
|
+
* company.
|
|
22
|
+
*/
|
|
23
|
+
async function jobsDeniedMessage(symbol: string | undefined, status: CloudDeniedStatus, client: Pick<HeadlessPaneContext["apiClient"], "getCloudHiring">): Promise<string> {
|
|
24
|
+
const need = cloudAccountNeed(status);
|
|
25
|
+
const preview = await client.getCloudHiring(symbol, { limit: 1 })
|
|
26
|
+
.then((payload) => !!payload && (symbol ? "symbol" in payload : "companies" in payload), () => false);
|
|
27
|
+
return `JOBS needs ${need}${preview ? `; HIRE${symbol ? ` ${symbol}` : ""} is free to preview` : ""}.`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function companyBundle(symbol: string, state: Exclude<JobsCompanyState, { kind: "denied" }>, roleLimit: number): HeadlessBundleResult {
|
|
18
31
|
if (state.kind === "pending") {
|
|
19
32
|
return {
|
|
20
33
|
sections: [{ title: "Hiring", entries: [{ label: "Status", value: "pending", formatted: state.message }] }],
|
|
@@ -169,15 +182,25 @@ export const jobsHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
169
182
|
maximum: 200,
|
|
170
183
|
},
|
|
171
184
|
],
|
|
185
|
+
// No aliases: the template's keywords stay the catalog's search terms.
|
|
186
|
+
discovery: {
|
|
187
|
+
dataRequirements: ["Gloom Cloud Pro account"],
|
|
188
|
+
limitations: ["Pro only; HIRE <ticker> previews a company's hiring for free."],
|
|
189
|
+
},
|
|
172
190
|
describe: (args) => (args.symbols[0] ? `Hiring | ${args.symbols[0]}` : "Hiring | coverage"),
|
|
173
191
|
async load(args, ctx): Promise<HeadlessBundleResult> {
|
|
174
192
|
const limit = Number(args.options.roles);
|
|
175
193
|
const symbol = args.symbols[0];
|
|
176
194
|
if (symbol) {
|
|
177
195
|
const state = await fetchJobs(symbol, { force: true, client: ctx.apiClient as JobsCloudClient });
|
|
196
|
+
if (state.kind === "denied") throw new Error(await jobsDeniedMessage(symbol, state.status, ctx.apiClient));
|
|
178
197
|
return companyBundle(symbol, state, limit);
|
|
179
198
|
}
|
|
180
|
-
const payload = await fetchJobsMovers(ctx.apiClient as JobsCloudClient)
|
|
199
|
+
const payload = await fetchJobsMovers(ctx.apiClient as JobsCloudClient).catch(async (error: unknown) => {
|
|
200
|
+
const status = cloudDeniedStatus(error);
|
|
201
|
+
if (status) throw new Error(await jobsDeniedMessage(undefined, status, ctx.apiClient));
|
|
202
|
+
throw error;
|
|
203
|
+
});
|
|
181
204
|
const rows = buildMoverRows(payload.movers).slice(0, Math.max(limit, 15)).map((row) => ({
|
|
182
205
|
ticker: row.ticker,
|
|
183
206
|
company: row.company,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { publicTickerBindingSymbol } from "../../../tickers/selection";
|
|
2
2
|
import type { PluginModule } from "../plugin-module";
|
|
3
|
+
import { JOBS_SERIES } from "./series";
|
|
3
4
|
import { resetJobsCache } from "./client";
|
|
4
5
|
import { jobsHeadless } from "./headless";
|
|
5
6
|
import { JOBS_PANE_ID, JobsPane, JobsResearchTab } from "./pane";
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
const description =
|
|
9
|
-
"
|
|
10
|
+
"Pro hiring read from the company's own careers system: open roles over time, by function and location, new roles, pay ranges. Alone, every covered company ranked.";
|
|
10
11
|
|
|
11
12
|
function explicitSymbol(options?: { arg?: string; symbol?: string | null }): string | null {
|
|
12
13
|
const symbol = (options?.symbol ?? options?.arg ?? "").trim().toUpperCase();
|
|
@@ -14,6 +15,7 @@ function explicitSymbol(options?: { arg?: string; symbol?: string | null }): str
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export const jobsModule: PluginModule = {
|
|
18
|
+
series: JOBS_SERIES,
|
|
17
19
|
setup(ctx) {
|
|
18
20
|
ctx.registerTickerResearchTab({
|
|
19
21
|
id: "jobs",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SeriesDefinition } from "../../../series/types";
|
|
2
|
+
import { fetchJobs } from "./client";
|
|
3
|
+
|
|
4
|
+
/** A company's open job postings each day, as the jobs pane charts them. */
|
|
5
|
+
export const JOBS_SERIES: readonly SeriesDefinition[] = [{
|
|
6
|
+
id: "jobs:open-roles",
|
|
7
|
+
name: "Open job postings",
|
|
8
|
+
unit: "jobs",
|
|
9
|
+
frequency: "daily",
|
|
10
|
+
group: "Alternative data",
|
|
11
|
+
tags: ["hiring", "jobs", "postings", "headcount"],
|
|
12
|
+
input: "ticker",
|
|
13
|
+
load: async ({ ticker }) => {
|
|
14
|
+
const state = await fetchJobs(ticker!);
|
|
15
|
+
if (state.kind === "pending") throw new Error(state.message || `Postings for ${ticker} are still being collected.`);
|
|
16
|
+
if (state.kind !== "ready") throw new Error(state.message || `No postings for ${ticker}.`);
|
|
17
|
+
return state.summary.series.map((point) => ({ date: point.day, value: point.open }));
|
|
18
|
+
},
|
|
19
|
+
}];
|
|
@@ -19,6 +19,8 @@ export const positionSizerModule: PluginModule = {
|
|
|
19
19
|
reportFreshness: { source: "Your inputs and Gloom Cloud", status: "not-a-feed", basis: "position sizing" },
|
|
20
20
|
name: "Position Sizer",
|
|
21
21
|
icon: "K",
|
|
22
|
+
// The bankroll is the account's value.
|
|
23
|
+
personalData: "holdings",
|
|
22
24
|
component: KellySizerPane,
|
|
23
25
|
defaultPosition: "right",
|
|
24
26
|
defaultMode: "floating",
|
|
@@ -85,7 +85,8 @@ import {
|
|
|
85
85
|
buildKellyHistoryItems,
|
|
86
86
|
buildKellyResultItems,
|
|
87
87
|
} from "./sections";
|
|
88
|
-
import {
|
|
88
|
+
import { resolveActivePortfolioId, resolveKellyBankroll } from "./portfolio";
|
|
89
|
+
import { getPortfolioPositionValue } from "../../../portfolio/position-value";
|
|
89
90
|
import { useKellyCommonAssumptions } from "./state";
|
|
90
91
|
|
|
91
92
|
export function KellySizerPane({ focused, width, height }: PaneProps) {
|
|
@@ -1,46 +1,7 @@
|
|
|
1
1
|
import type { AppConfig } from "../../../types/config";
|
|
2
|
-
import type { TickerFinancials } from "../../../types/financials";
|
|
3
2
|
import type { TickerRecord } from "../../../types/ticker";
|
|
4
|
-
import { convertCurrency } from "../../../utils/format";
|
|
5
3
|
import { allocationTotal, type AllocationHolding } from "../portfolio-list/allocation";
|
|
6
4
|
import { getCollectionTypeFromConfig } from "../portfolio-list/pane/data";
|
|
7
|
-
import { getPortfolioPositionMetrics, getPortfolioQuoteDisplay, resolvePortfolioMarketValue } from "../portfolio-list/position-metrics";
|
|
8
|
-
|
|
9
|
-
export function getPortfolioPositionValue({
|
|
10
|
-
ticker,
|
|
11
|
-
financials,
|
|
12
|
-
portfolioId,
|
|
13
|
-
baseCurrency,
|
|
14
|
-
exchangeRates,
|
|
15
|
-
}: {
|
|
16
|
-
ticker: TickerRecord | null;
|
|
17
|
-
financials: TickerFinancials | null;
|
|
18
|
-
portfolioId: string | null;
|
|
19
|
-
baseCurrency: string;
|
|
20
|
-
exchangeRates: Map<string, number>;
|
|
21
|
-
}): number {
|
|
22
|
-
if (!ticker) return 0;
|
|
23
|
-
const scopedTicker: TickerRecord = portfolioId
|
|
24
|
-
? {
|
|
25
|
-
...ticker,
|
|
26
|
-
metadata: {
|
|
27
|
-
...ticker.metadata,
|
|
28
|
-
positions: ticker.metadata.positions.filter((position) => position.portfolio === portfolioId),
|
|
29
|
-
},
|
|
30
|
-
}
|
|
31
|
-
: ticker;
|
|
32
|
-
const quote = financials?.quote;
|
|
33
|
-
|
|
34
|
-
const quoteCurrency = quote?.currency || ticker.metadata.currency || baseCurrency;
|
|
35
|
-
const metrics = getPortfolioPositionMetrics(scopedTicker, undefined, quoteCurrency, {
|
|
36
|
-
currency: baseCurrency, convert: (value, currency) => convertCurrency(value, currency, baseCurrency, exchangeRates),
|
|
37
|
-
}, quote);
|
|
38
|
-
const activeQuote = getPortfolioQuoteDisplay(metrics, quote);
|
|
39
|
-
|
|
40
|
-
return resolvePortfolioMarketValue(metrics, activeQuote
|
|
41
|
-
? convertCurrency(activeQuote.price, quoteCurrency, baseCurrency, exchangeRates) : null)?.gross
|
|
42
|
-
?? (metrics.positionCount > 0 ? Number.NaN : 0);
|
|
43
|
-
}
|
|
44
5
|
|
|
45
6
|
/**
|
|
46
7
|
* What the portfolio is worth to bet with: its equity. A broker account's is
|
|
@@ -7,7 +7,9 @@ import type { DataProvider } from "../../../types/data-provider";
|
|
|
7
7
|
import type { PricePoint } from "../../../types/financials";
|
|
8
8
|
import { abortable, abortError } from "../../../utils/async-deadline";
|
|
9
9
|
import { errorMessage } from "../../../utils/errors";
|
|
10
|
-
import { resolveExchangeTimeZone } from "../../../utils/exchanges";
|
|
10
|
+
import { parsePublicTickerKey, resolveExchangeTimeZone } from "../../../utils/exchanges";
|
|
11
|
+
import { loadEarningsHistory } from "../earnings/client";
|
|
12
|
+
import type { MacroDayEarningsReport } from "./model";
|
|
11
13
|
import { bundledMacroReleases, mergeMacroReleases, type MacroReleaseList } from "./releases";
|
|
12
14
|
|
|
13
15
|
export const macroReleaseCache = createPluginCache<CloudMacroReleaseDaysPayload>({
|
|
@@ -43,11 +45,12 @@ const US_LISTINGS_ONLY = "Macro-day moves are for US listings.";
|
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* A listing whose venue sits outside New York trades US releases on a different clock.
|
|
46
|
-
* A bare symbol such as 7203.T carries no exchange, so its venue suffix names it
|
|
48
|
+
* A bare symbol such as 7203.T carries no exchange, so its venue suffix names it,
|
|
49
|
+
* and a listing key such as SAP:XETR names it before the ticker record has loaded.
|
|
47
50
|
*/
|
|
48
51
|
function isNonUsVenue(instrument: InstrumentRef): boolean {
|
|
49
52
|
if (tickerHasListingSuffix(instrument.symbol)) return true;
|
|
50
|
-
const zone = resolveExchangeTimeZone(instrument.exchange);
|
|
53
|
+
const zone = resolveExchangeTimeZone(instrument.exchange || parsePublicTickerKey(instrument.symbol).exchange);
|
|
51
54
|
return !!zone && zone !== "America/New_York";
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -72,3 +75,41 @@ export async function loadMacroDayHistory(
|
|
|
72
75
|
return { history: [], stale: false, error: errorMessage(error), fetchedAt: now };
|
|
73
76
|
}
|
|
74
77
|
}
|
|
78
|
+
|
|
79
|
+
export interface MacroDayEarnings {
|
|
80
|
+
reports: MacroDayEarningsReport[];
|
|
81
|
+
stale: boolean;
|
|
82
|
+
/** Why the reports are missing; the study then runs without the earnings marker. */
|
|
83
|
+
error: string | null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The earnings history's own depth: the oldest report that can matter is five years back, about twenty quarters. */
|
|
87
|
+
const EARNINGS_REPORT_LIMIT = 24;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The ticker's own earnings reports, from the history `ERN` shows. Never
|
|
91
|
+
* rejects but on cancel: a listing outside the US or without reports has none,
|
|
92
|
+
* and a failed read leaves the study as it was, with the reason in `error`.
|
|
93
|
+
*/
|
|
94
|
+
export async function loadMacroDayEarnings(
|
|
95
|
+
request: { instrument: InstrumentRef; signal?: AbortSignal; forceRefresh?: boolean },
|
|
96
|
+
load: typeof loadEarningsHistory = loadEarningsHistory,
|
|
97
|
+
): Promise<MacroDayEarnings> {
|
|
98
|
+
if (request.signal?.aborted) throw abortError(CANCELLED);
|
|
99
|
+
if (isNonUsVenue(request.instrument)) return { reports: [], stale: false, error: null };
|
|
100
|
+
try {
|
|
101
|
+
// Earnings are keyed by the bare US symbol; a listing key ("CRWV:XNAS") drops its exchange.
|
|
102
|
+
const symbol = parsePublicTickerKey(request.instrument.symbol.trim()).symbol.toUpperCase();
|
|
103
|
+
const resource = await abortable(load(symbol, request.forceRefresh, EARNINGS_REPORT_LIMIT), request.signal, CANCELLED);
|
|
104
|
+
return { reports: resource.payload.reports.map((report) => ({ date: report.date, timing: report.timing, reactionSession: report.realized?.afterSession ?? null })),
|
|
105
|
+
stale: resource.stale, error: null };
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (request.signal?.aborted || (error instanceof Error && error.name === "AbortError")) throw abortError(CANCELLED);
|
|
108
|
+
return { reports: [], stale: false, error: errorMessage(error) };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** What the pane footer and the report notes say when the earnings marker could not be applied. */
|
|
113
|
+
export function macroDayEarningsNotice(earnings: MacroDayEarnings): string | null {
|
|
114
|
+
return earnings.error ? `Earnings dates unavailable (${earnings.error}); release days on the company's own report are not marked.` : null;
|
|
115
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HeadlessPaneDefinition } from "../../../types/plugin";
|
|
2
2
|
import { resolveHeadlessInstrument } from "../shared/headless-market-data";
|
|
3
|
-
import { loadMacroDayHistory, loadMacroReleases } from "./client";
|
|
4
|
-
import { projectMacroDays, type MacroDayStats } from "./model";
|
|
3
|
+
import { loadMacroDayEarnings, loadMacroDayHistory, loadMacroReleases, macroDayEarningsNotice } from "./client";
|
|
4
|
+
import { macroDayEventLabel, projectMacroDays, type MacroDayStats } from "./model";
|
|
5
5
|
import { MACRO_EVENT_KINDS, MACRO_EVENT_LABELS, MACRO_RELEASE_SOURCES, staleMacroReleasesNotice } from "./releases";
|
|
6
6
|
|
|
7
7
|
// A mean that rounds to zero reads 0.00%, never -0.00%.
|
|
@@ -11,12 +11,14 @@ const share = (value: unknown) => typeof value === "number" ? `${Math.round(valu
|
|
|
11
11
|
|
|
12
12
|
export const macroDayHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
13
13
|
shape: "bundle", argument: { kind: "ticker", description: "Ticker" },
|
|
14
|
+
usListingsOnly: "Macro release day data",
|
|
14
15
|
// Dated by the release list (releasesThrough) as much as by the closes, so no session schedule applies.
|
|
15
16
|
freshness: { status: "not-a-feed", basis: "release-day study on daily closes" },
|
|
16
17
|
describe: (args) => `MDAY ${args.symbols[0] ?? ""}`,
|
|
17
18
|
discovery: { screenshotReadiness: "live-dom", limitations: [
|
|
18
19
|
"US listings; close-to-close on the release day.",
|
|
19
20
|
"Published CPI, jobs and FOMC days; sessions after the list's last covered day (releasesThrough) are left out.",
|
|
21
|
+
"A release day that is also the reaction session of the company's own earnings report is marked earnings and left out of the release averages and the normal day.",
|
|
20
22
|
] },
|
|
21
23
|
options: [
|
|
22
24
|
{ key: "release", type: "enum", values: [{ value: "all" }, ...MACRO_EVENT_KINDS.map((value) => ({ value }))], defaultValue: "all",
|
|
@@ -25,11 +27,12 @@ export const macroDayHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
25
27
|
],
|
|
26
28
|
async load(args, ctx) {
|
|
27
29
|
const instrument = await resolveHeadlessInstrument(ctx, args.symbols[0]!);
|
|
28
|
-
const [history, releases] = await Promise.all([loadMacroDayHistory({ instrument, signal: ctx.signal }, ctx.marketData), loadMacroReleases()
|
|
30
|
+
const [history, releases, earnings] = await Promise.all([loadMacroDayHistory({ instrument, signal: ctx.signal }, ctx.marketData), loadMacroReleases(),
|
|
31
|
+
loadMacroDayEarnings({ instrument, signal: ctx.signal })]);
|
|
29
32
|
ctx.signal.throwIfAborted();
|
|
30
33
|
const model = projectMacroDays(history.history, { symbol: instrument.symbol, lookbackYears: Number(args.options.lookbackYears) || 5,
|
|
31
|
-
releases: releases.releases, coveredThrough: releases.coveredThrough });
|
|
32
|
-
const
|
|
34
|
+
releases: releases.releases, coveredThrough: releases.coveredThrough, earnings: earnings.reports });
|
|
35
|
+
const notes = [staleMacroReleasesNotice(releases), macroDayEarningsNotice(earnings)].filter((note): note is string => !!note);
|
|
33
36
|
const row = (label: string, stats: MacroDayStats) => ({ label, ...stats });
|
|
34
37
|
const release = String(args.options.release ?? "all");
|
|
35
38
|
const events = release === "all" ? model.events : model.events.filter((event) => event.kind === release);
|
|
@@ -39,18 +42,18 @@ export const macroDayHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
39
42
|
{ key: "meanAbs", header: "Avg |move|", format: percent }, { key: "multiple", header: "vs normal", format: multiple },
|
|
40
43
|
{ key: "mean", header: "Avg move", format: percent }, { key: "hitRate", header: "Up", format: share }],
|
|
41
44
|
rows: [...MACRO_EVENT_KINDS.map((kind) => row(MACRO_EVENT_LABELS[kind], model.byKind[kind])),
|
|
42
|
-
row("Any release", model.allEvents), row("Normal day", model.normal)] },
|
|
45
|
+
row("Any release", model.allEvents), ...(model.earnings.count ? [row("Earnings", model.earnings)] : []), row("Normal day", model.normal)] },
|
|
43
46
|
{ title: "Release days", columns: [{ key: "date", header: "Date" }, { key: "event", header: "Release" },
|
|
44
47
|
{ key: "session", header: "Session" }, { key: "move", header: "Move", format: percent }, { key: "multiple", header: "vs normal", format: multiple }],
|
|
45
|
-
rows: events.map((event) => ({ ...event, event:
|
|
48
|
+
rows: events.map((event) => ({ ...event, event: macroDayEventLabel(event) })) },
|
|
46
49
|
],
|
|
47
|
-
complete: !history.stale && !history.error && !
|
|
50
|
+
complete: !history.stale && !earnings.stale && !history.error && !notes.length && model.events.length > 0,
|
|
48
51
|
unavailableSymbols: model.events.length ? [] : [instrument.symbol],
|
|
49
52
|
errors: history.error ? [history.error] : [],
|
|
50
|
-
...(
|
|
53
|
+
...(notes.length ? { notes } : {}),
|
|
51
54
|
metadata: { unit: "decimal return, close to close on the release day", start: model.start, asOf: model.asOf,
|
|
52
55
|
releasesThrough: releases.coveredThrough, releaseSources: Object.values(MACRO_RELEASE_SOURCES),
|
|
53
|
-
stale: history.stale, fetchedAt: history.fetchedAt, methodology: "docs/research-data.md#macro-day-reaction" },
|
|
56
|
+
stale: history.stale || earnings.stale, fetchedAt: history.fetchedAt, methodology: "docs/research-data.md#macro-day-reaction" },
|
|
54
57
|
};
|
|
55
58
|
},
|
|
56
59
|
};
|