gloomberb 0.18.3 → 0.18.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 +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +32 -1
- package/src/account/auth-model.ts +7 -3
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +11 -6
- package/src/api-client/catalysts.ts +2 -1
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +98 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +182 -16
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +18 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +224 -26
- package/src/api-client/research-activity.ts +3 -10
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +96 -2
- package/src/app/keybindings/index.ts +3 -0
- package/src/app/keybindings/labels.ts +18 -1
- package/src/app/keybindings/resolve.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/broker-import.ts +43 -26
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +9 -2
- package/src/cli/commands/keybindings.ts +25 -2
- package/src/cli/commands/market.ts +1177 -278
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-chain.ts +59 -3
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +222 -61
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +82 -46
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +194 -48
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +21 -3
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +38 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +113 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +226 -50
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +123 -27
- package/src/cli/listing-arg.ts +316 -46
- package/src/cli/name-entries.ts +30 -18
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +193 -30
- package/src/cli/pane-functions/function-help.ts +76 -30
- package/src/cli/pane-functions/headless.ts +59 -12
- package/src/cli/pane-functions/index.ts +28 -19
- package/src/cli/pane-functions/market-session.ts +15 -5
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +10 -6
- package/src/cli/pane-functions/resolver.ts +64 -11
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +45 -4
- package/src/cli/report-tables.ts +75 -19
- package/src/cli/restore-plugins.ts +42 -15
- package/src/cli/result.ts +164 -23
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +198 -68
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +395 -20
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +7 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +314 -13
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +20 -4
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +17 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/panel/prompt-binding.ts +0 -8
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/alert.ts +1 -1
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +12 -6
- package/src/components/layout/header.tsx +33 -46
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +38 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-frame.tsx +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +10 -2
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +6 -4
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +123 -0
- package/src/docs/snapshot.json +422 -112
- package/src/i18n/es.ts +30 -13
- package/src/i18n/ja.ts +30 -13
- package/src/i18n/ko.ts +30 -13
- package/src/i18n/zh-cn.ts +30 -13
- package/src/i18n/zh-tw.ts +30 -13
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/coordinator/financials.ts +10 -2
- package/src/market-data/coordinator/index.ts +3 -1
- package/src/market-data/coordinator/quotes.ts +4 -2
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +81 -11
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/status.ts +16 -4
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/options-alternatives.ts +60 -0
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +25 -3
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +7 -2
- package/src/market-data/selectors.ts +3 -0
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/notifications/notification-log.ts +6 -4
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +34 -20
- package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
- package/src/plugins/builtin/alerts/cli.ts +533 -85
- package/src/plugins/builtin/alerts/command.ts +12 -10
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +119 -0
- package/src/plugins/builtin/alerts/format.ts +10 -3
- package/src/plugins/builtin/alerts/headless.ts +107 -41
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +92 -0
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +107 -30
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +61 -0
- package/src/plugins/builtin/alerts/metric-data.ts +70 -0
- package/src/plugins/builtin/alerts/metric-model.ts +175 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +130 -49
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +76 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +38 -12
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/alerts/types.ts +3 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +6 -3
- package/src/plugins/builtin/backtest/headless.ts +13 -8
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +24 -14
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +18 -3
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +66 -24
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +19 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +111 -24
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +51 -5
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +4 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
- package/src/plugins/builtin/chart-composer/headless.ts +266 -37
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +144 -30
- package/src/plugins/builtin/chart-composer/presets.ts +50 -15
- package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +31 -28
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +44 -31
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/command-suggestions.ts +92 -0
- package/src/plugins/builtin/chat/content/composer.tsx +13 -6
- package/src/plugins/builtin/chat/content/footer.tsx +6 -3
- package/src/plugins/builtin/chat/content/index.tsx +51 -22
- package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
- package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
- package/src/plugins/builtin/chat/index.tsx +23 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
- package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
- package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/plugin.tsx +1 -1
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +79 -23
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +5 -3
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +3 -2
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +18 -11
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +144 -27
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/figures.ts +72 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +144 -27
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +34 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +87 -28
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +104 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/charts.tsx +2 -2
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +20 -1
- package/src/plugins/builtin/exposure/pane.tsx +10 -5
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +12 -10
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +3 -3
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +20 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
- package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
- package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/headless.ts +7 -4
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +10 -4
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +51 -13
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +29 -8
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/breadth-pane.tsx +81 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +24 -10
- package/src/plugins/builtin/members/index.tsx +9 -9
- package/src/plugins/builtin/members/model.ts +23 -4
- package/src/plugins/builtin/members/pane.tsx +31 -14
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/analytics.ts +26 -2
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +5 -2
- package/src/plugins/builtin/options/strike-window.ts +2 -1
- package/src/plugins/builtin/options/table.ts +1 -7
- package/src/plugins/builtin/options/view.tsx +30 -13
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-positioning/client.ts +19 -0
- package/src/plugins/builtin/options-positioning/headless.ts +54 -14
- package/src/plugins/builtin/options-positioning/index.tsx +3 -3
- package/src/plugins/builtin/options-positioning/model.ts +47 -8
- package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +36 -15
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +14 -9
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +168 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +49 -26
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +7 -4
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +4 -1
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +80 -13
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/index.ts +24 -1
- package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
- package/src/plugins/builtin/scanner/live-feed.ts +168 -0
- package/src/plugins/builtin/scanner/live-headless.ts +114 -0
- package/src/plugins/builtin/scanner/live-model.ts +351 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
- package/src/plugins/builtin/scanner/live-track.ts +186 -0
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/macro-releases.ts +65 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +21 -0
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
- package/src/plugins/builtin/shared/volatility/pricing.ts +7 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +11 -6
- package/src/plugins/builtin/themes/model.ts +15 -5
- package/src/plugins/builtin/themes/pane.tsx +27 -8
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +14 -4
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +7 -4
- package/src/plugins/builtin/vol-surface/headless.ts +71 -13
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +26 -9
- package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/volatility/pane.tsx +2 -2
- package/src/plugins/builtin/volatility/series.ts +26 -0
- package/src/plugins/builtin/world-indices/footer.ts +1 -1
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +15 -9
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +15 -13
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +15 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +5 -55
- package/src/renderers/browser/main.tsx +30 -60
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/styles.css +76 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +36 -2
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/app-name.ts +17 -0
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +1 -1
- package/src/renderers/opentui/toast-host.tsx +71 -43
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +16 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/batches.ts +10 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +58 -15
- package/src/sources/provider-router/index.ts +146 -10
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +67 -17
- package/src/sync/core-contributors.ts +46 -14
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +11 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/company-name.ts +59 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-venues.ts +23 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +111 -33
- package/src/tickers/search/ranking.ts +64 -5
- package/src/tickers/search/types.ts +5 -0
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +315 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/field-catalog.ts +1 -3
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +173 -10
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/hooks.ts +1 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/price-units.ts +72 -2
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +161 -0
- package/src/time-series/resolve.ts +185 -1587
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +242 -0
- package/src/time-series/spec.ts +13 -7
- package/src/time-series/studies.ts +377 -82
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/transforms.ts +1 -0
- package/src/time-series/types.ts +34 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +23 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +145 -8
- package/src/types/headless.ts +117 -9
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +66 -9
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +180 -0
- package/src/updater/index.ts +10 -5
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +89 -5
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +86 -0
- package/src/utils/option-expiry.ts +186 -7
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +23 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
- package/src/renderers/browser/first-screen.ts +0 -193
|
@@ -20,11 +20,23 @@ import {
|
|
|
20
20
|
concentration,
|
|
21
21
|
pairedReturns,
|
|
22
22
|
regressReturns,
|
|
23
|
+
RISK_TAIL_CONFIDENCE,
|
|
24
|
+
RISK_TAIL_MINIMUM,
|
|
23
25
|
rollingBasketRisk,
|
|
24
26
|
rollingBeta,
|
|
25
27
|
sinceBasketRisk,
|
|
26
28
|
subtractReturns,
|
|
27
29
|
} from "./risk-math";
|
|
30
|
+
import {
|
|
31
|
+
repriceBook,
|
|
32
|
+
RISK_SHOCK_LIMITS,
|
|
33
|
+
riskCashLines,
|
|
34
|
+
type RiskAssetShift,
|
|
35
|
+
type RiskBookLine,
|
|
36
|
+
type RiskCashLine,
|
|
37
|
+
type RiskFxShift,
|
|
38
|
+
type RiskRepricing,
|
|
39
|
+
} from "./risk-book";
|
|
28
40
|
import {
|
|
29
41
|
calculateAccountPerformance,
|
|
30
42
|
calculateBrinson,
|
|
@@ -69,32 +81,51 @@ interface PortfolioRiskHolding {
|
|
|
69
81
|
/** Why the holding is outside the basket; null when it qualifies. */
|
|
70
82
|
leftOut: string | null;
|
|
71
83
|
}
|
|
72
|
-
/** A holding outside the basket, with its share of
|
|
84
|
+
/** A holding or a currency's cash outside the basket, with its share of the book when one is known. */
|
|
73
85
|
interface RiskLeftOut {
|
|
74
86
|
id: string;
|
|
75
87
|
symbol: string;
|
|
76
88
|
reason: string;
|
|
77
89
|
value: number | null;
|
|
78
90
|
share: number | null;
|
|
91
|
+
/** Set on a currency's cash, which is never in the basket and does not make a report incomplete. */
|
|
92
|
+
cash?: true;
|
|
93
|
+
}
|
|
94
|
+
/** One currency of the book's cash, valued in the account currency. */
|
|
95
|
+
interface RiskCashHolding extends RiskCashLine {
|
|
96
|
+
id: string;
|
|
97
|
+
/** "TRY cash". */
|
|
98
|
+
symbol: string;
|
|
99
|
+
/** Signed, in the portfolio currency at the current rate; null without a rate. */
|
|
100
|
+
value: number | null;
|
|
79
101
|
}
|
|
80
102
|
/** What the basket views cover of the account. */
|
|
81
103
|
export interface RiskCoverage {
|
|
82
104
|
currency: string;
|
|
83
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Gross current value of the book in the portfolio currency: every holding
|
|
107
|
+
* that has one, and the cash.
|
|
108
|
+
*/
|
|
84
109
|
marketValue: number;
|
|
85
110
|
coveredValue: number;
|
|
86
|
-
/** Covered share of
|
|
111
|
+
/** Covered share of the book, cash included; an upper bound while `unvalued` lines have no value. */
|
|
87
112
|
share: number | null;
|
|
113
|
+
/** Gross value of the holdings alone, and the covered share of it, which `sufficient` reads. */
|
|
114
|
+
holdingsValue?: number;
|
|
115
|
+
holdingsShare?: number | null;
|
|
116
|
+
/** Gross value of the cash in the portfolio currency. */
|
|
117
|
+
cashValue?: number;
|
|
88
118
|
holdings: number;
|
|
89
119
|
/** Holdings that qualify for the basket. */
|
|
90
120
|
covered: number;
|
|
91
121
|
/** Covered holdings whose returns were converted to USD from their listing currency. */
|
|
92
122
|
converted: number;
|
|
123
|
+
/** Holdings and cash lines nothing values. */
|
|
93
124
|
unvalued: number;
|
|
94
125
|
minimumShare: number;
|
|
95
|
-
/** The basket views estimate only when qualifying holdings reach the minimum share. */
|
|
126
|
+
/** The basket views estimate only when qualifying holdings reach the minimum share of the holdings, cash aside. */
|
|
96
127
|
sufficient: boolean;
|
|
97
|
-
/**
|
|
128
|
+
/** Holdings and cash, largest first. */
|
|
98
129
|
leftOut: RiskLeftOut[];
|
|
99
130
|
}
|
|
100
131
|
export interface RiskDisplayRow {
|
|
@@ -112,10 +143,16 @@ export interface RiskDisplayRow {
|
|
|
112
143
|
interaction?: number;
|
|
113
144
|
/** Holdings rows only: why the holding is outside the covered basket. */
|
|
114
145
|
leftOut?: string;
|
|
115
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* A loss or change in money beside `value`, in `amountCurrency`: VaR and
|
|
148
|
+
* expected shortfall on the covered basket's current value (`amountBase`),
|
|
149
|
+
* a shock on the repriced line.
|
|
150
|
+
*/
|
|
116
151
|
amount?: number;
|
|
117
152
|
amountCurrency?: string;
|
|
118
153
|
amountBase?: number;
|
|
154
|
+
/** What a tail loss in money is taken on: the basket's value and share of the book, and what it leaves out. */
|
|
155
|
+
basis?: string;
|
|
119
156
|
}
|
|
120
157
|
/** The tail-loss rows, which also read in money on the covered basket. */
|
|
121
158
|
const TAIL_ROW_IDS: ReadonlySet<string> = new Set(["var", "es"]);
|
|
@@ -144,6 +181,9 @@ export interface RiskShifts {
|
|
|
144
181
|
equity: number;
|
|
145
182
|
rates: number;
|
|
146
183
|
volatility: number;
|
|
184
|
+
/** Currencies' moves against USD and holdings' own price moves, applied together to every line of the book. */
|
|
185
|
+
fx?: RiskFxShift[];
|
|
186
|
+
assets?: RiskAssetShift[];
|
|
147
187
|
}
|
|
148
188
|
/** The benchmark the basket's returns, active return and tracking error are measured against. */
|
|
149
189
|
const RISK_BENCHMARK = "SPY";
|
|
@@ -330,6 +370,22 @@ function outsideValue(
|
|
|
330
370
|
const value = resolvePortfolioMarketValue(metrics, unit != null && Number.isFinite(unit) ? unit : null)?.gross;
|
|
331
371
|
return value != null && Number.isFinite(value) ? value : null;
|
|
332
372
|
}
|
|
373
|
+
/** Cash in the portfolio currency at the load's rates (USD per unit); null without a rate. */
|
|
374
|
+
function cashValue(line: RiskCashLine, accountCurrency: string, rates: Readonly<Record<string, number>>): number | null {
|
|
375
|
+
const unit = resolveCurrencyUnit(line.currency);
|
|
376
|
+
if (unit.currency === accountCurrency) return line.amount / unit.divisor;
|
|
377
|
+
const usd = unit.currency === "USD" ? 1 : rates[unit.currency];
|
|
378
|
+
const account = accountCurrency === "USD" ? 1 : rates[accountCurrency];
|
|
379
|
+
const value = usd != null && usd > 0 && account != null && account > 0 ? (line.amount / unit.divisor) * usd / account : Number.NaN;
|
|
380
|
+
return Number.isFinite(value) ? value : null;
|
|
381
|
+
}
|
|
382
|
+
/** Why a currency's cash is outside the basket, and for one in another currency, what moves its value. */
|
|
383
|
+
function cashReason(line: RiskCashLine, accountCurrency: string): string {
|
|
384
|
+
const own = resolveCurrencyUnit(line.currency).currency;
|
|
385
|
+
return own === accountCurrency
|
|
386
|
+
? "Cash is outside the equity basket"
|
|
387
|
+
: `Cash is outside the equity basket; its ${accountCurrency} value moves with ${own}`;
|
|
388
|
+
}
|
|
333
389
|
/** USD returns in the account currency, or none with the reason its daily closes cannot convert them. */
|
|
334
390
|
function accountReturns(returns: readonly DatedReturn[], account: AccountFx): { returns: DatedReturn[]; error: string | null } {
|
|
335
391
|
if (account.error) return { returns: [], error: account.error };
|
|
@@ -355,67 +411,84 @@ const shareText = (share: number) =>
|
|
|
355
411
|
share < 0.001 ? "under 0.1%" : `${(share * 100).toFixed(1)}%`;
|
|
356
412
|
const convertedText = (coverage: RiskCoverage) =>
|
|
357
413
|
coverage.converted ? `${holdingCount(coverage.converted)} converted from local currency` : null;
|
|
414
|
+
/** Whole percents of shares that add up to one, the remainders handed out largest first, so a line of them adds up to 100. */
|
|
415
|
+
function wholePercents(shares: readonly number[]): number[] {
|
|
416
|
+
const raw = shares.map((share) => share * 100);
|
|
417
|
+
const whole = raw.map((value) => Math.floor(value + 1e-9));
|
|
418
|
+
let left = Math.round(raw.reduce((sum, value) => sum + value, 0)) - whole.reduce((sum, value) => sum + value, 0);
|
|
419
|
+
const order = raw.map((_, index) => index).sort((a, b) => raw[b]! - whole[b]! - (raw[a]! - whole[a]!));
|
|
420
|
+
for (const index of order) {
|
|
421
|
+
if (left <= 0) break;
|
|
422
|
+
whole[index]! += 1;
|
|
423
|
+
left -= 1;
|
|
424
|
+
}
|
|
425
|
+
return whole;
|
|
426
|
+
}
|
|
427
|
+
const percentText = (percent: number, share: number) => (percent > 0 ? `${percent}%` : share > 0 ? "under 1%" : "0%");
|
|
428
|
+
/** Lines the coverage line names before "N more". */
|
|
429
|
+
const NAMED_EXCLUSIONS = 2;
|
|
358
430
|
/**
|
|
359
|
-
* "
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
431
|
+
* "basket 48,286 USD = 72% of book; left out: BTC-USD 10%, TRY cash 18%": the
|
|
432
|
+
* value the basket views estimate on, its share of the whole book (every
|
|
433
|
+
* holding and the cash), and what it leaves out, largest first, the percents
|
|
434
|
+
* adding up to 100. Past three lines left out the rest read "7 more 14%". The
|
|
435
|
+
* basket's share reads "at most" while a line has no value, and a line nothing
|
|
436
|
+
* values is named with "value unknown". Converted listings are counted after.
|
|
363
437
|
*/
|
|
364
|
-
export function
|
|
438
|
+
export function riskCoverageLine(coverage: RiskCoverage | undefined): string | null {
|
|
365
439
|
if (!coverage) return null;
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
440
|
+
const named = coverage.leftOut.length <= NAMED_EXCLUSIONS + 1 ? coverage.leftOut : coverage.leftOut.slice(0, NAMED_EXCLUSIONS);
|
|
441
|
+
const rest = coverage.leftOut.slice(named.length);
|
|
442
|
+
const restShare = rest.reduce((sum, row) => sum + (row.share ?? 0), 0);
|
|
443
|
+
const shares = [coverage.share ?? 0, ...named.map((row) => row.share ?? 0), ...(rest.length ? [restShare] : [])];
|
|
444
|
+
const percents = wholePercents(shares);
|
|
445
|
+
const basket = `basket ${formatNumber(coverage.coveredValue, 0)} ${coverage.currency}${coverage.share == null ? "" : ` = ${coverage.unvalued ? "at most " : ""}${percentText(percents[0]!, shares[0]!)} of book`}`;
|
|
446
|
+
const items = [
|
|
447
|
+
...named.map((row, index) => `${row.symbol} ${row.share == null ? "value unknown" : percentText(percents[index + 1]!, row.share)}`),
|
|
448
|
+
...(rest.length ? [`${rest.length} more${restShare > 0 ? ` ${percentText(percents.at(-1)!, restShare)}` : ""}`] : []),
|
|
449
|
+
];
|
|
450
|
+
return [`${basket}${items.length ? `; left out: ${items.join(", ")}` : ""}`, convertedText(coverage)].filter(Boolean).join(" · ");
|
|
372
451
|
}
|
|
373
|
-
/**
|
|
374
|
-
const
|
|
452
|
+
/** Whether the basket leaves out a holding, which makes a report incomplete; cash never is in it. */
|
|
453
|
+
export const riskHoldingsLeftOut = (coverage: RiskCoverage) => coverage.leftOut.some((row) => !row.cash);
|
|
375
454
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
* covered percent, so the two always add to 100; it reads "at least" while a
|
|
380
|
-
* holding has no value, and a holding nothing values is named with "value
|
|
381
|
-
* unknown". Null when every holding is in the basket.
|
|
455
|
+
* "historical, 1-day, 95%, 60 daily returns": how VaR and expected shortfall
|
|
456
|
+
* are estimated, from the sample they read; without an estimate, how many
|
|
457
|
+
* returns it needs.
|
|
382
458
|
*/
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (coverage.share == null || !coverage.leftOut.some((row) => (row.share ?? 0) > 0))
|
|
389
|
-
return `excludes ${names}, value unknown`;
|
|
390
|
-
const percent = 100 - coveragePercent(coverage.share);
|
|
391
|
-
return `excludes ${names}, ${coverage.unvalued ? "at least " : ""}${percent > 0 ? `${percent}%` : "under 1%"} of value`;
|
|
392
|
-
}
|
|
393
|
-
/** The line that leads what the basket views cover: what is left out, then what converted from local currency. */
|
|
394
|
-
export function riskCoverageHeadline(coverage: RiskCoverage | undefined): string | null {
|
|
395
|
-
if (!coverage) return null;
|
|
396
|
-
return [riskExclusionText(coverage), convertedText(coverage)].filter(Boolean).join(" · ") || null;
|
|
459
|
+
function riskTailMethod(samples: number, estimated: boolean): string {
|
|
460
|
+
const head = `historical, 1-day, ${Math.round(RISK_TAIL_CONFIDENCE * 100)}%`;
|
|
461
|
+
return estimated
|
|
462
|
+
? `${head}, ${samples} daily returns`
|
|
463
|
+
: `${head}; needs ${RISK_TAIL_MINIMUM} daily returns${samples ? `, has ${samples}` : ""}`;
|
|
397
464
|
}
|
|
465
|
+
/** The unit of the concentration shares, which divide the priced holdings' value, cash aside. */
|
|
466
|
+
export const HOLDINGS_SHARE_UNIT = "% holdings";
|
|
398
467
|
/** A reason reads as the tail of a sentence, so its first word loses its capital unless it is an acronym ("FX", "USD"). */
|
|
399
468
|
const lowerFirst = (text: string) => (/^[A-Z][a-z]/.test(text) ? text[0]!.toLowerCase() + text.slice(1) : text);
|
|
400
|
-
/** One sentence per left
|
|
469
|
+
/** One sentence per holding or cash left out, largest first, naming it and why it is out. */
|
|
401
470
|
export function riskCoverageNotices(coverage: RiskCoverage | undefined): string[] {
|
|
402
471
|
if (!coverage?.leftOut.length) return [];
|
|
403
472
|
return coverage.leftOut.map(
|
|
404
473
|
(row) =>
|
|
405
|
-
`${row.symbol} (${row.share == null ? "value unknown" : `${shareText(row.share)} of
|
|
474
|
+
`${row.symbol} (${row.share == null ? "value unknown" : `${shareText(row.share)} of the book`}) is excluded from the risk estimate: ${lowerFirst(row.reason.replace(/\.$/, ""))}.`,
|
|
406
475
|
);
|
|
407
476
|
}
|
|
408
|
-
/** Why the basket views show no estimate, when too little of the
|
|
477
|
+
/** Why the basket views show no estimate, when too little of the holdings qualifies. */
|
|
409
478
|
export function riskCoverageShortfall(
|
|
410
479
|
coverage: RiskCoverage | undefined,
|
|
411
480
|
): { title: string; message: string } | null {
|
|
412
481
|
if (!coverage || coverage.sufficient) return null;
|
|
413
482
|
if (!coverage.holdings) return { title: "No holdings in this portfolio.", message: "" };
|
|
414
483
|
const minimum = Math.round(coverage.minimumShare * 100);
|
|
484
|
+
// A share of what is invested: cash is no holding the basket could take.
|
|
485
|
+
const share = coverage.holdingsShare !== undefined ? coverage.holdingsShare : coverage.share;
|
|
486
|
+
const base = coverage.holdingsValue ?? coverage.marketValue;
|
|
415
487
|
const reasons = new Map<string, { share: number; count: number }>();
|
|
416
488
|
for (const row of coverage.leftOut) {
|
|
489
|
+
if (row.cash) continue;
|
|
417
490
|
const entry = reasons.get(row.reason) ?? { share: 0, count: 0 };
|
|
418
|
-
entry.share += row.
|
|
491
|
+
entry.share += row.value != null && base > 0 ? row.value / base : 0;
|
|
419
492
|
entry.count += 1;
|
|
420
493
|
reasons.set(row.reason, entry);
|
|
421
494
|
}
|
|
@@ -423,14 +496,51 @@ export function riskCoverageShortfall(
|
|
|
423
496
|
([, left], [, right]) => right.share - left.share || right.count - left.count,
|
|
424
497
|
)[0] ?? [];
|
|
425
498
|
return {
|
|
426
|
-
title: coverage.covered === 0 ||
|
|
427
|
-
? `No holding qualifies for basket estimates, which need ${minimum}% of
|
|
428
|
-
: `Qualifying holdings cover ${coverage.unvalued ? "at most " : ""}${coveragePercent(
|
|
499
|
+
title: coverage.covered === 0 || share == null
|
|
500
|
+
? `No holding qualifies for basket estimates, which need ${minimum}% of the holdings' value.`
|
|
501
|
+
: `Qualifying holdings cover ${coverage.unvalued ? "at most " : ""}${coveragePercent(share)}% of the holdings' value; basket estimates need ${minimum}%.`,
|
|
429
502
|
message: reason
|
|
430
|
-
? `Most of what is left out: ${reason}${largest!.share > 0 ? ` (${shareText(largest!.share)} of
|
|
503
|
+
? `Most of what is left out: ${reason}${largest!.share > 0 ? ` (${shareText(largest!.share)} of the holdings' value)` : ""}.`
|
|
431
504
|
: "",
|
|
432
505
|
};
|
|
433
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* The stress rows of the given shocks: each line they move, its change in
|
|
509
|
+
* percent of its own value and in money, then the book's total, in percent of
|
|
510
|
+
* its net value with the cash.
|
|
511
|
+
*/
|
|
512
|
+
/** The Stress row that totals the currency and price shocks over the whole book. */
|
|
513
|
+
export const BOOK_TOTAL_ROW_ID = "shock:book";
|
|
514
|
+
/** A Stress row of the currency and price shocks, which reprice the book without the basket. */
|
|
515
|
+
export function isShockRow(row: Pick<RiskDisplayRow, "id">): boolean {
|
|
516
|
+
return row.id.startsWith("shock:");
|
|
517
|
+
}
|
|
518
|
+
function repricingRows(repricing: RiskRepricing, currency: string, asOf: string): RiskDisplayRow[] {
|
|
519
|
+
const money = (value: number) => `${formatNumber(value, 0)} ${currency}`;
|
|
520
|
+
return [
|
|
521
|
+
...repricing.lines.map((line) => ({
|
|
522
|
+
id: `shock:${line.id}`,
|
|
523
|
+
label: line.label,
|
|
524
|
+
value: line.percent,
|
|
525
|
+
unit: "%",
|
|
526
|
+
percentile: null,
|
|
527
|
+
asOf,
|
|
528
|
+
detail: `${line.shocks.join(", ")}; ${line.before == null || line.after == null ? "value unknown, not repriced" : `${money(line.before)} to ${money(line.after)}`}`,
|
|
529
|
+
...(line.change != null ? { amount: line.change, amountCurrency: currency } : {}),
|
|
530
|
+
})),
|
|
531
|
+
{
|
|
532
|
+
id: BOOK_TOTAL_ROW_ID,
|
|
533
|
+
label: "Book total",
|
|
534
|
+
value: repricing.percent,
|
|
535
|
+
unit: "%",
|
|
536
|
+
percentile: null,
|
|
537
|
+
asOf,
|
|
538
|
+
detail: `${repricing.scenario}; of ${money(repricing.bookValue)} book, cash included${repricing.unvalued.length ? `; ${repricing.unvalued.join(", ")} without a value not repriced` : ""}`,
|
|
539
|
+
amount: repricing.change,
|
|
540
|
+
amountCurrency: currency,
|
|
541
|
+
},
|
|
542
|
+
];
|
|
543
|
+
}
|
|
434
544
|
/**
|
|
435
545
|
* Basket estimates use the holdings that qualify, reweighted among themselves.
|
|
436
546
|
* Every other holding stays listed with its reason and counts in the market
|
|
@@ -443,6 +553,8 @@ export function buildPortfolioRisk(
|
|
|
443
553
|
evidence: PortfolioRiskEvidence | null = null,
|
|
444
554
|
shifts: RiskShifts = DEFAULT_RISK_SHIFTS,
|
|
445
555
|
window: RiskWindowRequest = {},
|
|
556
|
+
/** The book's cash by currency; the portfolio's own entry when left out. */
|
|
557
|
+
cash: readonly RiskCashLine[] = riskCashLines(portfolio, null),
|
|
446
558
|
) {
|
|
447
559
|
if (
|
|
448
560
|
![shifts.equity, shifts.rates, shifts.volatility].every(Number.isFinite) ||
|
|
@@ -450,7 +562,9 @@ export function buildPortfolioRisk(
|
|
|
450
562
|
Math.abs(shifts.equity) > 100 ||
|
|
451
563
|
Math.abs(shifts.rates) > 500 ||
|
|
452
564
|
shifts.volatility < -50 ||
|
|
453
|
-
shifts.volatility > 100
|
|
565
|
+
shifts.volatility > 100 ||
|
|
566
|
+
[...(shifts.fx ?? []), ...(shifts.assets ?? [])].some((shift) =>
|
|
567
|
+
!Number.isFinite(shift.percent) || shift.percent < RISK_SHOCK_LIMITS.minimum || shift.percent > RISK_SHOCK_LIMITS.maximum)
|
|
454
568
|
)
|
|
455
569
|
throw new Error("Stress shifts exceed the supported range");
|
|
456
570
|
if (
|
|
@@ -580,33 +694,59 @@ export function buildPortfolioRisk(
|
|
|
580
694
|
leftOut,
|
|
581
695
|
};
|
|
582
696
|
});
|
|
697
|
+
// Each currency's cash once, valued in the portfolio currency.
|
|
698
|
+
const cashTotals = new Map<string, number>();
|
|
699
|
+
for (const line of cash)
|
|
700
|
+
if (Number.isFinite(line.amount) && line.amount !== 0)
|
|
701
|
+
cashTotals.set(line.currency, (cashTotals.get(line.currency) ?? 0) + line.amount);
|
|
702
|
+
const cashHoldings: RiskCashHolding[] = [...cashTotals].map(([currency, amount]) => ({
|
|
703
|
+
id: `cash:${currency}`,
|
|
704
|
+
symbol: `${currency} cash`,
|
|
705
|
+
currency,
|
|
706
|
+
amount,
|
|
707
|
+
value: cashValue({ currency, amount }, portfolio.currency, rates),
|
|
708
|
+
}));
|
|
583
709
|
const qualifying = holdings.filter((row) => row.leftOut == null);
|
|
584
710
|
const valued = holdings.filter((row) => row.marketValue != null);
|
|
585
|
-
const
|
|
711
|
+
const holdingsValue = valued.reduce((sum, row) => sum + row.marketValue!, 0);
|
|
712
|
+
// Cash counts in the book the coverage is a share of, at its gross value as a short does.
|
|
713
|
+
const cashGross = cashHoldings.reduce((sum, row) => sum + Math.abs(row.value ?? 0), 0);
|
|
714
|
+
const marketValue = holdingsValue + cashGross;
|
|
586
715
|
const coveredValue = qualifying.reduce((sum, row) => sum + row.value!, 0);
|
|
587
716
|
const share = marketValue > 0 ? coveredValue / marketValue : null;
|
|
588
|
-
|
|
717
|
+
// Whether the basket is most of what is invested: cash is no holding the basket could have taken.
|
|
718
|
+
const holdingsShare = holdingsValue > 0 ? coveredValue / holdingsValue : null;
|
|
719
|
+
const sufficient = qualifying.length > 0 && holdingsShare != null && holdingsShare >= RISK_MIN_COVERAGE;
|
|
720
|
+
const bookShare = (value: number | null) => value != null && marketValue > 0 ? value / marketValue : null;
|
|
589
721
|
const coverage: RiskCoverage = {
|
|
590
722
|
currency: portfolio.currency,
|
|
591
723
|
marketValue,
|
|
592
724
|
coveredValue,
|
|
593
725
|
share,
|
|
726
|
+
holdingsValue,
|
|
727
|
+
holdingsShare,
|
|
728
|
+
cashValue: cashGross,
|
|
594
729
|
holdings: holdings.length,
|
|
595
730
|
covered: qualifying.length,
|
|
596
731
|
converted: qualifying.filter((row) => row.convertedFrom != null).length,
|
|
597
|
-
unvalued: holdings.length - valued.length,
|
|
732
|
+
unvalued: holdings.length - valued.length + cashHoldings.filter((row) => row.value == null).length,
|
|
598
733
|
minimumShare: RISK_MIN_COVERAGE,
|
|
599
734
|
sufficient,
|
|
600
|
-
leftOut:
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
735
|
+
leftOut: [
|
|
736
|
+
...holdings
|
|
737
|
+
.filter((row) => row.leftOut != null)
|
|
738
|
+
.map((row): RiskLeftOut => ({
|
|
739
|
+
id: row.id,
|
|
740
|
+
symbol: row.symbol,
|
|
741
|
+
reason: row.leftOut!,
|
|
742
|
+
value: row.marketValue,
|
|
743
|
+
share: bookShare(row.marketValue),
|
|
744
|
+
})),
|
|
745
|
+
...cashHoldings.map((row): RiskLeftOut => {
|
|
746
|
+
const value = row.value == null ? null : Math.abs(row.value);
|
|
747
|
+
return { id: row.id, symbol: row.symbol, reason: cashReason(row, portfolio.currency), value, share: bookShare(value), cash: true };
|
|
748
|
+
}),
|
|
749
|
+
].sort((a, b) => (b.value ?? -1) - (a.value ?? -1)),
|
|
610
750
|
};
|
|
611
751
|
// Weights renormalize over the covered basket; nothing outside it is approximated into it.
|
|
612
752
|
const members = sufficient ? qualifying : [];
|
|
@@ -774,6 +914,26 @@ export function buildPortfolioRisk(
|
|
|
774
914
|
value: regression ? regression.beta * stress.shock * 100 : null,
|
|
775
915
|
};
|
|
776
916
|
});
|
|
917
|
+
// The given currency and price shocks reprice every line of the book, cash included, at once.
|
|
918
|
+
const bookLines: RiskBookLine[] = [
|
|
919
|
+
...holdings.map((row) => ({
|
|
920
|
+
id: row.id,
|
|
921
|
+
label: row.symbol,
|
|
922
|
+
currency: row.convertedFrom ?? row.currency,
|
|
923
|
+
// A holding outside the USD marks keeps its gross value, signed as its position is.
|
|
924
|
+
value: row.value ?? (row.marketValue == null ? null : row.quantity < 0 ? -row.marketValue : row.marketValue),
|
|
925
|
+
listing: { symbol: row.symbol, exchange: row.exchange },
|
|
926
|
+
})),
|
|
927
|
+
...cashHoldings.map((row) => ({ id: row.id, label: row.symbol, currency: row.currency, value: row.value, listing: null })),
|
|
928
|
+
];
|
|
929
|
+
const repricing = repriceBook(bookLines, portfolio.currency, shifts.fx, shifts.assets);
|
|
930
|
+
if (repricing?.unmatched.length) {
|
|
931
|
+
const held = holdings.map((row) => row.symbol);
|
|
932
|
+
for (const { kind, name } of repricing.unmatched)
|
|
933
|
+
notes.push(kind === "currency"
|
|
934
|
+
? `Nothing in "${portfolio.name}" moves with ${name} against USD, so the ${name} shift changes nothing.`
|
|
935
|
+
: `"${portfolio.name}" holds no ${name}, so its shift changes nothing${held.length ? `; it holds ${held.slice(0, 8).join(", ")}${held.length > 8 ? ` and ${held.length - 8} more` : ""}` : ""}.`);
|
|
936
|
+
}
|
|
777
937
|
if (sufficient)
|
|
778
938
|
for (const factor of factors)
|
|
779
939
|
if (factor.samples === 0)
|
|
@@ -806,10 +966,15 @@ export function buildPortfolioRisk(
|
|
|
806
966
|
return {
|
|
807
967
|
...row,
|
|
808
968
|
percentile: row.rank.percentile,
|
|
809
|
-
// The method (price returns, bought and held or at fixed current weights) is in docs
|
|
810
|
-
detail:
|
|
969
|
+
// The tail rows name how they are estimated; the other rows' method (price returns, bought and held or at fixed current weights) is in docs.
|
|
970
|
+
detail: TAIL_ROW_IDS.has(row.id) ? riskTailMethod(row.samples, row.value != null) : `${row.samples} sessions`,
|
|
811
971
|
...(tail
|
|
812
|
-
? {
|
|
972
|
+
? {
|
|
973
|
+
amount: (row.value! / 100) * coverage.coveredValue,
|
|
974
|
+
amountCurrency: coverage.currency,
|
|
975
|
+
amountBase: coverage.coveredValue,
|
|
976
|
+
basis: riskCoverageLine(coverage) ?? undefined,
|
|
977
|
+
}
|
|
813
978
|
: {}),
|
|
814
979
|
};
|
|
815
980
|
}),
|
|
@@ -818,21 +983,48 @@ export function buildPortfolioRisk(
|
|
|
818
983
|
percentile: row.rank.percentile,
|
|
819
984
|
detail: `${row.samples} sessions; R² ${row.regression?.rSquared?.toFixed(2) ?? "--"}; independent ETF proxy`,
|
|
820
985
|
})),
|
|
821
|
-
// Largest current value first, left-out holdings in place; unvalued ones last.
|
|
822
|
-
holdings: [
|
|
823
|
-
.
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
986
|
+
// Largest current value first, left-out holdings and each currency's cash in place; unvalued ones last.
|
|
987
|
+
holdings: [
|
|
988
|
+
...holdings.map((row) => ({
|
|
989
|
+
size: row.marketValue,
|
|
990
|
+
row: {
|
|
991
|
+
id: row.id,
|
|
992
|
+
label: row.symbol,
|
|
993
|
+
value: row.weight == null ? null : row.weight * 100,
|
|
994
|
+
unit: "% basket",
|
|
995
|
+
percentile: null,
|
|
996
|
+
asOf: row.priceAsOf,
|
|
997
|
+
detail: row.leftOut
|
|
998
|
+
? row.leftOut
|
|
999
|
+
: `${row.quantity} shares; ${formatNumber(row.value ?? undefined)} ${portfolio.currency}${row.markSource === "close" || row.markSource === "regular-close" ? ` at ${row.priceAsOf} close` : ""}${row.convertedFrom ? ` from ${row.convertedFrom} at daily FX` : ""}; history ${row.historyAsOf}`,
|
|
1000
|
+
...(row.leftOut ? { leftOut: row.leftOut } : {}),
|
|
1001
|
+
} as RiskDisplayRow,
|
|
1002
|
+
})),
|
|
1003
|
+
...cashHoldings.map((row) => {
|
|
1004
|
+
const amount = `${formatNumber(row.amount)} ${row.currency}`;
|
|
1005
|
+
const foreign = resolveCurrencyUnit(row.currency).currency !== portfolio.currency;
|
|
1006
|
+
return {
|
|
1007
|
+
size: row.value == null ? null : Math.abs(row.value),
|
|
1008
|
+
row: {
|
|
1009
|
+
id: row.id,
|
|
1010
|
+
label: row.symbol,
|
|
1011
|
+
value: null,
|
|
1012
|
+
unit: "% basket",
|
|
1013
|
+
percentile: null,
|
|
1014
|
+
asOf: market.fetchedAt,
|
|
1015
|
+
// What it is worth in the account currency and what moves it; the value column says it is left out.
|
|
1016
|
+
detail: [
|
|
1017
|
+
!foreign ? amount : row.value == null ? `${amount}; no current ${row.currency} rate values it` : `${amount} = ${formatNumber(row.value)} ${portfolio.currency}`,
|
|
1018
|
+
...(foreign ? [`moves with ${row.currency}`] : []),
|
|
1019
|
+
"outside the basket",
|
|
1020
|
+
].join("; "),
|
|
1021
|
+
leftOut: cashReason(row, portfolio.currency),
|
|
1022
|
+
} as RiskDisplayRow,
|
|
1023
|
+
};
|
|
1024
|
+
}),
|
|
1025
|
+
]
|
|
1026
|
+
.sort((a, b) => (b.size ?? -1) - (a.size ?? -1))
|
|
1027
|
+
.map(({ row }) => row),
|
|
836
1028
|
correlation: correlation.map((row) => ({
|
|
837
1029
|
id: `${row.left}/${row.right}`,
|
|
838
1030
|
label: row.label,
|
|
@@ -842,15 +1034,19 @@ export function buildPortfolioRisk(
|
|
|
842
1034
|
asOf: row.asOf ?? null,
|
|
843
1035
|
detail: `${row.samples ?? 0} matched daily returns`,
|
|
844
1036
|
})),
|
|
845
|
-
stress:
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1037
|
+
stress: [
|
|
1038
|
+
// A regression scenario moves the basket by its beta; it is a share of the basket, not of the book.
|
|
1039
|
+
...stresses.map((row) => ({
|
|
1040
|
+
id: row.id,
|
|
1041
|
+
label: row.label,
|
|
1042
|
+
value: row.value,
|
|
1043
|
+
unit: "%",
|
|
1044
|
+
percentile: null,
|
|
1045
|
+
asOf: row.regression?.asOf ?? null,
|
|
1046
|
+
detail: `% of basket; ${row.regression?.samples ?? 0} sessions; R² ${row.regression?.rSquared?.toFixed(2) ?? "--"}; ${row.source}`,
|
|
1047
|
+
})),
|
|
1048
|
+
...(repricing ? repricingRows(repricing, portfolio.currency, market.fetchedAt) : []),
|
|
1049
|
+
],
|
|
854
1050
|
performance: performance
|
|
855
1051
|
? [
|
|
856
1052
|
{
|
|
@@ -951,25 +1147,27 @@ export function buildPortfolioRisk(
|
|
|
951
1147
|
)
|
|
952
1148
|
: [],
|
|
953
1149
|
};
|
|
1150
|
+
// Concentration is of the priced holdings, cash aside, and says so with the value it divides.
|
|
1151
|
+
const holdingsBase = book ? `Share of ${formatNumber(book.gross, 0)} ${portfolio.currency} in priced holdings, cash aside` : "";
|
|
954
1152
|
if (book)
|
|
955
1153
|
rows.holdings.unshift(
|
|
956
1154
|
{
|
|
957
1155
|
id: "top",
|
|
958
1156
|
label: "Largest holding",
|
|
959
1157
|
value: book.top * 100,
|
|
960
|
-
unit:
|
|
1158
|
+
unit: HOLDINGS_SHARE_UNIT,
|
|
961
1159
|
percentile: null,
|
|
962
1160
|
asOf: market.fetchedAt,
|
|
963
|
-
detail:
|
|
1161
|
+
detail: holdingsBase,
|
|
964
1162
|
},
|
|
965
1163
|
{
|
|
966
1164
|
id: "top-five",
|
|
967
1165
|
label: "Largest five",
|
|
968
1166
|
value: book.topFive * 100,
|
|
969
|
-
unit:
|
|
1167
|
+
unit: HOLDINGS_SHARE_UNIT,
|
|
970
1168
|
percentile: null,
|
|
971
1169
|
asOf: market.fetchedAt,
|
|
972
|
-
detail:
|
|
1170
|
+
detail: holdingsBase,
|
|
973
1171
|
},
|
|
974
1172
|
{
|
|
975
1173
|
id: "hhi",
|
|
@@ -978,7 +1176,7 @@ export function buildPortfolioRisk(
|
|
|
978
1176
|
unit: "ratio",
|
|
979
1177
|
percentile: null,
|
|
980
1178
|
asOf: market.fetchedAt,
|
|
981
|
-
detail: `${book.effectiveHoldings.toFixed(2)} effective holdings`,
|
|
1179
|
+
detail: `${book.effectiveHoldings.toFixed(2)} effective holdings, cash aside`,
|
|
982
1180
|
},
|
|
983
1181
|
);
|
|
984
1182
|
return {
|
|
@@ -997,9 +1195,11 @@ export function buildPortfolioRisk(
|
|
|
997
1195
|
evidence,
|
|
998
1196
|
rows,
|
|
999
1197
|
coverage,
|
|
1198
|
+
cash: cashHoldings,
|
|
1199
|
+
repricing,
|
|
1000
1200
|
complete:
|
|
1001
1201
|
sufficient &&
|
|
1002
|
-
coverage
|
|
1202
|
+
!riskHoldingsLeftOut(coverage) &&
|
|
1003
1203
|
metrics.some((row) => row.value != null),
|
|
1004
1204
|
warnings: [...new Set(warnings)],
|
|
1005
1205
|
notes,
|
|
@@ -1029,18 +1229,11 @@ export const riskValue = (row: RiskDisplayRow) =>
|
|
|
1029
1229
|
: row.value == null
|
|
1030
1230
|
? "--"
|
|
1031
1231
|
: `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}${riskAmount(row)}`;
|
|
1032
|
-
/**
|
|
1033
|
-
export function riskAmountBase(row: Pick<RiskDisplayRow, "amountBase" | "amountCurrency">): string | null {
|
|
1034
|
-
return row.amountBase != null && Number.isFinite(row.amountBase) && row.amountCurrency
|
|
1035
|
-
? `${formatNumber(row.amountBase, 0)} ${row.amountCurrency} basket`
|
|
1036
|
-
: null;
|
|
1037
|
-
}
|
|
1038
|
-
/** A row's evidence with the basket a tail loss in money is taken on. */
|
|
1232
|
+
/** A row's evidence with what a tail loss in money is taken on: the basket, its share of the book and what it leaves out. */
|
|
1039
1233
|
export function riskEvidence(row: RiskDisplayRow): string {
|
|
1040
|
-
|
|
1041
|
-
return base ? `${row.detail}; of ${base}` : row.detail;
|
|
1234
|
+
return row.basis ? `${row.detail}; ${row.basis}` : row.detail;
|
|
1042
1235
|
}
|
|
1043
|
-
/** " ($5,735)": a
|
|
1236
|
+
/** " ($5,735)": a loss or change in money beside its percent. */
|
|
1044
1237
|
function riskAmount(row: RiskDisplayRow): string {
|
|
1045
1238
|
if (row.amount == null || !Number.isFinite(row.amount) || !row.amountCurrency) return "";
|
|
1046
1239
|
return ` (${formatCurrency(row.amount, row.amountCurrency, 0)})`;
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
loadScenarioMarket,
|
|
7
7
|
type ScenarioLoaderDependencies,
|
|
8
8
|
} from "../options-scenario/client";
|
|
9
|
+
import { optionModelSpot } from "../options/model-spot";
|
|
9
10
|
import { createGloomberbCloudProvider } from "../../../sources/gloomberb-cloud";
|
|
10
11
|
import { canonicalExchange } from "../../../utils/exchanges";
|
|
11
12
|
|
|
@@ -142,14 +143,28 @@ export async function loadPortfolioOptionBook(
|
|
|
142
143
|
option.impliedVolatility <= 0
|
|
143
144
|
)
|
|
144
145
|
throw new Error("Contract implied volatility unavailable");
|
|
146
|
+
// Valued where the chain's IV was measured, as OMON values the chain: a
|
|
147
|
+
// closed session's quotes at the time they were taken and the session's
|
|
148
|
+
// close. Over the hours left now, a same-day IV would price the contract
|
|
149
|
+
// under its quote before the open.
|
|
150
|
+
const valuation = optionModelSpot(
|
|
151
|
+
market.underlyingQuote,
|
|
152
|
+
market.chain,
|
|
153
|
+
dependencies.now?.() ?? Date.now(),
|
|
154
|
+
exchange,
|
|
155
|
+
);
|
|
156
|
+
if (!valuation)
|
|
157
|
+
throw new Error(
|
|
158
|
+
"Fresh matching Cloud spot, chain, rate and dividend inputs are required",
|
|
159
|
+
);
|
|
145
160
|
const position: ScenarioPosition = {
|
|
146
161
|
symbol: market.symbol,
|
|
147
162
|
exchange,
|
|
148
163
|
currency: market.currency,
|
|
149
|
-
spot:
|
|
164
|
+
spot: valuation.price,
|
|
150
165
|
rate: market.rate,
|
|
151
166
|
dividendYield: market.dividendYield,
|
|
152
|
-
asOf:
|
|
167
|
+
asOf: valuation.valuationTime,
|
|
153
168
|
legs: [
|
|
154
169
|
{
|
|
155
170
|
id: String(contract.conId),
|