gloomberb 0.16.3 → 0.16.5
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 +7 -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 +42 -17
- package/src/account/upgrade-personalization.ts +57 -0
- package/src/account/upgrade-tickers.ts +124 -0
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +58 -18
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +16 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +95 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +46 -10
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +74 -2
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +26 -2
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +61 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +19 -4
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +744 -181
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +425 -0
- package/src/cli/commands/overview.ts +251 -40
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +109 -15
- package/src/cli/commands/system.ts +151 -24
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +149 -40
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +150 -17
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +22 -8
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/glossary.ts +429 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +58 -0
- package/src/cli/index.ts +29 -12
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +595 -26
- package/src/cli/not-a-ticker.ts +44 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +11 -4
- package/src/cli/pane-functions/catalog.ts +48 -7
- package/src/cli/pane-functions/data.ts +48 -13
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +41 -19
- package/src/cli/pane-functions/freshness.ts +531 -32
- package/src/cli/pane-functions/function-help.ts +77 -25
- package/src/cli/pane-functions/headless.ts +50 -21
- package/src/cli/pane-functions/index.ts +66 -10
- package/src/cli/pane-functions/market-session.ts +147 -0
- package/src/cli/pane-functions/options.ts +77 -25
- package/src/cli/pane-functions/report-notices.ts +81 -0
- package/src/cli/pane-functions/report.ts +19 -8
- package/src/cli/pane-functions/resolver.ts +53 -18
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +199 -30
- package/src/cli/registry.ts +2 -1
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +53 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +83 -10
- package/src/components/chart/composite/legend.tsx +88 -8
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -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/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- 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/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +9 -2
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +40 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +26 -2
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +43 -9
- package/src/components/layout/shell/drag/live.ts +87 -6
- package/src/components/layout/shell/drag/runtime.ts +62 -20
- package/src/components/layout/shell/index.tsx +71 -12
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +33 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +216 -28
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +69 -23
- package/src/components/metric-treemap/heat-surface.tsx +37 -9
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- 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-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +50 -41
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
- 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/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +17 -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 +49 -0
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +20 -1
- package/src/components/ui/data-table/visible-range.ts +2 -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 +13 -2
- package/src/components/ui/index.ts +1 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +44 -5
- 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 +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +75 -5
- package/src/i18n/ja.ts +75 -5
- package/src/i18n/ko.ts +75 -5
- package/src/i18n/zh-cn.ts +75 -5
- package/src/i18n/zh-tw.ts +75 -5
- package/src/layout/desks.ts +2 -3
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/market-data/coordinator/quotes.ts +2 -2
- 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 +193 -30
- package/src/market-data/market/status.ts +59 -23
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +22 -2
- package/src/market-data/quotes/metadata.ts +8 -9
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +61 -9
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +2 -56
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +37 -8
- package/src/plugins/builtin/account-management/password-dialog.tsx +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/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- 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 +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +71 -12
- package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
- 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/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -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.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- 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/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +50 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
- package/src/plugins/builtin/cloud/askg/model.ts +156 -78
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
- package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -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 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- 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/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +116 -67
- 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/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +23 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- 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/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -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/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-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +70 -22
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- 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 +70 -9
- 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/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- 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 +64 -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 +114 -20
- 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/index.tsx +18 -8
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- 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 +62 -14
- 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 +42 -134
- package/src/plugins/builtin/holders/pane.tsx +14 -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 +27 -10
- 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/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +26 -6
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +27 -12
- package/src/plugins/builtin/iv-history/index.tsx +5 -3
- package/src/plugins/builtin/iv-history/model.ts +172 -20
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +68 -3
- package/src/plugins/builtin/macro-day/headless.ts +18 -12
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +66 -15
- package/src/plugins/builtin/macro-day/pane.tsx +34 -20
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +102 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +11 -3
- package/src/plugins/builtin/market-movers/model.ts +101 -17
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- 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 +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- 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/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +162 -13
- 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 +5 -2
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +75 -18
- package/src/plugins/builtin/options-scenario/headless.ts +72 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -8
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +32 -6
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +90 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
- package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +8 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- 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/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- 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/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +69 -0
- 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/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +59 -2
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +21 -4
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +3 -10
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- 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/model.ts +1 -1
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- 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/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- 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 +48 -4
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
- package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +125 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- 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/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +129 -64
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +173 -28
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -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 +48 -1
- package/src/remote/app-host.tsx +25 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +126 -59
- package/src/remote/matching.ts +69 -0
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +63 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +32 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -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 +27 -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 +21 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +4 -1
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +14 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +74 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +6 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- 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 +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +26 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +14 -5
- package/src/sources/provider-errors.ts +88 -3
- 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 +9 -5
- package/src/sources/provider-router/financial-routes.ts +12 -5
- package/src/sources/provider-router/financials.ts +55 -15
- package/src/sources/provider-router/history.ts +68 -34
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +5 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +67 -9
- package/src/tickers/search/ranking.ts +78 -18
- package/src/tickers/search/types.ts +10 -2
- package/src/tickers/starter-symbols.ts +8 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +96 -30
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +67 -1
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +72 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +68 -3
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +26 -4
- package/src/ui/index.tsx +2 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +21 -2
- 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/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 +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +120 -1
- package/src/utils/format.ts +17 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +44 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +130 -40
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +178 -36
- package/src/utils/sec.ts +98 -40
- package/src/utils/throttled-fetch.ts +51 -22
- package/src/utils/utc-time.ts +51 -4
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import type { PaneHint } from "../../../components";
|
|
3
|
+
import type { PaneTemplateCreateOptions } from "../../../types/plugin";
|
|
4
|
+
import { usePluginAppActions } from "../../runtime";
|
|
5
|
+
import { RESEARCH_SEARCH_TEMPLATE_ID } from "../research-search/model";
|
|
6
|
+
import { useOpenDescription } from "../shared/open-description";
|
|
7
|
+
import { THIRTEENF_TEMPLATE_ID } from "../thirteenf/model";
|
|
8
|
+
import type { EventAlertRule } from "./events";
|
|
9
|
+
import type { AlertHistoryItem } from "./history";
|
|
10
|
+
import { isResearchAlertKind, readResearchRule } from "./research-rules";
|
|
11
|
+
import type { AlertRule } from "./types";
|
|
12
|
+
|
|
13
|
+
/** What an alert follows, read the same way from a saved rule and from a delivered alert. */
|
|
14
|
+
export interface AlertSubject {
|
|
15
|
+
kind: string;
|
|
16
|
+
symbol?: string;
|
|
17
|
+
exchange?: string;
|
|
18
|
+
marketId?: string;
|
|
19
|
+
/** A macro event rule's release: `cpi` or `fomc`. */
|
|
20
|
+
event?: string;
|
|
21
|
+
keyword?: string;
|
|
22
|
+
cik?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A listing's DES, or a pane template and what it opens on. */
|
|
26
|
+
export type AlertTarget =
|
|
27
|
+
| { kind: "description"; symbol: string; exchange?: string }
|
|
28
|
+
| { kind: "pane"; templateId: string; options?: PaneTemplateCreateOptions };
|
|
29
|
+
|
|
30
|
+
const pane = (templateId: string, options?: PaneTemplateCreateOptions): AlertTarget =>
|
|
31
|
+
({ kind: "pane", templateId, ...(options ? { options } : {}) });
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The one map from what an alert follows to what it opens, for every rule kind and every delivered alert:
|
|
35
|
+
* a perpetual opens PERP on its market; a dated event the pane its date comes from (ERN, CPI, WIRP); catalyst,
|
|
36
|
+
* Congress and 13F rules their calendar or list, on the company or fund they name; any other rule on a security
|
|
37
|
+
* that listing's DES. A rule on no security opens the pane it watches (SRCH for a news keyword, FLOW for flow
|
|
38
|
+
* on the user's lists, FIRST for breaking news). Null when there is nothing to open.
|
|
39
|
+
*/
|
|
40
|
+
export function alertTarget(subject: AlertSubject): AlertTarget | null {
|
|
41
|
+
const { kind, symbol } = subject;
|
|
42
|
+
switch (kind) {
|
|
43
|
+
case "perps_threshold": return subject.marketId ? pane("perps-pane", { arg: subject.marketId }) : null;
|
|
44
|
+
case "earnings_date":
|
|
45
|
+
case "earnings": return symbol ? pane("earnings-calendar-pane", { arg: symbol }) : null;
|
|
46
|
+
case "macro_event": return subject.event === "cpi" ? pane("cpi-pane") : subject.event === "fomc" ? pane("rate-path-pane") : null;
|
|
47
|
+
case "catalyst": return pane("catalysts-pane", symbol ? { symbol } : undefined);
|
|
48
|
+
case "congress_trade": return pane("congress-trades-pane");
|
|
49
|
+
case "thirteenf_filing": return pane(THIRTEENF_TEMPLATE_ID, subject.cik ? { arg: subject.cik } : undefined);
|
|
50
|
+
case "news_keyword": if (!symbol) return pane(RESEARCH_SEARCH_TEMPLATE_ID, subject.keyword ? { arg: subject.keyword } : undefined); break;
|
|
51
|
+
case "options_flow": if (!symbol) return pane("scanner-flow-pane"); break;
|
|
52
|
+
case "breaking_news": if (!symbol) return pane("news-breaking-pane"); break;
|
|
53
|
+
}
|
|
54
|
+
return symbol ? { kind: "description", symbol, ...(subject.exchange ? { exchange: subject.exchange } : {}) } : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** A research rule's `US` is any US venue, which names no listing. */
|
|
58
|
+
const venue = (exchange: string | undefined) => exchange && exchange !== "US" ? exchange : undefined;
|
|
59
|
+
|
|
60
|
+
/** An Events rule: a ticker, a fund or a research rule's own fields. */
|
|
61
|
+
export function eventRuleSubject(rule: EventAlertRule): AlertSubject {
|
|
62
|
+
if (isResearchAlertKind(rule.kind)) {
|
|
63
|
+
const config = readResearchRule(rule.kind, rule.value);
|
|
64
|
+
return { kind: rule.kind, symbol: config?.symbol, exchange: venue(config?.exchange), marketId: config?.marketId, event: config?.event, keyword: config?.keyword };
|
|
65
|
+
}
|
|
66
|
+
return { kind: rule.kind, ...(rule.target === "ticker" ? { symbol: rule.value } : rule.target === "fund" ? { cik: rule.value } : {}) };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const priceRuleSubject = (alert: AlertRule): AlertSubject => ({ kind: "price", symbol: alert.symbol, exchange: alert.exchange });
|
|
70
|
+
|
|
71
|
+
/** A delivered alert, from the fields its notification carries. */
|
|
72
|
+
export function deliveredAlertSubject(item: AlertHistoryItem): AlertSubject {
|
|
73
|
+
const text = (key: string) => {
|
|
74
|
+
const value = item.data?.[key];
|
|
75
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
76
|
+
};
|
|
77
|
+
return { kind: item.kind, symbol: text("symbol"), exchange: venue(text("exchange")), marketId: text("marketId"), event: text("event"), keyword: text("keyword"), cik: text("cik") };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The `v` hint each alerts tab gives its selected row, when the row has something to open. */
|
|
81
|
+
export const alertViewHints = (target: AlertTarget | null, open: (target: AlertTarget) => void): PaneHint[] =>
|
|
82
|
+
target ? [{ id: "view", key: "v", label: "iew", title: "View what it follows", onPress: () => open(target) }] : [];
|
|
83
|
+
|
|
84
|
+
/** Opens an alert's target: a DES the way every pane's `d` does, any other pane from its template. */
|
|
85
|
+
export function useOpenAlertTarget(): (target: AlertTarget) => void {
|
|
86
|
+
const openDescription = useOpenDescription();
|
|
87
|
+
const { createPaneFromTemplate } = usePluginAppActions();
|
|
88
|
+
return useCallback((target: AlertTarget) => {
|
|
89
|
+
if (target.kind === "description") openDescription(target.symbol, target.exchange);
|
|
90
|
+
else createPaneFromTemplate(target.templateId, target.options);
|
|
91
|
+
}, [createPaneFromTemplate, openDescription]);
|
|
92
|
+
}
|
|
@@ -450,13 +450,15 @@ export const portfolioAnalyticsModule: PluginModule = {
|
|
|
450
450
|
component: PortfolioAnalyticsPane,
|
|
451
451
|
headless: portfolioRiskHeadless,
|
|
452
452
|
tableExport: true,
|
|
453
|
-
|
|
453
|
+
// The risk window reads as trailing until it is set.
|
|
454
|
+
settings: (context) => ({ values: { riskSince: context.settings.riskSince ?? "trailing" }, fields: [
|
|
454
455
|
{ key: "analyticsView", label: "View", type: "select", options: [{ value: "overview", label: "Overview" }, { value: "risk", label: "Risk depth" }] },
|
|
456
|
+
{ key: "riskSince", label: "Risk window", type: "select", options: [{ value: "trailing", label: "Trailing 60 sessions" }, { value: "filed", label: "Since 13F filing" }] },
|
|
455
457
|
{ key: "riskEvidence", label: "Local evidence JSON", type: "text" },
|
|
456
458
|
{ key: "equityShift", label: "Index shift (%)", type: "text" },
|
|
457
459
|
{ key: "rateShift", label: "10Y shift (bp)", type: "text" },
|
|
458
460
|
{ key: "volShift", label: "VIX shift (points)", type: "text" },
|
|
459
|
-
] },
|
|
461
|
+
] }),
|
|
460
462
|
defaultPosition: "right",
|
|
461
463
|
defaultMode: "floating",
|
|
462
464
|
defaultFloatingSize: { width: 80, height: 30 },
|
|
@@ -11,8 +11,10 @@ import {
|
|
|
11
11
|
riskCoverageShortfall,
|
|
12
12
|
riskCoverageText,
|
|
13
13
|
RISK_VIEWS,
|
|
14
|
+
riskEvidence,
|
|
14
15
|
riskPercentile,
|
|
15
16
|
riskValue,
|
|
17
|
+
sinceFallbackNote,
|
|
16
18
|
type PortfolioRiskModel,
|
|
17
19
|
type RiskCoverage,
|
|
18
20
|
type RiskDisplayRow,
|
|
@@ -39,7 +41,8 @@ function displayRow(row: RiskDisplayRow) {
|
|
|
39
41
|
value: riskValue(row),
|
|
40
42
|
percentile: riskPercentile(row),
|
|
41
43
|
asOf: row.asOf?.slice(0, 10) ?? null,
|
|
42
|
-
detail: row
|
|
44
|
+
detail: riskEvidence(row),
|
|
45
|
+
...(row.amount != null ? { amount: row.amount, currency: row.amountCurrency ?? null } : {}),
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -130,9 +133,16 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
130
133
|
key: "view",
|
|
131
134
|
type: "enum",
|
|
132
135
|
settingKey: "riskView",
|
|
133
|
-
|
|
136
|
+
// No default: left out, the report prints every view.
|
|
134
137
|
values: RISK_VIEWS.map((value) => ({ value })),
|
|
135
|
-
description: "
|
|
138
|
+
description: "One portfolio risk view; every view when left out.",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: "since",
|
|
142
|
+
type: "enum",
|
|
143
|
+
settingKey: "riskSince",
|
|
144
|
+
values: [{ value: "filed" }],
|
|
145
|
+
description: "Risk rows since the 13F filing date of a portfolio made with portfolio import --13f, instead of the trailing 60 sessions.",
|
|
136
146
|
},
|
|
137
147
|
{
|
|
138
148
|
key: "evidence",
|
|
@@ -144,28 +154,25 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
144
154
|
key: "equity-shift",
|
|
145
155
|
type: "integer",
|
|
146
156
|
settingKey: "equityShift",
|
|
147
|
-
defaultValue: -10,
|
|
148
157
|
minimum: -99,
|
|
149
158
|
maximum: 100,
|
|
150
|
-
description: "Independent index shock in percent.",
|
|
159
|
+
description: "Independent index shock in percent (-10 when left out).",
|
|
151
160
|
},
|
|
152
161
|
{
|
|
153
162
|
key: "rate-shift",
|
|
154
163
|
type: "integer",
|
|
155
164
|
settingKey: "rateShift",
|
|
156
|
-
defaultValue: 100,
|
|
157
165
|
minimum: -500,
|
|
158
166
|
maximum: 500,
|
|
159
|
-
description: "Independent 10Y yield shock in basis points.",
|
|
167
|
+
description: "Independent 10Y yield shock in basis points (100 when left out).",
|
|
160
168
|
},
|
|
161
169
|
{
|
|
162
170
|
key: "vol-shift",
|
|
163
171
|
type: "integer",
|
|
164
172
|
settingKey: "volShift",
|
|
165
|
-
defaultValue: 10,
|
|
166
173
|
minimum: -50,
|
|
167
174
|
maximum: 100,
|
|
168
|
-
description: "Independent VIX shock in index points.",
|
|
175
|
+
description: "Independent VIX shock in index points (10 when left out).",
|
|
169
176
|
},
|
|
170
177
|
],
|
|
171
178
|
describe: (args) =>
|
|
@@ -191,7 +198,8 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
191
198
|
throw new Error(
|
|
192
199
|
"Imported evidence belongs to a different portfolio or currency",
|
|
193
200
|
);
|
|
194
|
-
const
|
|
201
|
+
const requestedView = isRiskView(args.options.view) ? args.options.view : null;
|
|
202
|
+
const view: string = requestedView ?? "risk";
|
|
195
203
|
const localOnly =
|
|
196
204
|
["performance", "attribution", "greeks"].includes(view) &&
|
|
197
205
|
evidence != null;
|
|
@@ -226,7 +234,17 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
226
234
|
rates: Number(args.options["rate-shift"] ?? 100),
|
|
227
235
|
volatility: Number(args.options["vol-shift"] ?? 10),
|
|
228
236
|
},
|
|
237
|
+
args.options.since === "filed" ? { since: "filed" } : {},
|
|
229
238
|
);
|
|
239
|
+
// Options for views the report does not print are named, not dropped silently; the fallback from --since opens the report.
|
|
240
|
+
const fallback = sinceFallbackNote(local.portfolio);
|
|
241
|
+
const shifted = ["equity-shift", "rate-shift", "vol-shift"].filter((key) => args.options[key] != null);
|
|
242
|
+
const notices = [
|
|
243
|
+
...(model.window.kind === "since-filed" ? [`Risk rows since the 13F filing on ${model.window.filed}, against ${model.benchmark}`] : []),
|
|
244
|
+
...(args.options.since === "filed" && model.window.kind !== "since-filed" ? [fallback] : []),
|
|
245
|
+
...(requestedView && requestedView !== "stress" && shifted.length ? [`${shifted.map((key) => `--${key}`).join(", ")} change${shifted.length === 1 ? "s" : ""} the stress view only, not --view ${requestedView}`] : []),
|
|
246
|
+
...(requestedView && args.options.since != null && requestedView !== "risk" ? [`--since changes the risk view only, not --view ${requestedView}`] : []),
|
|
247
|
+
];
|
|
230
248
|
// A basket view is complete only when the basket covers every holding.
|
|
231
249
|
const covered = model.coverage.leftOut.length === 0;
|
|
232
250
|
const complete =
|
|
@@ -246,13 +264,13 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
246
264
|
return {
|
|
247
265
|
complete,
|
|
248
266
|
errors: [...(shortfall ? [shortfall] : []), ...model.warnings],
|
|
249
|
-
notes: [...riskCoverageNotices(model.coverage), ...model.notes],
|
|
250
|
-
sections: RISK_VIEWS.map((view) => ({
|
|
267
|
+
notes: [...riskCoverageNotices(model.coverage), ...model.notes.filter((note) => note !== fallback)],
|
|
268
|
+
sections: (requestedView ? [requestedView] : RISK_VIEWS).map((view) => ({
|
|
251
269
|
title: view,
|
|
252
270
|
columns: RISK_COLUMNS,
|
|
253
271
|
rows: model.rows[view].map(displayRow),
|
|
254
272
|
})),
|
|
255
|
-
metadata: { coverage: coverageSummary(model.coverage), model },
|
|
273
|
+
metadata: { coverage: coverageSummary(model.coverage), model, benchmark: model.benchmark, window: model.window, notices },
|
|
256
274
|
};
|
|
257
275
|
},
|
|
258
276
|
compact(result, args) {
|
|
@@ -278,6 +296,8 @@ export const portfolioRiskHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
278
296
|
currency: model.portfolio.currency,
|
|
279
297
|
},
|
|
280
298
|
view,
|
|
299
|
+
benchmark: model.benchmark,
|
|
300
|
+
window: model.window,
|
|
281
301
|
...(basketView && model.coverage
|
|
282
302
|
? { coverage: coverageSummary(model.coverage, COMPACT_LEFT_OUT_LIMIT) }
|
|
283
303
|
: {}),
|
|
@@ -186,28 +186,24 @@ const percentile = (
|
|
|
186
186
|
};
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
): RiskStatistic[] {
|
|
193
|
-
if (!Number.isInteger(window) || window < 60)
|
|
194
|
-
throw new Error("Risk window must contain at least 60 daily sessions");
|
|
195
|
-
const definitions = [
|
|
189
|
+
/** The return and risk statistics of a basket against its benchmark, over one window of paired sessions. */
|
|
190
|
+
function basketRiskDefinitions(benchmark: string) {
|
|
191
|
+
return [
|
|
196
192
|
{
|
|
197
193
|
id: "return",
|
|
198
|
-
|
|
194
|
+
name: "basket return",
|
|
199
195
|
value: (rows: RiskSamplePoint[]) =>
|
|
200
196
|
100 * compoundReturns(rows.map((row) => row.value)),
|
|
201
197
|
},
|
|
202
198
|
{
|
|
203
199
|
id: "benchmark",
|
|
204
|
-
|
|
200
|
+
name: `benchmark return (${benchmark})`,
|
|
205
201
|
value: (rows: RiskSamplePoint[]) =>
|
|
206
202
|
100 * compoundReturns(rows.map((row) => row.benchmark)),
|
|
207
203
|
},
|
|
208
204
|
{
|
|
209
205
|
id: "active",
|
|
210
|
-
|
|
206
|
+
name: "active return",
|
|
211
207
|
value: (rows: RiskSamplePoint[]) =>
|
|
212
208
|
100 *
|
|
213
209
|
(compoundReturns(rows.map((row) => row.value)) -
|
|
@@ -215,36 +211,56 @@ export function rollingBasketRisk(
|
|
|
215
211
|
},
|
|
216
212
|
{
|
|
217
213
|
id: "volatility",
|
|
218
|
-
|
|
219
|
-
value: (rows: RiskSamplePoint[]) =>
|
|
220
|
-
|
|
214
|
+
name: "annualized volatility",
|
|
215
|
+
value: (rows: RiskSamplePoint[]) => {
|
|
216
|
+
const volatility = sampleVolatility(rows.map((row) => row.value));
|
|
217
|
+
return volatility == null ? null : 100 * volatility;
|
|
218
|
+
},
|
|
221
219
|
},
|
|
222
220
|
{
|
|
223
221
|
id: "drawdown",
|
|
224
|
-
|
|
222
|
+
name: "max drawdown",
|
|
225
223
|
value: (rows: RiskSamplePoint[]) =>
|
|
226
224
|
100 * Math.min(0, ...drawdownPath(rows.map((row) => row.value))),
|
|
227
225
|
},
|
|
228
226
|
{
|
|
229
227
|
id: "var",
|
|
230
|
-
|
|
231
|
-
value: (rows: RiskSamplePoint[]) =>
|
|
232
|
-
|
|
228
|
+
name: "1D VaR 95%",
|
|
229
|
+
value: (rows: RiskSamplePoint[]) => {
|
|
230
|
+
const tail = historicalTail(rows.map((row) => row.value));
|
|
231
|
+
return tail == null ? null : 100 * tail.var;
|
|
232
|
+
},
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
235
|
id: "es",
|
|
236
|
-
|
|
237
|
-
value: (rows: RiskSamplePoint[]) =>
|
|
238
|
-
|
|
236
|
+
name: "1D expected shortfall",
|
|
237
|
+
value: (rows: RiskSamplePoint[]) => {
|
|
238
|
+
const tail = historicalTail(rows.map((row) => row.value));
|
|
239
|
+
return tail == null ? null : 100 * tail.expectedShortfall;
|
|
240
|
+
},
|
|
239
241
|
},
|
|
240
242
|
{
|
|
241
243
|
id: "tracking",
|
|
242
|
-
|
|
243
|
-
value: (rows: RiskSamplePoint[]) =>
|
|
244
|
-
|
|
244
|
+
name: "tracking error",
|
|
245
|
+
value: (rows: RiskSamplePoint[]) => {
|
|
246
|
+
const volatility = sampleVolatility(rows.map((row) => row.value - row.benchmark));
|
|
247
|
+
return volatility == null ? null : 100 * volatility;
|
|
248
|
+
},
|
|
245
249
|
},
|
|
246
250
|
];
|
|
247
|
-
|
|
251
|
+
}
|
|
252
|
+
const TAIL_IDS = new Set(["var", "es"]);
|
|
253
|
+
const finiteOrNull = (value: number | null) =>
|
|
254
|
+
value != null && Number.isFinite(value) ? value : null;
|
|
255
|
+
|
|
256
|
+
export function rollingBasketRisk(
|
|
257
|
+
sample: readonly RiskSamplePoint[],
|
|
258
|
+
window = RISK_WINDOW,
|
|
259
|
+
benchmark = "SPY",
|
|
260
|
+
): RiskStatistic[] {
|
|
261
|
+
if (!Number.isInteger(window) || window < 60)
|
|
262
|
+
throw new Error("Risk window must contain at least 60 daily sessions");
|
|
263
|
+
return basketRiskDefinitions(benchmark).map((definition) => {
|
|
248
264
|
const history = sample.map((point, index) => {
|
|
249
265
|
const rows = sample.slice(index - window + 1, index + 1);
|
|
250
266
|
const contiguous =
|
|
@@ -252,10 +268,9 @@ export function rollingBasketRisk(
|
|
|
252
268
|
rows.every(
|
|
253
269
|
(row, i) => i === 0 || row.startDateKey === rows[i - 1]!.dateKey,
|
|
254
270
|
);
|
|
255
|
-
const value = contiguous ? definition.value(rows) : null;
|
|
256
271
|
return {
|
|
257
272
|
date: point.dateKey,
|
|
258
|
-
value:
|
|
273
|
+
value: contiguous ? finiteOrNull(definition.value(rows)) : null,
|
|
259
274
|
};
|
|
260
275
|
});
|
|
261
276
|
const latest = history.at(-1),
|
|
@@ -263,7 +278,9 @@ export function rollingBasketRisk(
|
|
|
263
278
|
asOf = latest?.date ?? null;
|
|
264
279
|
return {
|
|
265
280
|
id: definition.id,
|
|
266
|
-
label: definition.
|
|
281
|
+
label: TAIL_IDS.has(definition.id)
|
|
282
|
+
? `${definition.name} (${window}D)`
|
|
283
|
+
: `${window}D ${definition.name}`,
|
|
267
284
|
value,
|
|
268
285
|
unit: "%" as const,
|
|
269
286
|
asOf,
|
|
@@ -276,6 +293,53 @@ export function rollingBasketRisk(
|
|
|
276
293
|
});
|
|
277
294
|
}
|
|
278
295
|
|
|
296
|
+
/**
|
|
297
|
+
* The same statistics over every paired session since `since` (a 13F filing
|
|
298
|
+
* date), measured from the last close on or before it: the trailing
|
|
299
|
+
* contiguous run of sessions that end after that day. Each row's history is
|
|
300
|
+
* the statistic as of each session in the run; there is no rolling sample to
|
|
301
|
+
* rank it against, so it has no percentile. VaR and expected shortfall need
|
|
302
|
+
* 60 sessions.
|
|
303
|
+
*/
|
|
304
|
+
export function sinceBasketRisk(
|
|
305
|
+
sample: readonly RiskSamplePoint[],
|
|
306
|
+
since: string,
|
|
307
|
+
benchmark = "SPY",
|
|
308
|
+
): RiskStatistic[] {
|
|
309
|
+
let first = sample.length;
|
|
310
|
+
while (
|
|
311
|
+
first > 0 &&
|
|
312
|
+
sample[first - 1]!.dateKey > since &&
|
|
313
|
+
(first === sample.length || sample[first]!.startDateKey === sample[first - 1]!.dateKey)
|
|
314
|
+
)
|
|
315
|
+
first -= 1;
|
|
316
|
+
const rows = sample.slice(first);
|
|
317
|
+
const start = rows[0]?.startDateKey ?? since;
|
|
318
|
+
const capitalized = (text: string) => `${text[0]!.toUpperCase()}${text.slice(1)}`;
|
|
319
|
+
return basketRiskDefinitions(benchmark).map((definition) => {
|
|
320
|
+
const history = rows.map((point, index) => ({
|
|
321
|
+
date: point.dateKey,
|
|
322
|
+
value: finiteOrNull(definition.value(rows.slice(0, index + 1))),
|
|
323
|
+
}));
|
|
324
|
+
const value = history.at(-1)?.value ?? null,
|
|
325
|
+
asOf = rows.at(-1)?.dateKey ?? null;
|
|
326
|
+
return {
|
|
327
|
+
id: definition.id,
|
|
328
|
+
label: TAIL_IDS.has(definition.id)
|
|
329
|
+
? `${definition.name} (since ${start})`
|
|
330
|
+
: `${capitalized(definition.name)} since ${start}`,
|
|
331
|
+
value,
|
|
332
|
+
unit: "%" as const,
|
|
333
|
+
asOf,
|
|
334
|
+
startDate: rows.length ? start : null,
|
|
335
|
+
// The sessions in the window, also when too few for a value (a tail estimate needs 60).
|
|
336
|
+
samples: rows.length,
|
|
337
|
+
rank: { ...historyStatistics([], value, { asOf: asOf ?? since }), percentile: null, rank: null },
|
|
338
|
+
history,
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
279
343
|
export function rollingBeta(
|
|
280
344
|
asset: readonly DatedReturn[],
|
|
281
345
|
factor: readonly DatedReturn[],
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { portfolioOptionGreeks } from "./risk-options";
|
|
2
2
|
import type { Portfolio, TickerRecord } from "../../../types/ticker";
|
|
3
|
-
import { formatNumber } from "../../../utils/format";
|
|
3
|
+
import { formatCurrency, formatNumber } from "../../../utils/format";
|
|
4
4
|
import { resolveCurrencyUnit } from "../../../utils/currency-units";
|
|
5
5
|
import {
|
|
6
6
|
getPortfolioPositionMetrics,
|
|
7
7
|
resolvePortfolioMarketValue,
|
|
8
|
-
} from "
|
|
8
|
+
} from "../../../portfolio/position-metrics";
|
|
9
9
|
import type { DatedReturn } from "./metrics";
|
|
10
10
|
import {
|
|
11
11
|
computeWeightedPortfolioReturns,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
regressReturns,
|
|
18
18
|
rollingBasketRisk,
|
|
19
19
|
rollingBeta,
|
|
20
|
+
sinceBasketRisk,
|
|
20
21
|
subtractReturns,
|
|
21
22
|
} from "./risk-math";
|
|
22
23
|
import {
|
|
@@ -97,7 +98,13 @@ export interface RiskDisplayRow {
|
|
|
97
98
|
interaction?: number;
|
|
98
99
|
/** Holdings rows only: why the holding is outside the covered basket. */
|
|
99
100
|
leftOut?: string;
|
|
101
|
+
/** VaR and expected shortfall only: the loss `value` is on the covered basket's current value (`amountBase`), in `amountCurrency`. */
|
|
102
|
+
amount?: number;
|
|
103
|
+
amountCurrency?: string;
|
|
104
|
+
amountBase?: number;
|
|
100
105
|
}
|
|
106
|
+
/** The tail-loss rows, which also read in money on the covered basket. */
|
|
107
|
+
const TAIL_ROW_IDS: ReadonlySet<string> = new Set(["var", "es"]);
|
|
101
108
|
/**
|
|
102
109
|
* Below half of market value the qualifying holdings are not most of the
|
|
103
110
|
* account, so a basket estimate would mostly describe something other than it;
|
|
@@ -124,6 +131,22 @@ export interface RiskShifts {
|
|
|
124
131
|
rates: number;
|
|
125
132
|
volatility: number;
|
|
126
133
|
}
|
|
134
|
+
/** The benchmark the basket's returns, active return and tracking error are measured against. */
|
|
135
|
+
const RISK_BENCHMARK = "SPY";
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The window the risk rows cover: the trailing 60 sessions, or, with `since:
|
|
139
|
+
* "filed"`, every session since the filing date of a portfolio imported from
|
|
140
|
+
* a 13F.
|
|
141
|
+
*/
|
|
142
|
+
export interface RiskWindowRequest {
|
|
143
|
+
since?: "filed";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Why a portfolio asked for risk since its filing shows the trailing window instead. */
|
|
147
|
+
export const sinceFallbackNote = (portfolio: Pick<Portfolio, "name">) =>
|
|
148
|
+
`"${portfolio.name}" was not imported from a 13F, so it has no filing date; the risk rows cover the trailing 60 sessions.`;
|
|
149
|
+
|
|
127
150
|
const DEFAULT_RISK_SHIFTS: RiskShifts = {
|
|
128
151
|
equity: -10,
|
|
129
152
|
rates: 100,
|
|
@@ -287,6 +310,7 @@ export function buildPortfolioRisk(
|
|
|
287
310
|
market: RiskMarketSnapshot,
|
|
288
311
|
evidence: PortfolioRiskEvidence | null = null,
|
|
289
312
|
shifts: RiskShifts = DEFAULT_RISK_SHIFTS,
|
|
313
|
+
window: RiskWindowRequest = {},
|
|
290
314
|
) {
|
|
291
315
|
if (
|
|
292
316
|
![shifts.equity, shifts.rates, shifts.volatility].every(Number.isFinite) ||
|
|
@@ -469,9 +493,15 @@ export function buildPortfolioRisk(
|
|
|
469
493
|
);
|
|
470
494
|
return (instrument && byId.get(riskInstrumentId(instrument))?.returns) || [];
|
|
471
495
|
};
|
|
472
|
-
const benchmark = proxy(
|
|
496
|
+
const benchmark = proxy(RISK_BENCHMARK),
|
|
473
497
|
sample = pairedReturns(basket, benchmark);
|
|
474
|
-
|
|
498
|
+
// Since the filing only for a portfolio that has one; any other keeps the trailing window and says why.
|
|
499
|
+
const filed = window.since === "filed" ? portfolio.importedFrom?.filed ?? null : null;
|
|
500
|
+
if (window.since === "filed" && !filed)
|
|
501
|
+
notes.push(sinceFallbackNote(portfolio));
|
|
502
|
+
const metrics = filed
|
|
503
|
+
? sinceBasketRisk(sample, filed, RISK_BENCHMARK)
|
|
504
|
+
: rollingBasketRisk(sample, undefined, RISK_BENCHMARK);
|
|
475
505
|
const factors = [
|
|
476
506
|
{ id: "market", label: "Market (SPY)", series: benchmark },
|
|
477
507
|
{
|
|
@@ -546,7 +576,9 @@ export function buildPortfolioRisk(
|
|
|
546
576
|
if (factor.samples === 0)
|
|
547
577
|
warnings.push(`${factor.label}: no matched factor history`);
|
|
548
578
|
if (sufficient && metrics.every((row) => row.value == null))
|
|
549
|
-
warnings.push(
|
|
579
|
+
warnings.push(filed
|
|
580
|
+
? `No completed session since the 13F filing on ${filed} yet.`
|
|
581
|
+
: "Fewer than 60 consecutive matched completed daily returns.");
|
|
550
582
|
const performance = evidence?.performance
|
|
551
583
|
? calculateAccountPerformance(evidence.performance)
|
|
552
584
|
: null;
|
|
@@ -565,12 +597,19 @@ export function buildPortfolioRisk(
|
|
|
565
597
|
: null;
|
|
566
598
|
warnings.push(...(greeks?.warnings ?? []));
|
|
567
599
|
const rows: Record<RiskView, RiskDisplayRow[]> = {
|
|
568
|
-
risk: metrics.map((row) =>
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
600
|
+
risk: metrics.map((row) => {
|
|
601
|
+
// VaR and expected shortfall are a one-day loss on the covered basket's current value, in the portfolio currency.
|
|
602
|
+
const tail = TAIL_ROW_IDS.has(row.id) && row.value != null && coverage.coveredValue > 0;
|
|
603
|
+
return {
|
|
604
|
+
...row,
|
|
605
|
+
percentile: row.rank.percentile,
|
|
606
|
+
// The method (price returns at fixed current weights) is in docs; the footer keeps room for coverage.
|
|
607
|
+
detail: filed && row.value == null && TAIL_ROW_IDS.has(row.id) ? `${row.samples} sessions; needs 60` : `${row.samples} sessions`,
|
|
608
|
+
...(tail
|
|
609
|
+
? { amount: (row.value! / 100) * coverage.coveredValue, amountCurrency: coverage.currency, amountBase: coverage.coveredValue }
|
|
610
|
+
: {}),
|
|
611
|
+
};
|
|
612
|
+
}),
|
|
574
613
|
factors: factors.map((row) => ({
|
|
575
614
|
...row,
|
|
576
615
|
percentile: row.rank.percentile,
|
|
@@ -762,6 +801,10 @@ export function buildPortfolioRisk(
|
|
|
762
801
|
warnings: [...new Set(warnings)],
|
|
763
802
|
notes,
|
|
764
803
|
fetchedAt: market.fetchedAt,
|
|
804
|
+
benchmark: RISK_BENCHMARK,
|
|
805
|
+
window: filed
|
|
806
|
+
? { kind: "since-filed" as const, filed, start: metrics[0]?.startDate ?? null, sessions: metrics[0]?.samples ?? 0 }
|
|
807
|
+
: { kind: "trailing" as const, sessions: 60 },
|
|
765
808
|
};
|
|
766
809
|
}
|
|
767
810
|
export type PortfolioRiskModel = ReturnType<typeof buildPortfolioRisk>;
|
|
@@ -770,6 +813,22 @@ export const riskValue = (row: RiskDisplayRow) =>
|
|
|
770
813
|
? "left out"
|
|
771
814
|
: row.value == null
|
|
772
815
|
? "--"
|
|
773
|
-
: `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}`;
|
|
816
|
+
: `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}${riskAmount(row)}`;
|
|
817
|
+
/** "220,476 USD basket": the value a tail loss in money is taken on, or null for a row without one. */
|
|
818
|
+
export function riskAmountBase(row: Pick<RiskDisplayRow, "amountBase" | "amountCurrency">): string | null {
|
|
819
|
+
return row.amountBase != null && Number.isFinite(row.amountBase) && row.amountCurrency
|
|
820
|
+
? `${formatNumber(row.amountBase, 0)} ${row.amountCurrency} basket`
|
|
821
|
+
: null;
|
|
822
|
+
}
|
|
823
|
+
/** A row's evidence with the basket a tail loss in money is taken on. */
|
|
824
|
+
export function riskEvidence(row: RiskDisplayRow): string {
|
|
825
|
+
const base = riskAmountBase(row);
|
|
826
|
+
return base ? `${row.detail}; of ${base}` : row.detail;
|
|
827
|
+
}
|
|
828
|
+
/** " ($5,735)": a tail loss in money beside its percent. */
|
|
829
|
+
function riskAmount(row: RiskDisplayRow): string {
|
|
830
|
+
if (row.amount == null || !Number.isFinite(row.amount) || !row.amountCurrency) return "";
|
|
831
|
+
return ` (${formatCurrency(row.amount, row.amountCurrency, 0)})`;
|
|
832
|
+
}
|
|
774
833
|
export const riskPercentile = (row: RiskDisplayRow) =>
|
|
775
834
|
row.percentile == null ? "--" : String(Math.round(row.percentile));
|