gloomberb 0.16.0 → 0.16.2
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 +2 -1
- package/package.json +2 -1
- package/src/api-client/beneficial-owners.ts +92 -0
- package/src/api-client/data.ts +44 -11
- package/src/api-client/errors.ts +12 -0
- package/src/api-client/geo.ts +363 -0
- package/src/api-client/index.ts +5 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/members.ts +26 -0
- package/src/api-client/paths.ts +30 -1
- package/src/api-client/perps.ts +41 -0
- package/src/api-client/request.ts +5 -2
- package/src/api-client/types.ts +9 -1
- package/src/app/global-shortcuts.ts +14 -6
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/runtime/update.ts +38 -2
- package/src/app.tsx +10 -6
- package/src/brokers/account-cache.ts +24 -0
- package/src/cli/commands/command-utils.ts +8 -0
- package/src/cli/commands/crypto-hints.ts +75 -0
- package/src/cli/commands/market.ts +414 -106
- package/src/cli/commands/overview.ts +77 -32
- package/src/cli/commands/ticker.ts +101 -43
- package/src/cli/desktop-pane-shot.ts +34 -4
- package/src/cli/freshness.ts +61 -0
- package/src/cli/help.ts +1 -0
- package/src/cli/helpers.ts +4 -8
- package/src/cli/index.ts +12 -2
- package/src/cli/listing-arg.ts +321 -0
- package/src/cli/pane-functions/access-gate.ts +42 -0
- package/src/cli/pane-functions/catalog.ts +28 -1
- package/src/cli/pane-functions/data.ts +3 -1
- package/src/cli/pane-functions/dom.ts +20 -2
- package/src/cli/pane-functions/freshness.ts +400 -0
- package/src/cli/pane-functions/function-help.ts +36 -22
- package/src/cli/pane-functions/headless.ts +39 -11
- package/src/cli/pane-functions/index.ts +15 -4
- package/src/cli/pane-functions/options.ts +3 -0
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +35 -7
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +7 -3
- package/src/cli/result.ts +41 -27
- package/src/cli/ticker-resolution.ts +7 -5
- package/src/components/chart/composite/composite-chart.tsx +88 -2536
- package/src/components/chart/composite/drawing-store.ts +59 -0
- package/src/components/chart/composite/legend.tsx +319 -0
- package/src/components/chart/composite/panel-bitmap.ts +139 -0
- package/src/components/chart/composite/panel-gestures.ts +59 -0
- package/src/components/chart/composite/panel-labels.ts +107 -0
- package/src/components/chart/composite/panel-surface.tsx +876 -0
- package/src/components/chart/composite/tool-catalog.ts +98 -0
- package/src/components/chart/composite/toolbar.tsx +186 -0
- package/src/components/chart/composite/tools.ts +8 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
- package/src/components/chart/composite/use-composite-viewport.ts +143 -0
- package/src/components/command-bar/commands/collection.ts +5 -1
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/list/view.tsx +16 -3
- package/src/components/command-bar/pane-templates/workflow.ts +1 -0
- package/src/components/command-bar/routes/root/command-items.ts +9 -2
- package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
- package/src/components/command-bar/routes/root/provider-search.ts +19 -5
- package/src/components/command-bar/routes/root/runtime.ts +14 -5
- package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
- package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
- package/src/components/command-bar/routing/actions.ts +2 -0
- package/src/components/command-bar/selection-runtime.ts +38 -0
- package/src/components/command-bar/surface/index.tsx +7 -2
- package/src/components/command-bar/workflow/ops.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +6 -0
- package/src/components/data-table/view.tsx +29 -10
- package/src/components/feedback-dialog.tsx +2 -1
- package/src/components/form-modal/field-row.tsx +2 -2
- package/src/components/index.ts +2 -2
- package/src/components/layout/detached-pane-shell.tsx +6 -3
- package/src/components/layout/floating-pane.tsx +6 -0
- package/src/components/layout/header.tsx +24 -7
- package/src/components/layout/missing-pane.tsx +2 -2
- package/src/components/layout/pane/content.tsx +23 -10
- package/src/components/layout/pane/error-boundary.tsx +103 -0
- package/src/components/layout/pane/footer/registration.tsx +68 -23
- package/src/components/layout/pane/header.tsx +61 -28
- package/src/components/layout/pane/index.tsx +6 -0
- package/src/components/layout/pane/title.ts +31 -7
- package/src/components/layout/shell/drag/index.ts +6 -5
- package/src/components/layout/shell/drag/runtime.ts +3 -0
- package/src/components/layout/shell/index.tsx +6 -0
- package/src/components/layout/shell/menu.ts +2 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +29 -10
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
- package/src/components/layout/shell/ticker-link-menu.ts +23 -9
- package/src/components/metric-treemap/heat-surface.tsx +745 -0
- package/src/components/metric-treemap/heat-tiles.ts +228 -0
- package/src/components/metric-treemap/index.tsx +2 -0
- package/src/components/metric-treemap/layout.ts +8 -0
- package/src/components/metric-treemap/scene.ts +432 -0
- package/src/components/onboarding/onboarding-keyboard.ts +311 -0
- package/src/components/onboarding/onboarding-wizard.tsx +101 -788
- package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
- package/src/components/onboarding/use-onboarding-progress.ts +298 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
- package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -0
- package/src/components/ticker/list-table-view.tsx +13 -1
- package/src/components/toggle-list.tsx +38 -12
- package/src/components/ui/country-flag-art.tsx +449 -0
- package/src/components/ui/country-flag.tsx +41 -0
- package/src/components/ui/data-table/types.ts +13 -0
- package/src/components/ui/fields.tsx +8 -0
- package/src/components/ui/icon.tsx +2 -0
- package/src/components/ui/index.ts +4 -0
- package/src/components/ui/multi-select/dialog.tsx +108 -22
- package/src/components/ui/range-track.tsx +53 -0
- package/src/components/ui/status.tsx +8 -2
- package/src/components/ui/tabs.tsx +11 -4
- package/src/components/ui/text-prompt-dialog.tsx +4 -2
- package/src/core/state/app/types.ts +10 -1
- package/src/data/config/store/normalize.ts +17 -1
- package/src/i18n/es.ts +24 -4
- package/src/i18n/ja.ts +24 -4
- package/src/i18n/ko.ts +24 -4
- package/src/i18n/zh-cn.ts +24 -4
- package/src/i18n/zh-tw.ts +24 -4
- package/src/layout/ticker-navigation.ts +28 -2
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/quotes.ts +23 -4
- package/src/market-data/fx-closes.ts +72 -0
- package/src/market-data/market/freshness.ts +78 -6
- package/src/market-data/market/session-close-note.ts +57 -0
- package/src/market-data/market/status.ts +151 -0
- package/src/market-data/published-apac-sessions.ts +66 -0
- package/src/market-data/quotes/contributions.ts +8 -0
- package/src/market-data/quotes/freshness.ts +36 -0
- package/src/market-data/quotes/resolution.ts +24 -8
- package/src/market-data/quotes/screener-live-quotes.ts +49 -4
- package/src/market-data/quotes/time.ts +16 -0
- package/src/plugins/builtin/account-management/pane.tsx +4 -0
- package/src/plugins/builtin/alerts/cli.ts +10 -5
- package/src/plugins/builtin/alerts/index.tsx +1 -0
- package/src/plugins/builtin/analytics/metrics.ts +8 -3
- package/src/plugins/builtin/analytics/risk-client.ts +330 -79
- package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
- package/src/plugins/builtin/analytics/risk-math.ts +33 -13
- package/src/plugins/builtin/analytics/risk-model.ts +282 -64
- package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
- package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
- package/src/plugins/builtin/attention/headless.ts +6 -4
- package/src/plugins/builtin/attention/index.tsx +1 -1
- package/src/plugins/builtin/attention/pane.tsx +1 -1
- package/src/plugins/builtin/awards/headless.ts +1 -0
- package/src/plugins/builtin/awards/pane.tsx +1 -1
- package/src/plugins/builtin/backtest/headless.ts +1 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
- package/src/plugins/builtin/buildout/cells.tsx +15 -12
- package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
- package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
- package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
- package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
- package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
- package/src/plugins/builtin/buildout/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +3 -1
- package/src/plugins/builtin/catalysts/index.tsx +2 -2
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/headless.ts +2 -0
- package/src/plugins/builtin/cds/index.tsx +1 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
- package/src/plugins/builtin/chart-composer/headless.ts +38 -3
- package/src/plugins/builtin/chart-composer/index.tsx +3 -1
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
- package/src/plugins/builtin/chat/channels.ts +19 -3
- package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
- package/src/plugins/builtin/chat/content/footer.tsx +15 -6
- package/src/plugins/builtin/chat/content/index.tsx +120 -21
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
- package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
- package/src/plugins/builtin/chat/direct-messages.ts +200 -0
- package/src/plugins/builtin/chat/index.tsx +1 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
- package/src/plugins/builtin/chat/message/header.tsx +16 -6
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
- package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
- package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
- package/src/plugins/builtin/chat/message/types.ts +14 -2
- package/src/plugins/builtin/chat/profile-popover.ts +18 -13
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/comment-letters/index.tsx +1 -0
- package/src/plugins/builtin/company-attention/headless.ts +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +1 -1
- package/src/plugins/builtin/company-kpis/headless.ts +1 -0
- package/src/plugins/builtin/congress-trades/headless.ts +1 -0
- package/src/plugins/builtin/correlation/compute.ts +59 -16
- package/src/plugins/builtin/correlation/geo.ts +34 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
- package/src/plugins/builtin/correlation/headless.ts +42 -8
- package/src/plugins/builtin/correlation/history.ts +2 -0
- package/src/plugins/builtin/correlation/index.tsx +68 -14
- package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
- package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
- package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
- package/src/plugins/builtin/correlation/settings.ts +1 -1
- package/src/plugins/builtin/cot/headless.ts +6 -3
- package/src/plugins/builtin/cot/index.tsx +3 -3
- package/src/plugins/builtin/cot/model.ts +36 -3
- package/src/plugins/builtin/cpi/headless.ts +4 -0
- package/src/plugins/builtin/credit-boards/headless.ts +2 -0
- package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
- package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
- package/src/plugins/builtin/credit-documents/headless.ts +2 -0
- package/src/plugins/builtin/crypto-board/headless.ts +3 -0
- package/src/plugins/builtin/custom-view/loader.ts +1 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
- package/src/plugins/builtin/debt-maturities/wall-bar.tsx +14 -41
- package/src/plugins/builtin/dividend-yield/client.ts +4 -2
- package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
- package/src/plugins/builtin/doe/headless.ts +7 -0
- package/src/plugins/builtin/doe/range-bar.tsx +7 -37
- package/src/plugins/builtin/earnings/client.ts +2 -2
- package/src/plugins/builtin/earnings/headless.ts +5 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
- package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
- package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
- package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
- package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
- package/src/plugins/builtin/econ/index.tsx +1 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
- package/src/plugins/builtin/equity-screener/headless.ts +2 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/headless.ts +3 -1
- package/src/plugins/builtin/fear-greed/headless.ts +2 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +39 -10
- package/src/plugins/builtin/futures-curve/index.tsx +3 -3
- package/src/plugins/builtin/futures-curve/model.ts +188 -4
- package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
- package/src/plugins/builtin/fx-matrix/direction.ts +81 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
- package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
- package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
- package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
- package/src/plugins/builtin/gpu/headless.ts +7 -3
- package/src/plugins/builtin/gpu/ladder.tsx +26 -30
- package/src/plugins/builtin/gpu/model.ts +27 -1
- package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
- package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
- package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
- package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
- package/src/plugins/builtin/holders/headless.ts +139 -5
- package/src/plugins/builtin/holders/index.tsx +10 -3
- package/src/plugins/builtin/holders/pane.tsx +20 -3
- package/src/plugins/builtin/holders/report-header.ts +95 -0
- package/src/plugins/builtin/holders/table-model.ts +20 -5
- package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
- package/src/plugins/builtin/holders/types.ts +2 -1
- package/src/plugins/builtin/insider/headless.ts +2 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
- package/src/plugins/builtin/iv-history/headless.ts +4 -1
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +2 -0
- package/src/plugins/builtin/market-halts/index.tsx +1 -0
- package/src/plugins/builtin/market-heatmap/data.ts +30 -2
- package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
- package/src/plugins/builtin/market-heatmap/live.ts +88 -0
- package/src/plugins/builtin/market-heatmap/model.ts +146 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
- package/src/plugins/builtin/market-movers/client.ts +3 -2
- package/src/plugins/builtin/market-movers/headless.ts +10 -1
- package/src/plugins/builtin/market-movers/screener.ts +18 -5
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/members/client.ts +53 -0
- package/src/plugins/builtin/members/headless.ts +35 -0
- package/src/plugins/builtin/members/index.tsx +20 -0
- package/src/plugins/builtin/members/model.ts +68 -0
- package/src/plugins/builtin/members/pane.tsx +175 -0
- package/src/plugins/builtin/mna/distress/headless.ts +1 -0
- package/src/plugins/builtin/mna/headless.ts +1 -0
- package/src/plugins/builtin/mna/index.tsx +2 -1
- package/src/plugins/builtin/mna/pane.tsx +5 -2
- package/src/plugins/builtin/money-markets/headless.ts +1 -0
- package/src/plugins/builtin/news/headless.ts +2 -0
- package/src/plugins/builtin/news/wire/index.tsx +8 -1
- package/src/plugins/builtin/notes/cli.ts +14 -6
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/openfda/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +2 -1
- package/src/plugins/builtin/options-calculator/headless.ts +2 -0
- package/src/plugins/builtin/options-positioning/headless.ts +3 -0
- package/src/plugins/builtin/options-scenario/headless.ts +5 -0
- package/src/plugins/builtin/pe-band/client.ts +74 -2
- package/src/plugins/builtin/pe-band/headless.ts +26 -8
- package/src/plugins/builtin/pe-band/model.ts +102 -22
- package/src/plugins/builtin/pe-band/pane.tsx +34 -16
- package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
- package/src/plugins/builtin/perps/client.ts +66 -5
- package/src/plugins/builtin/perps/equity-identity.ts +16 -0
- package/src/plugins/builtin/perps/equity-row.tsx +6 -4
- package/src/plugins/builtin/perps/headless.ts +144 -16
- package/src/plugins/builtin/perps/index.tsx +6 -6
- package/src/plugins/builtin/perps/model.ts +189 -12
- package/src/plugins/builtin/perps/pane.tsx +248 -47
- package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
- package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
- package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
- package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
- package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
- package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
- package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
- package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
- package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
- package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
- package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
- package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
- package/src/plugins/builtin/power/headless.ts +3 -1
- package/src/plugins/builtin/rate-path/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
- package/src/plugins/builtin/research/analyst-headless.ts +3 -0
- package/src/plugins/builtin/research/events-headless.ts +2 -0
- package/src/plugins/builtin/research/headless.ts +2 -0
- package/src/plugins/builtin/research/index.tsx +1 -0
- package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
- package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
- package/src/plugins/builtin/research-search/index.tsx +1 -0
- package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
- package/src/plugins/builtin/risk-factors/headless.ts +2 -0
- package/src/plugins/builtin/scanner/flow-history.ts +2 -13
- package/src/plugins/builtin/scanner/headless.ts +14 -0
- package/src/plugins/builtin/scanner/hilo-bars.tsx +12 -70
- package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
- package/src/plugins/builtin/seasonality/headless.ts +2 -0
- package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
- package/src/plugins/builtin/sec/filing-content.ts +42 -17
- package/src/plugins/builtin/sec/forms.ts +12 -0
- package/src/plugins/builtin/sec/headless.ts +2 -0
- package/src/plugins/builtin/sectors/client.ts +1 -0
- package/src/plugins/builtin/sectors/headless.ts +9 -1
- package/src/plugins/builtin/sectors/move-bar.tsx +10 -32
- package/src/plugins/builtin/sectors/sector-model.ts +2 -0
- package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
- package/src/plugins/builtin/shared/report-freshness.ts +57 -0
- package/src/plugins/builtin/shared/research-cells.tsx +4 -9
- package/src/plugins/builtin/short-interest/headless.ts +2 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/index.tsx +1 -1
- package/src/plugins/builtin/supply-chain/headless.ts +7 -1
- package/src/plugins/builtin/supply-chain/index.tsx +10 -1
- package/src/plugins/builtin/supply-chain/model.ts +27 -2
- package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
- package/src/plugins/builtin/themes/headless.ts +3 -0
- package/src/plugins/builtin/thirteenf/headless.ts +110 -25
- package/src/plugins/builtin/thirteenf/index.tsx +2 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
- package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
- package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
- package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
- package/src/plugins/builtin/time-sales/headless.ts +5 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
- package/src/plugins/builtin/vol-surface/index.tsx +1 -1
- package/src/plugins/builtin/volatility/headless.ts +6 -1
- package/src/plugins/builtin/world-indices/headless.ts +2 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
- package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
- package/src/plugins/builtin/world-venue-map/client.ts +45 -0
- package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
- package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
- package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
- package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
- package/src/plugins/builtin/world-venue-map/index.ts +67 -4
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
- package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
- package/src/plugins/builtin/world-venue-map/model.ts +7 -4
- package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
- package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
- package/src/plugins/builtin/yield-curve/headless.ts +16 -0
- package/src/plugins/catalog-browser.ts +2 -0
- package/src/plugins/catalog-manifest.ts +1 -0
- package/src/plugins/catalog-ui.ts +3 -1
- package/src/plugins/catalog.ts +1 -1
- package/src/plugins/host-link.ts +33 -1
- package/src/plugins/installer.ts +48 -12
- package/src/plugins/loader.ts +30 -3
- package/src/plugins/manager-node.ts +15 -5
- package/src/plugins/registry/index.ts +1 -1
- package/src/plugins/registry/pane-settings.ts +26 -7
- package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
- package/src/renderers/dom/build-assets.ts +81 -3
- package/src/renderers/dom/data-table/row.tsx +52 -16
- package/src/renderers/dom/desktop/controls.tsx +7 -3
- package/src/renderers/dom/desktop/icons.tsx +1 -0
- package/src/renderers/dom/desktop/list-view.tsx +35 -10
- package/src/renderers/dom/desktop/popover.tsx +73 -14
- package/src/renderers/dom/host/box.tsx +69 -26
- package/src/renderers/dom/host/input.tsx +14 -3
- package/src/renderers/dom/host/tabs.tsx +37 -1
- package/src/renderers/dom/styles.css +41 -7
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
- package/src/renderers/electrobun/bun/index.ts +73 -6
- package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
- package/src/renderers/electrobun/shared/protocol.ts +3 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
- package/src/renderers/electrobun/view/main.tsx +7 -1
- package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
- package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
- package/src/renderers/electrobun/view/update-host.ts +45 -21
- package/src/renderers/opentui/host.tsx +5 -0
- package/src/sources/gloomberb-cloud/index.ts +25 -4
- package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
- package/src/sources/provider-router/cached-routes.ts +4 -1
- package/src/sources/provider-router/financials.ts +11 -8
- package/src/sources/provider-router/history.ts +15 -10
- package/src/sources/sec-registrant.ts +75 -0
- package/src/state/app/context/index.tsx +24 -8
- package/src/state/hooks/quote-streaming.ts +41 -26
- package/src/sync/core-contributors.ts +4 -0
- package/src/telemetry/benign-window-error.ts +7 -0
- package/src/telemetry/crash-reports-dom.ts +2 -0
- package/src/telemetry/crash-reports.ts +4 -1
- package/src/test-support/cli-context.ts +10 -2
- package/src/test-support/daily-nav.ts +25 -0
- package/src/theme/heat-colors.ts +357 -2
- package/src/tickers/instrument-kind.ts +34 -7
- package/src/tickers/search/asset-classes.ts +24 -9
- package/src/tickers/search/index.ts +44 -11
- package/src/tickers/search/ranking.ts +23 -3
- package/src/time-series/resolve.ts +1 -1
- package/src/time-series/use-chart-resolution.ts +1 -1
- package/src/types/context-menu.ts +6 -0
- package/src/types/data-provider.ts +2 -0
- package/src/types/financials.ts +5 -0
- package/src/types/headless.ts +79 -2
- package/src/types/plugin.ts +38 -6
- package/src/types/ticker.ts +15 -0
- package/src/ui/context-menu.tsx +1 -0
- package/src/ui/host.tsx +16 -0
- package/src/updater/index.ts +38 -13
- package/src/utils/async-deadline.ts +21 -0
- package/src/utils/cli-output.ts +5 -1
- package/src/utils/crypto-pair.ts +41 -0
- package/src/utils/currency-units.ts +14 -0
- package/src/utils/depositary-receipt.ts +26 -0
- package/src/utils/exchanges.ts +72 -0
- package/src/utils/fire-and-forget.ts +24 -0
- package/src/utils/format.ts +13 -0
- package/src/utils/price-earnings.ts +70 -3
- package/src/utils/price-history.ts +58 -13
- package/src/utils/rpc-timeout-error.ts +27 -0
- package/src/utils/sec.ts +13 -1
- package/src/utils/utc-time.ts +79 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { portfolioOptionGreeks } from "./risk-options";
|
|
2
2
|
import type { Portfolio, TickerRecord } from "../../../types/ticker";
|
|
3
3
|
import { formatNumber } from "../../../utils/format";
|
|
4
|
+
import { resolveCurrencyUnit } from "../../../utils/currency-units";
|
|
5
|
+
import {
|
|
6
|
+
getPortfolioPositionMetrics,
|
|
7
|
+
resolvePortfolioMarketValue,
|
|
8
|
+
} from "../portfolio-list/position-metrics";
|
|
4
9
|
import type { DatedReturn } from "./metrics";
|
|
5
10
|
import {
|
|
6
11
|
computeWeightedPortfolioReturns,
|
|
@@ -22,6 +27,7 @@ import {
|
|
|
22
27
|
import {
|
|
23
28
|
RISK_FACTOR_INSTRUMENTS,
|
|
24
29
|
riskInstrumentId,
|
|
30
|
+
type RiskHoldingRequest,
|
|
25
31
|
type RiskMarketSnapshot,
|
|
26
32
|
} from "./risk-client";
|
|
27
33
|
|
|
@@ -31,14 +37,50 @@ interface PortfolioRiskHolding {
|
|
|
31
37
|
exchange: string;
|
|
32
38
|
quantity: number;
|
|
33
39
|
currency: string;
|
|
40
|
+
/** Signed USD value at the current mark; only these marks weight the basket. */
|
|
34
41
|
value: number | null;
|
|
42
|
+
/** Weight in the covered basket, null outside it. */
|
|
35
43
|
weight: number | null;
|
|
44
|
+
/** Gross current value in the portfolio currency, for the covered share only; null when nothing values it. */
|
|
45
|
+
marketValue: number | null;
|
|
36
46
|
priceAsOf: string | null;
|
|
37
47
|
/** "close" when no current quote arrived and the latest completed close marks the holding. */
|
|
38
48
|
markSource?: "quote" | "close" | null;
|
|
49
|
+
/** The listing currency its closes were converted from at daily FX closes; null for a USD listing. */
|
|
50
|
+
convertedFrom: string | null;
|
|
39
51
|
historyAsOf: string | null;
|
|
40
52
|
returns: DatedReturn[];
|
|
41
53
|
error: string | null;
|
|
54
|
+
/** Why the holding is outside the basket; null when it qualifies. */
|
|
55
|
+
leftOut: string | null;
|
|
56
|
+
}
|
|
57
|
+
/** A holding outside the basket, with its share of market value when one is known. */
|
|
58
|
+
interface RiskLeftOut {
|
|
59
|
+
id: string;
|
|
60
|
+
symbol: string;
|
|
61
|
+
reason: string;
|
|
62
|
+
value: number | null;
|
|
63
|
+
share: number | null;
|
|
64
|
+
}
|
|
65
|
+
/** What the basket views cover of the account. */
|
|
66
|
+
export interface RiskCoverage {
|
|
67
|
+
currency: string;
|
|
68
|
+
/** Gross current value of every holding that has one, in the portfolio currency. */
|
|
69
|
+
marketValue: number;
|
|
70
|
+
coveredValue: number;
|
|
71
|
+
/** Covered share of market value; an upper bound while `unvalued` holdings have no value. */
|
|
72
|
+
share: number | null;
|
|
73
|
+
holdings: number;
|
|
74
|
+
/** Holdings that qualify for the basket. */
|
|
75
|
+
covered: number;
|
|
76
|
+
/** Covered holdings whose returns were converted to USD from their listing currency. */
|
|
77
|
+
converted: number;
|
|
78
|
+
unvalued: number;
|
|
79
|
+
minimumShare: number;
|
|
80
|
+
/** The basket views estimate only when qualifying holdings reach the minimum share. */
|
|
81
|
+
sufficient: boolean;
|
|
82
|
+
/** Largest first. */
|
|
83
|
+
leftOut: RiskLeftOut[];
|
|
42
84
|
}
|
|
43
85
|
export interface RiskDisplayRow {
|
|
44
86
|
id: string;
|
|
@@ -53,7 +95,17 @@ export interface RiskDisplayRow {
|
|
|
53
95
|
allocation?: number;
|
|
54
96
|
selection?: number;
|
|
55
97
|
interaction?: number;
|
|
98
|
+
/** Holdings rows only: why the holding is outside the covered basket. */
|
|
99
|
+
leftOut?: string;
|
|
56
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Below half of market value the qualifying holdings are not most of the
|
|
103
|
+
* account, so a basket estimate would mostly describe something other than it;
|
|
104
|
+
* the basket views say why instead of estimating.
|
|
105
|
+
*/
|
|
106
|
+
const RISK_MIN_COVERAGE = 0.5;
|
|
107
|
+
/** Views computed from the covered basket; the others read the whole account or its option book. */
|
|
108
|
+
export const BASKET_VIEWS: ReadonlySet<RiskView> = new Set(["risk", "factors", "holdings", "correlation", "stress"]);
|
|
57
109
|
/** Book-level concentration rows that lead the holdings view, ahead of one row per holding. */
|
|
58
110
|
export const HOLDINGS_SUMMARY_ROW_IDS: ReadonlySet<string> = new Set(["top", "top-five", "hhi"]);
|
|
59
111
|
export const RISK_VIEWS = [
|
|
@@ -110,7 +162,125 @@ export function portfolioRiskTickers(
|
|
|
110
162
|
positions(ticker, portfolioId).length > 0,
|
|
111
163
|
);
|
|
112
164
|
}
|
|
113
|
-
|
|
165
|
+
const signedQuantity = (lots: TickerRecord["metadata"]["positions"]) =>
|
|
166
|
+
lots.reduce(
|
|
167
|
+
(sum, row) => sum + (row.side === "short" ? -Math.abs(row.shares) : row.shares),
|
|
168
|
+
0,
|
|
169
|
+
);
|
|
170
|
+
/** What the market load needs to rank holdings by value and skip the ones the basket cannot take. */
|
|
171
|
+
export function portfolioRiskRequests(
|
|
172
|
+
tickers: readonly TickerRecord[],
|
|
173
|
+
portfolioId: string,
|
|
174
|
+
): RiskHoldingRequest[] {
|
|
175
|
+
return tickers.map((ticker) => {
|
|
176
|
+
const lots = positions(ticker, portfolioId);
|
|
177
|
+
const currency = lots.find((row) => row.currency)?.currency ?? ticker.metadata.currency;
|
|
178
|
+
const snapshot = lots.every(
|
|
179
|
+
(row) => Number.isFinite(row.marketValue) && (row.currency ?? ticker.metadata.currency) === "USD",
|
|
180
|
+
)
|
|
181
|
+
? lots.reduce((sum, row) => sum + Math.abs(row.marketValue!), 0)
|
|
182
|
+
: null;
|
|
183
|
+
return {
|
|
184
|
+
symbol: ticker.metadata.ticker,
|
|
185
|
+
exchange: ticker.metadata.exchange,
|
|
186
|
+
quantity: signedQuantity(lots),
|
|
187
|
+
currency,
|
|
188
|
+
snapshotValue: snapshot,
|
|
189
|
+
unsupported:
|
|
190
|
+
syntheticPositionUnsupportedReason(ticker, "USD", portfolioId) != null ||
|
|
191
|
+
lots.some((row) => !Number.isFinite(row.shares)),
|
|
192
|
+
};
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Current gross value of a holding outside the USD marks, in the portfolio
|
|
197
|
+
* currency: its listing price, else the broker's snapshot, at the load's rates.
|
|
198
|
+
* It sizes what is left out and never enters a return.
|
|
199
|
+
*/
|
|
200
|
+
function outsideValue(
|
|
201
|
+
ticker: TickerRecord,
|
|
202
|
+
portfolio: Portfolio,
|
|
203
|
+
price: { price: number; currency: string } | null,
|
|
204
|
+
rates: Readonly<Record<string, number>>,
|
|
205
|
+
): number | null {
|
|
206
|
+
const toUsd = (value: number, currency: string) => {
|
|
207
|
+
const unit = resolveCurrencyUnit(currency);
|
|
208
|
+
const rate = unit.currency === "USD" ? 1 : rates[unit.currency];
|
|
209
|
+
return rate != null && rate > 0 ? (value * rate) / unit.divisor : Number.NaN;
|
|
210
|
+
};
|
|
211
|
+
const toAccount = (value: number, currency: string) => {
|
|
212
|
+
if (currency === portfolio.currency) return value;
|
|
213
|
+
const rate = portfolio.currency === "USD" ? 1 : rates[portfolio.currency];
|
|
214
|
+
return rate != null && rate > 0 ? toUsd(value, currency) / rate : Number.NaN;
|
|
215
|
+
};
|
|
216
|
+
const metrics = getPortfolioPositionMetrics(ticker, portfolio.id, ticker.metadata.currency, {
|
|
217
|
+
currency: portfolio.currency,
|
|
218
|
+
convert: toAccount,
|
|
219
|
+
});
|
|
220
|
+
const unit = price && Number.isFinite(price.price) && price.price > 0
|
|
221
|
+
? toAccount(price.price, price.currency)
|
|
222
|
+
: null;
|
|
223
|
+
const value = resolvePortfolioMarketValue(metrics, unit != null && Number.isFinite(unit) ? unit : null)?.gross;
|
|
224
|
+
return value != null && Number.isFinite(value) ? value : null;
|
|
225
|
+
}
|
|
226
|
+
const coveragePercent = (share: number) => Math.floor(share * 100);
|
|
227
|
+
const holdingCount = (count: number) => `${count} holding${count === 1 ? "" : "s"}`;
|
|
228
|
+
const shareText = (share: number) =>
|
|
229
|
+
share < 0.001 ? "under 0.1%" : `${(share * 100).toFixed(1)}%`;
|
|
230
|
+
/**
|
|
231
|
+
* "covers 78% of market value · 9 holdings left out · 2 converted from local
|
|
232
|
+
* currency", or null when every holding is in the basket in its own USD listing.
|
|
233
|
+
*/
|
|
234
|
+
export function riskCoverageText(coverage: RiskCoverage | undefined): string | null {
|
|
235
|
+
if (!coverage) return null;
|
|
236
|
+
const converted = coverage.converted ? `${holdingCount(coverage.converted)} converted from local currency` : null;
|
|
237
|
+
if (!coverage.leftOut.length) return converted;
|
|
238
|
+
const covers = coverage.share == null
|
|
239
|
+
? "covers an unknown share of market value"
|
|
240
|
+
: `covers ${coverage.unvalued ? "at most " : ""}${coveragePercent(coverage.share)}% of market value`;
|
|
241
|
+
return [covers, `${holdingCount(coverage.leftOut.length)} left out`, ...(converted ? [converted] : [])].join(" · ");
|
|
242
|
+
}
|
|
243
|
+
/** A reason reads as the tail of a sentence, so its first word loses its capital unless it is an acronym ("FX", "USD"). */
|
|
244
|
+
const lowerFirst = (text: string) => (/^[A-Z][a-z]/.test(text) ? text[0]!.toLowerCase() + text.slice(1) : text);
|
|
245
|
+
/** One sentence per left-out holding, largest first, naming the holding and why it is out. */
|
|
246
|
+
export function riskCoverageNotices(coverage: RiskCoverage | undefined): string[] {
|
|
247
|
+
if (!coverage?.leftOut.length) return [];
|
|
248
|
+
return coverage.leftOut.map(
|
|
249
|
+
(row) =>
|
|
250
|
+
`${row.symbol} (${row.share == null ? "value unknown" : `${shareText(row.share)} of market value`}) is excluded from the risk estimate: ${lowerFirst(row.reason.replace(/\.$/, ""))}.`,
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
/** Why the basket views show no estimate, when too little of the account qualifies. */
|
|
254
|
+
export function riskCoverageShortfall(
|
|
255
|
+
coverage: RiskCoverage | undefined,
|
|
256
|
+
): { title: string; message: string } | null {
|
|
257
|
+
if (!coverage || coverage.sufficient) return null;
|
|
258
|
+
if (!coverage.holdings) return { title: "No holdings in this portfolio.", message: "" };
|
|
259
|
+
const minimum = Math.round(coverage.minimumShare * 100);
|
|
260
|
+
const reasons = new Map<string, { share: number; count: number }>();
|
|
261
|
+
for (const row of coverage.leftOut) {
|
|
262
|
+
const entry = reasons.get(row.reason) ?? { share: 0, count: 0 };
|
|
263
|
+
entry.share += row.share ?? 0;
|
|
264
|
+
entry.count += 1;
|
|
265
|
+
reasons.set(row.reason, entry);
|
|
266
|
+
}
|
|
267
|
+
const [reason, largest] = [...reasons].sort(
|
|
268
|
+
([, left], [, right]) => right.share - left.share || right.count - left.count,
|
|
269
|
+
)[0] ?? [];
|
|
270
|
+
return {
|
|
271
|
+
title: coverage.covered === 0 || coverage.share == null
|
|
272
|
+
? `No holding qualifies for basket estimates, which need ${minimum}% of market value.`
|
|
273
|
+
: `Qualifying holdings cover ${coverage.unvalued ? "at most " : ""}${coveragePercent(coverage.share)}% of market value; basket estimates need ${minimum}%.`,
|
|
274
|
+
message: reason
|
|
275
|
+
? `Most of what is left out: ${reason}${largest!.share > 0 ? ` (${shareText(largest!.share)} of market value)` : ""}.`
|
|
276
|
+
: "",
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Basket estimates use the holdings that qualify, reweighted among themselves.
|
|
281
|
+
* Every other holding stays listed with its reason and counts in the market
|
|
282
|
+
* value they are measured against.
|
|
283
|
+
*/
|
|
114
284
|
export function buildPortfolioRisk(
|
|
115
285
|
portfolio: Portfolio,
|
|
116
286
|
tickers: readonly TickerRecord[],
|
|
@@ -138,6 +308,7 @@ export function buildPortfolioRisk(
|
|
|
138
308
|
const byId = new Map(
|
|
139
309
|
market.histories.map((row) => [riskInstrumentId(row.instrument), row]),
|
|
140
310
|
);
|
|
311
|
+
const rates = market.fxRates ?? {};
|
|
141
312
|
const holdings: PortfolioRiskHolding[] = portfolioRiskTickers(
|
|
142
313
|
tickers,
|
|
143
314
|
portfolio.id,
|
|
@@ -157,17 +328,14 @@ export function buildPortfolioRisk(
|
|
|
157
328
|
: quote
|
|
158
329
|
? { price: quote.price, currency: quote.currency, stale: !!quote.stale }
|
|
159
330
|
: null;
|
|
160
|
-
const quantity = lots
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
331
|
+
const quantity = signedQuantity(lots);
|
|
332
|
+
// A converted listing is marked and returned in USD; its own currency is what the holding records.
|
|
333
|
+
const convertedFrom = history?.converted?.currency ?? null;
|
|
334
|
+
const listingCurrency =
|
|
335
|
+
quote?.currency ?? close?.currency ?? history?.listing?.currency ?? ticker.metadata.currency;
|
|
336
|
+
const foreign = !convertedFrom && listingCurrency !== "USD";
|
|
165
337
|
const error =
|
|
166
|
-
syntheticPositionUnsupportedReason(
|
|
167
|
-
ticker,
|
|
168
|
-
quote?.currency ?? close?.currency ?? ticker.metadata.currency,
|
|
169
|
-
portfolio.id,
|
|
170
|
-
) ??
|
|
338
|
+
syntheticPositionUnsupportedReason(ticker, "USD", portfolio.id) ??
|
|
171
339
|
(lots.some((row) => !Number.isFinite(row.shares))
|
|
172
340
|
? "Invalid position quantity"
|
|
173
341
|
: null) ??
|
|
@@ -175,14 +343,18 @@ export function buildPortfolioRisk(
|
|
|
175
343
|
? "Historical account-currency FX is required"
|
|
176
344
|
: null) ??
|
|
177
345
|
(ticker.metadata.currency &&
|
|
178
|
-
mark?.currency &&
|
|
179
|
-
ticker.metadata.currency !== mark
|
|
346
|
+
(convertedFrom ?? mark?.currency) &&
|
|
347
|
+
ticker.metadata.currency !== (convertedFrom ?? mark?.currency)
|
|
180
348
|
? "Holding and quote currencies differ"
|
|
181
349
|
: null) ??
|
|
350
|
+
// A foreign listing that did not convert says why: no pair, stale or gapped FX.
|
|
351
|
+
(foreign
|
|
352
|
+
? (history?.error ?? syntheticPositionUnsupportedReason(ticker, listingCurrency, portfolio.id))
|
|
353
|
+
: null) ??
|
|
182
354
|
history?.error ??
|
|
183
355
|
(!history ? "Daily history unavailable" : null);
|
|
184
356
|
const priceDate = close ? close.date : quoteDate(quote?.lastUpdated);
|
|
185
|
-
const
|
|
357
|
+
const marked =
|
|
186
358
|
mark &&
|
|
187
359
|
mark.currency === portfolio.currency &&
|
|
188
360
|
!mark.stale &&
|
|
@@ -197,61 +369,98 @@ export function buildPortfolioRisk(
|
|
|
197
369
|
error?.startsWith("Short positions"))
|
|
198
370
|
? quantity * mark.price
|
|
199
371
|
: null;
|
|
372
|
+
const value = marked != null && Number.isFinite(marked) ? marked : null;
|
|
373
|
+
const returns = history?.returns ?? [];
|
|
374
|
+
const leftOut =
|
|
375
|
+
error ??
|
|
376
|
+
(value == null || value <= 0
|
|
377
|
+
? "No current USD mark"
|
|
378
|
+
: returns.length < 60
|
|
379
|
+
? "Fewer than 60 daily returns"
|
|
380
|
+
: null);
|
|
200
381
|
return {
|
|
201
382
|
id,
|
|
202
383
|
...instrument,
|
|
203
384
|
quantity,
|
|
204
|
-
currency:
|
|
205
|
-
value
|
|
385
|
+
currency: listingCurrency,
|
|
386
|
+
value,
|
|
206
387
|
weight: null,
|
|
388
|
+
marketValue:
|
|
389
|
+
value != null
|
|
390
|
+
? Math.abs(value)
|
|
391
|
+
: outsideValue(ticker, portfolio, quote ?? history?.listing ?? null, rates),
|
|
207
392
|
priceAsOf: priceDate,
|
|
208
393
|
markSource: close ? "close" : quote ? "quote" : null,
|
|
394
|
+
convertedFrom,
|
|
209
395
|
historyAsOf: history?.asOf ?? null,
|
|
210
|
-
returns
|
|
396
|
+
returns,
|
|
211
397
|
error,
|
|
398
|
+
leftOut,
|
|
212
399
|
};
|
|
213
400
|
});
|
|
214
|
-
const
|
|
215
|
-
|
|
401
|
+
const qualifying = holdings.filter((row) => row.leftOut == null);
|
|
402
|
+
const valued = holdings.filter((row) => row.marketValue != null);
|
|
403
|
+
const marketValue = valued.reduce((sum, row) => sum + row.marketValue!, 0);
|
|
404
|
+
const coveredValue = qualifying.reduce((sum, row) => sum + row.value!, 0);
|
|
405
|
+
const share = marketValue > 0 ? coveredValue / marketValue : null;
|
|
406
|
+
const sufficient = qualifying.length > 0 && share != null && share >= RISK_MIN_COVERAGE;
|
|
407
|
+
const coverage: RiskCoverage = {
|
|
408
|
+
currency: portfolio.currency,
|
|
409
|
+
marketValue,
|
|
410
|
+
coveredValue,
|
|
411
|
+
share,
|
|
412
|
+
holdings: holdings.length,
|
|
413
|
+
covered: qualifying.length,
|
|
414
|
+
converted: qualifying.filter((row) => row.convertedFrom != null).length,
|
|
415
|
+
unvalued: holdings.length - valued.length,
|
|
416
|
+
minimumShare: RISK_MIN_COVERAGE,
|
|
417
|
+
sufficient,
|
|
418
|
+
leftOut: holdings
|
|
419
|
+
.filter((row) => row.leftOut != null)
|
|
420
|
+
.sort((a, b) => (b.marketValue ?? -1) - (a.marketValue ?? -1))
|
|
421
|
+
.map((row) => ({
|
|
422
|
+
id: row.id,
|
|
423
|
+
symbol: row.symbol,
|
|
424
|
+
reason: row.leftOut!,
|
|
425
|
+
value: row.marketValue,
|
|
426
|
+
share: row.marketValue != null && marketValue > 0 ? row.marketValue / marketValue : null,
|
|
427
|
+
})),
|
|
428
|
+
};
|
|
429
|
+
// Weights renormalize over the covered basket; nothing outside it is approximated into it.
|
|
430
|
+
const members = sufficient ? qualifying : [];
|
|
431
|
+
const book = members.length ? concentration(members) : null;
|
|
432
|
+
for (const holding of members)
|
|
216
433
|
holding.weight =
|
|
217
434
|
book?.rows.find((row) => row.id === holding.id)?.weight ?? null;
|
|
218
|
-
const closeMarked =
|
|
219
|
-
|
|
220
|
-
).
|
|
221
|
-
|
|
222
|
-
|
|
435
|
+
const closeMarked = members.filter((row) => row.markSource === "close").length;
|
|
436
|
+
const converted = members.filter((row) => row.convertedFrom != null).length;
|
|
437
|
+
const held = new Set(holdings.map((row) => row.id));
|
|
438
|
+
// Caveats about an estimate that was made; the warnings are what failed.
|
|
439
|
+
const notes = [
|
|
223
440
|
...(closeMarked
|
|
224
441
|
? [
|
|
225
442
|
`${closeMarked} holding${closeMarked === 1 ? "" : "s"} had no current quote; weighted at the latest completed close.`,
|
|
226
443
|
]
|
|
227
444
|
: []),
|
|
445
|
+
// Daily closes pair by date, so a market that closes before or after the US session is not synchronous with it.
|
|
446
|
+
...(converted
|
|
447
|
+
? [
|
|
448
|
+
"Converted holdings are matched to the US close of the same date; where their market closes at another time, correlations and betas to US holdings read lower than they are.",
|
|
449
|
+
]
|
|
450
|
+
: []),
|
|
451
|
+
];
|
|
452
|
+
const warnings = [
|
|
453
|
+
...market.warnings,
|
|
454
|
+
// A held instrument's failure is its left-out reason; factor proxies report here.
|
|
228
455
|
...market.histories.flatMap((row) =>
|
|
229
|
-
row.error
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
row.error ? [`${row.symbol}: ${row.error}`] : [],
|
|
456
|
+
row.error && !held.has(riskInstrumentId(row.instrument))
|
|
457
|
+
? [`${row.instrument.symbol}: ${row.error}`]
|
|
458
|
+
: [],
|
|
233
459
|
),
|
|
234
460
|
];
|
|
235
|
-
const
|
|
236
|
-
holdings.length > 0 &&
|
|
237
|
-
holdings.length <= 80 &&
|
|
238
|
-
book != null &&
|
|
239
|
-
holdings.every(
|
|
240
|
-
(row) =>
|
|
241
|
-
!row.error &&
|
|
242
|
-
row.value != null &&
|
|
243
|
-
row.value > 0 &&
|
|
244
|
-
row.returns.length >= 60,
|
|
245
|
-
);
|
|
246
|
-
if (holdings.length > 80)
|
|
247
|
-
warnings.push("Basket risk supports at most 80 holdings");
|
|
248
|
-
if (!completeBasket && holdings.length)
|
|
249
|
-
warnings.push(
|
|
250
|
-
"Basket estimates require complete, positive USD equity marks and matched daily history for every holding.",
|
|
251
|
-
);
|
|
252
|
-
const basket = completeBasket
|
|
461
|
+
const basket = members.length
|
|
253
462
|
? computeWeightedPortfolioReturns(
|
|
254
|
-
|
|
463
|
+
members.map((row) => ({ weight: row.weight!, returns: row.returns })),
|
|
255
464
|
)
|
|
256
465
|
: [];
|
|
257
466
|
const proxy = (symbol: string) => {
|
|
@@ -290,8 +499,8 @@ export function buildPortfolioRisk(
|
|
|
290
499
|
...rollingBeta(basket, factor.series, factor.label, factor.id),
|
|
291
500
|
regression: regressReturns(basket.slice(-60), factor.series),
|
|
292
501
|
}));
|
|
293
|
-
const correlation =
|
|
294
|
-
|
|
502
|
+
const correlation = members.flatMap((left, index) =>
|
|
503
|
+
members.slice(index + 1).map((right) => {
|
|
295
504
|
const regression = regressReturns(left.returns.slice(-60), right.returns);
|
|
296
505
|
return {
|
|
297
506
|
left: left.id,
|
|
@@ -332,11 +541,11 @@ export function buildPortfolioRisk(
|
|
|
332
541
|
value: regression ? regression.beta * stress.shock * 100 : null,
|
|
333
542
|
};
|
|
334
543
|
});
|
|
335
|
-
if (
|
|
544
|
+
if (sufficient)
|
|
336
545
|
for (const factor of factors)
|
|
337
546
|
if (factor.samples === 0)
|
|
338
547
|
warnings.push(`${factor.label}: no matched factor history`);
|
|
339
|
-
if (
|
|
548
|
+
if (sufficient && metrics.every((row) => row.value == null))
|
|
340
549
|
warnings.push("Fewer than 60 consecutive matched completed daily returns.");
|
|
341
550
|
const performance = evidence?.performance
|
|
342
551
|
? calculateAccountPerformance(evidence.performance)
|
|
@@ -359,26 +568,28 @@ export function buildPortfolioRisk(
|
|
|
359
568
|
risk: metrics.map((row) => ({
|
|
360
569
|
...row,
|
|
361
570
|
percentile: row.rank.percentile,
|
|
362
|
-
|
|
571
|
+
// The method (price returns at fixed current weights) is in docs; the footer keeps room for coverage.
|
|
572
|
+
detail: `${row.samples} sessions`,
|
|
363
573
|
})),
|
|
364
574
|
factors: factors.map((row) => ({
|
|
365
575
|
...row,
|
|
366
576
|
percentile: row.rank.percentile,
|
|
367
577
|
detail: `${row.samples} sessions; R² ${row.regression?.rSquared?.toFixed(2) ?? "--"}; independent ETF proxy`,
|
|
368
578
|
})),
|
|
369
|
-
// Largest
|
|
579
|
+
// Largest current value first, left-out holdings in place; unvalued ones last.
|
|
370
580
|
holdings: [...holdings]
|
|
371
|
-
.sort((a, b) => (b.
|
|
581
|
+
.sort((a, b) => (b.marketValue ?? -1) - (a.marketValue ?? -1))
|
|
372
582
|
.map((row) => ({
|
|
373
583
|
id: row.id,
|
|
374
584
|
label: row.symbol,
|
|
375
585
|
value: row.weight == null ? null : row.weight * 100,
|
|
376
|
-
unit: "%
|
|
586
|
+
unit: "% basket",
|
|
377
587
|
percentile: null,
|
|
378
588
|
asOf: row.priceAsOf,
|
|
379
|
-
detail:
|
|
380
|
-
row.
|
|
381
|
-
`${row.quantity} shares; ${formatNumber(row.value ?? undefined)} ${row.currency}${row.markSource === "close" ? ` at ${row.priceAsOf} close` : ""}; history ${row.historyAsOf}`,
|
|
589
|
+
detail: row.leftOut
|
|
590
|
+
? row.leftOut
|
|
591
|
+
: `${row.quantity} shares; ${formatNumber(row.value ?? undefined)} ${row.currency}${row.markSource === "close" ? ` at ${row.priceAsOf} close` : ""}${row.convertedFrom ? ` from ${row.convertedFrom} at daily FX` : ""}; history ${row.historyAsOf}`,
|
|
592
|
+
...(row.leftOut ? { leftOut: row.leftOut } : {}),
|
|
382
593
|
})),
|
|
383
594
|
correlation: correlation.map((row) => ({
|
|
384
595
|
id: `${row.left}/${row.right}`,
|
|
@@ -504,19 +715,19 @@ export function buildPortfolioRisk(
|
|
|
504
715
|
id: "top",
|
|
505
716
|
label: "Largest holding",
|
|
506
717
|
value: book.top * 100,
|
|
507
|
-
unit: "%
|
|
718
|
+
unit: "% basket",
|
|
508
719
|
percentile: null,
|
|
509
720
|
asOf: market.fetchedAt,
|
|
510
|
-
detail: "
|
|
721
|
+
detail: "Current value in the covered basket",
|
|
511
722
|
},
|
|
512
723
|
{
|
|
513
724
|
id: "top-five",
|
|
514
725
|
label: "Largest five",
|
|
515
726
|
value: book.topFive * 100,
|
|
516
|
-
unit: "%
|
|
727
|
+
unit: "% basket",
|
|
517
728
|
percentile: null,
|
|
518
729
|
asOf: market.fetchedAt,
|
|
519
|
-
detail: "
|
|
730
|
+
detail: "Current value in the covered basket",
|
|
520
731
|
},
|
|
521
732
|
{
|
|
522
733
|
id: "hhi",
|
|
@@ -543,14 +754,21 @@ export function buildPortfolioRisk(
|
|
|
543
754
|
greeks,
|
|
544
755
|
evidence,
|
|
545
756
|
rows,
|
|
546
|
-
|
|
757
|
+
coverage,
|
|
758
|
+
complete:
|
|
759
|
+
sufficient &&
|
|
760
|
+
coverage.leftOut.length === 0 &&
|
|
761
|
+
metrics.some((row) => row.value != null),
|
|
547
762
|
warnings: [...new Set(warnings)],
|
|
763
|
+
notes,
|
|
548
764
|
fetchedAt: market.fetchedAt,
|
|
549
765
|
};
|
|
550
766
|
}
|
|
551
767
|
export type PortfolioRiskModel = ReturnType<typeof buildPortfolioRisk>;
|
|
552
768
|
export const riskValue = (row: RiskDisplayRow) =>
|
|
553
|
-
row.
|
|
769
|
+
row.leftOut
|
|
770
|
+
? "left out"
|
|
771
|
+
: row.value == null
|
|
554
772
|
? "--"
|
|
555
773
|
: `${row.value.toFixed(2)}${row.unit === "%" ? "%" : ` ${row.unit}`}`;
|
|
556
774
|
export const riskPercentile = (row: RiskDisplayRow) =>
|