gloomberb 0.11.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/README.zh-CN.md +4 -2
- package/package.json +28 -1
- package/src/api-client/auth.ts +10 -0
- package/src/api-client/data.ts +108 -1
- package/src/api-client/index.test.ts +127 -0
- package/src/api-client/index.ts +134 -1
- package/src/api-client/normalizers.ts +39 -0
- package/src/api-client/paths.ts +85 -1
- package/src/api-client/types.ts +220 -0
- package/src/app/pane-runtime/index.tsx +15 -12
- package/src/app/pane-runtime/layout-placement.test.ts +27 -0
- package/src/app/pane-runtime/layout-placement.ts +13 -0
- package/src/app/pane-runtime/plugin-bindings.ts +62 -0
- package/src/app.tsx +60 -18
- package/src/architecture/browser-entry-graph.test.ts +96 -0
- package/src/brokers/profile-form.test.ts +25 -27
- package/src/brokers/test-broker.ts +68 -0
- package/src/capabilities/chart-series.ts +3 -2
- package/src/cli/commands/market.ts +2 -2
- package/src/cli/commands/plugins.ts +39 -11
- package/src/cli/desktop-pane-shot.ts +285 -16
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/capabilities.ts +61 -31
- package/src/cli/pane-functions/catalog.ts +16 -4
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/headless.test.ts +247 -0
- package/src/cli/pane-functions/headless.ts +423 -0
- package/src/cli/pane-functions/index.test.ts +9 -0
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +27 -2
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +26 -8
- package/src/cli/pane-functions/screenshot.test.ts +76 -0
- package/src/cli/pane-functions/screenshot.ts +236 -20
- package/src/cli/registry.ts +0 -22
- package/src/cli/restore-plugins.ts +34 -0
- package/src/cli/result.ts +7 -10
- package/src/components/chart/{static/chart → composite}/axis-overlays.test.tsx +3 -3
- package/src/components/chart/{static/chart → composite}/axis-overlays.tsx +6 -11
- package/src/components/chart/{static/chart → composite}/bitmap.ts +17 -3
- package/src/components/chart/composite/composite-chart.test.tsx +68 -20
- package/src/components/chart/composite/composite-chart.tsx +301 -204
- package/src/components/chart/composite/format.ts +8 -2
- package/src/components/chart/composite/interactions.test.ts +68 -102
- package/src/components/chart/composite/interactions.ts +214 -264
- package/src/components/chart/composite/price-axis-labels.test.ts +21 -0
- package/src/components/chart/{price-axis-labels.tsx → composite/price-axis-labels.tsx} +9 -4
- package/src/components/chart/composite/scene.ts +57 -3
- package/src/components/chart/composite/text-renderer.ts +3 -2
- package/src/components/chart/composite/time-scale.ts +138 -57
- package/src/components/chart/composite/types.ts +25 -1
- package/src/components/chart/core/data.ts +9 -13
- package/src/components/chart/core/date-window.ts +7 -1
- package/src/components/chart/core/pointer.ts +3 -0
- package/src/components/chart/core/types.ts +0 -45
- package/src/components/chart/native/chart-rasterizer.ts +0 -1
- package/src/components/chart/native/kitty/index.test.ts +0 -188
- package/src/components/chart/native/raster/crosshair.ts +6 -5
- package/src/components/chart/native/raster/primitives.ts +0 -23
- package/src/components/chart/native/renderer-selection.ts +81 -31
- package/src/components/chart/static/{chart/surface.test.tsx → chart-surface.test.tsx} +28 -80
- package/src/components/chart/static/chart-surface.tsx +150 -0
- package/src/components/chart/static/index.ts +8 -0
- package/src/components/chart/static/multi-line-chart-surface.tsx +51 -166
- package/src/components/chart/static/scatter-chart-surface.test.ts +30 -0
- package/src/components/chart/static/scatter-chart-surface.tsx +135 -34
- package/src/components/chart/static/series.ts +49 -0
- package/src/components/command-bar/action-runtime.ts +1 -3
- package/src/components/command-bar/assist/model.test.ts +17 -2
- package/src/components/command-bar/assist/model.ts +40 -9
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +1 -1
- package/src/components/command-bar/commands/registry.ts +0 -11
- package/src/components/command-bar/helpers.test.ts +2 -2
- package/src/components/command-bar/helpers.ts +2 -6
- package/src/components/command-bar/keyboard-shortcuts.ts +0 -11
- package/src/components/command-bar/list/badge.test.ts +54 -0
- package/src/components/command-bar/list/badge.ts +62 -0
- package/src/components/command-bar/list/model.test.ts +103 -0
- package/src/components/command-bar/list/model.ts +61 -4
- package/src/components/command-bar/list/view.test.tsx +113 -0
- package/src/components/command-bar/list/view.tsx +147 -131
- package/src/components/command-bar/pane-templates/workflow.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +51 -65
- package/src/components/command-bar/panel/index.tsx +48 -13
- package/src/components/command-bar/panel/layout.test.ts +139 -0
- package/src/components/command-bar/panel/layout.ts +65 -28
- package/src/components/command-bar/panel/native-surface.ts +24 -0
- package/src/components/command-bar/panel/prompt-binding.ts +54 -0
- package/src/components/command-bar/panel/runtime.ts +6 -3
- package/src/components/command-bar/panel/state.ts +41 -7
- package/src/components/command-bar/panel/types.ts +7 -1
- package/src/components/command-bar/routes/root/provider-search.ts +34 -15
- package/src/components/command-bar/routes/root/results.test.ts +161 -0
- package/src/components/command-bar/routes/root/results.ts +30 -28
- package/src/components/command-bar/routes/root/runtime.ts +37 -20
- package/src/components/command-bar/routes/root/search-providers.test.tsx +224 -0
- package/src/components/command-bar/routes/root/search-providers.ts +205 -0
- package/src/components/command-bar/routes/root/selection.ts +1 -12
- package/src/components/command-bar/routes/root/shortcuts.test.ts +8 -8
- package/src/components/command-bar/routes/ticker-search/actions.ts +10 -9
- package/src/components/command-bar/routes/ticker-search/results.test.ts +54 -1
- package/src/components/command-bar/routes/ticker-search/results.ts +60 -19
- package/src/components/command-bar/routes/ticker-search/route.ts +1 -0
- package/src/components/command-bar/routing/actions.ts +1 -81
- package/src/components/command-bar/routing/launch-request.ts +1 -1
- package/src/components/command-bar/routing/list-state.ts +6 -21
- package/src/components/command-bar/selection-runtime.ts +1 -1
- package/src/components/command-bar/surface/assist.test.tsx +14 -10
- package/src/components/command-bar/surface/environment.ts +8 -1
- package/src/components/command-bar/surface/index.test.tsx +84 -68
- package/src/components/command-bar/surface/index.tsx +33 -36
- package/src/components/command-bar/surface/test-harness.tsx +15 -3
- package/src/components/command-bar/theme-picker.tsx +43 -15
- package/src/components/command-bar/view-model.test.ts +53 -8
- package/src/components/command-bar/view-model.ts +43 -14
- package/src/components/command-bar/workflow/tickers.ts +1 -0
- package/src/components/command-bar/workflow/types.ts +1 -1
- package/src/components/data-table/export.test.ts +21 -0
- package/src/components/data-table/export.ts +21 -0
- package/src/components/data-table/view.test.tsx +45 -6
- package/src/components/data-table/view.tsx +55 -9
- package/src/components/index.ts +10 -2
- package/src/components/input-search-bar.test.tsx +36 -2
- package/src/components/input-search-bar.tsx +18 -1
- package/src/components/layout/header.test.tsx +57 -10
- package/src/components/layout/header.tsx +292 -149
- package/src/components/layout/market-summary.test.ts +81 -0
- package/src/components/layout/market-summary.ts +109 -0
- package/src/components/layout/shell/chrome.ts +96 -1
- package/src/components/layout/shell/index.tsx +11 -3
- package/src/components/layout/shell/menu.ts +9 -0
- package/src/components/layout/shell/pane/actions.ts +29 -0
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/shortcuts.ts +3 -0
- package/src/components/layout/status-bar.test.tsx +9 -8
- package/src/components/layout/status-bar.tsx +85 -54
- package/src/components/onboarding/onboarding-frame.tsx +2 -26
- package/src/components/price-sparkline/index.ts +61 -34
- package/src/components/price-sparkline/view.tsx +1 -1
- package/src/components/sign-in-gate.test.tsx +128 -0
- package/src/components/sign-in-gate.tsx +149 -0
- package/src/components/speedometer-gauge/desktop.tsx +2 -12
- package/src/components/ticker/badge/list.tsx +17 -3
- package/src/components/ticker/list-table-view.tsx +6 -3
- package/src/components/ui/data-table/index.tsx +22 -4
- package/src/components/ui/data-table/opentui/index.tsx +165 -120
- package/src/components/ui/frame.tsx +28 -0
- package/src/components/ui/index.ts +3 -0
- package/src/components/ui/native-select.tsx +20 -10
- package/src/components/ui/select-button.tsx +138 -0
- package/src/components/ui/status.tsx +2 -2
- package/src/components/ui/table-layout.ts +1 -1
- package/src/components/use-double-click-activation.ts +7 -3
- package/src/core/app-services.ts +3 -3
- package/src/data/config/chart-settings.ts +4 -4
- package/src/data/config/layout.ts +12 -6
- package/src/data/config/store/index.test.ts +97 -0
- package/src/data/config/store/migrations.ts +41 -0
- package/src/data/config/store/normalize.ts +5 -3
- package/src/i18n/es.ts +6 -2
- package/src/i18n/ja.ts +6 -2
- package/src/i18n/ko.ts +6 -2
- package/src/i18n/zh-cn.ts +6 -2
- package/src/i18n/zh-tw.ts +6 -2
- package/src/layout-marketplace/gallery-terminal.tsx +126 -96
- package/src/layout-marketplace/gallery.test.tsx +65 -1
- package/src/layout-marketplace/pane-imagery.ts +1 -0
- package/src/layout-marketplace/payload.test.ts +17 -0
- package/src/layout-marketplace/payload.ts +40 -5
- package/src/market-data/coordinator/index.ts +3 -2
- package/src/market-data/coordinator/quotes.ts +173 -66
- package/src/market-data/coordinator/subscriptions.test.ts +215 -37
- package/src/pane-settings.ts +1 -1
- package/src/plugins/builtin/analytics/pane-model.ts +1 -1
- package/src/plugins/builtin/analytics/view.tsx +1 -1
- package/src/plugins/builtin/broker-manager/index.test.tsx +3 -2
- package/src/plugins/builtin/broker-manager/model.test.ts +2 -2
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +16 -2
- package/src/plugins/builtin/chart-composer/cli-options.ts +12 -9
- package/src/plugins/builtin/chart-composer/pane.tsx +22 -8
- package/src/plugins/builtin/chart-composer/settings.ts +2 -13
- package/src/plugins/builtin/chat/content/composer.tsx +8 -4
- package/src/plugins/builtin/cloud/auth-dialog.tsx +14 -228
- package/src/plugins/builtin/cloud/auth-form.tsx +277 -0
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/composite-plugins.ts +16 -1
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +2 -6
- package/src/plugins/builtin/correlation/relationship/view-model.ts +2 -2
- package/src/plugins/builtin/credit-conditions/index.test.tsx +12 -6
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -21
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/earnings/index.tsx +1 -0
- package/src/plugins/builtin/earnings-calls/data.ts +223 -0
- package/src/plugins/builtin/earnings-calls/format.ts +49 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +69 -0
- package/src/plugins/builtin/earnings-calls/pane.tsx +756 -0
- package/src/plugins/builtin/earnings-calls/prose.test.ts +36 -0
- package/src/plugins/builtin/earnings-calls/prose.ts +59 -0
- package/src/plugins/builtin/earnings-calls/transcript-view.tsx +334 -0
- package/src/plugins/builtin/econ/detail-view.tsx +1 -2
- package/src/plugins/builtin/econ/fred-series-map.ts +16 -1
- package/src/plugins/builtin/econ/index.tsx +3 -1
- package/src/plugins/builtin/econ-statistics/cache.ts +4 -0
- package/src/plugins/builtin/econ-statistics/client.ts +92 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +66 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +154 -0
- package/src/plugins/builtin/econ-statistics/headless.test.ts +54 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +171 -0
- package/src/plugins/builtin/econ-statistics/index.tsx +54 -0
- package/src/plugins/builtin/econ-statistics/pane.tsx +356 -0
- package/src/plugins/builtin/econ-statistics/stats.ts +522 -0
- package/src/plugins/builtin/econ-statistics/transform.test.ts +86 -0
- package/src/plugins/builtin/econ-statistics/transform.ts +85 -0
- package/src/plugins/builtin/econ-statistics/trend.ts +57 -0
- package/src/plugins/builtin/econ-statistics/view.ts +90 -0
- package/src/plugins/builtin/fear-greed/charts.tsx +7 -18
- package/src/plugins/builtin/fear-greed/data.ts +6 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +1 -0
- package/src/plugins/builtin/help/index.tsx +4 -0
- package/src/plugins/builtin/holders/index.tsx +1 -0
- package/src/plugins/builtin/insider/index.tsx +1 -0
- package/src/plugins/builtin/ipo-calendar/index.tsx +1 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/sections.tsx +2 -3
- package/src/plugins/builtin/market-halts/index.tsx +1 -0
- package/src/plugins/builtin/market-movers/index.tsx +1 -0
- package/src/plugins/builtin/market-valuation/align.ts +122 -0
- package/src/plugins/builtin/market-valuation/cache.ts +32 -0
- package/src/plugins/builtin/market-valuation/chart-projection.ts +217 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +89 -0
- package/src/plugins/builtin/market-valuation/client.test.ts +141 -0
- package/src/plugins/builtin/market-valuation/client.ts +116 -0
- package/src/plugins/builtin/market-valuation/defs.ts +251 -0
- package/src/plugins/builtin/market-valuation/detail.tsx +159 -0
- package/src/plugins/builtin/market-valuation/headless.test.ts +58 -0
- package/src/plugins/builtin/market-valuation/headless.ts +170 -0
- package/src/plugins/builtin/market-valuation/index.tsx +64 -0
- package/src/plugins/builtin/market-valuation/indicators.ts +422 -0
- package/src/plugins/builtin/market-valuation/model.test.ts +350 -0
- package/src/plugins/builtin/market-valuation/model.ts +8 -0
- package/src/plugins/builtin/market-valuation/pane.test.tsx +247 -0
- package/src/plugins/builtin/market-valuation/pane.tsx +344 -0
- package/src/plugins/builtin/market-valuation/series.ts +12 -0
- package/src/plugins/builtin/market-valuation/settings.ts +38 -0
- package/src/plugins/builtin/market-valuation/sources.ts +130 -0
- package/src/plugins/builtin/market-valuation/trend.ts +89 -0
- package/src/plugins/builtin/market-valuation/view.ts +137 -0
- package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +123 -0
- package/src/plugins/builtin/market-valuation/zone-scale/index.tsx +12 -0
- package/src/plugins/builtin/market-valuation/zone-scale/model.ts +60 -0
- package/src/plugins/builtin/market-valuation/zone-scale/terminal.tsx +94 -0
- package/src/plugins/builtin/news/wire/breaking/filters.test.ts +99 -0
- package/src/plugins/builtin/news/wire/breaking/filters.ts +110 -0
- package/src/plugins/builtin/news/wire/breaking/notifications.test.ts +157 -53
- package/src/plugins/builtin/news/wire/breaking/notifications.ts +91 -25
- package/src/plugins/builtin/news/wire/index.tsx +31 -44
- package/src/plugins/builtin/options/analytics.test.ts +83 -0
- package/src/plugins/builtin/options/analytics.ts +110 -0
- package/src/plugins/builtin/options/index.tsx +18 -2
- package/src/plugins/builtin/options/table.ts +121 -51
- package/src/plugins/builtin/options/types.ts +22 -15
- package/src/plugins/builtin/options/view.test.tsx +53 -1
- package/src/plugins/builtin/options/view.tsx +92 -41
- package/src/plugins/builtin/plugin-marketplace/feed.ts +80 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +31 -0
- package/src/plugins/builtin/plugin-marketplace/model.test.ts +200 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +204 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +385 -0
- package/src/plugins/builtin/plugin-marketplace/store.ts +46 -0
- package/src/plugins/builtin/plugin-module.test.ts +2 -4
- package/src/plugins/builtin/plugin-module.ts +9 -8
- package/src/plugins/builtin/portfolio-list/index.tsx +1 -0
- package/src/plugins/builtin/research/index.tsx +4 -0
- package/src/plugins/builtin/research-search/command-bar-search.test.ts +81 -0
- package/src/plugins/builtin/research-search/command-bar-search.ts +175 -0
- package/src/plugins/builtin/research-search/data.ts +109 -0
- package/src/plugins/builtin/research-search/document-view.test.tsx +75 -0
- package/src/plugins/builtin/research-search/document-view.tsx +254 -0
- package/src/plugins/builtin/research-search/filter-bar.tsx +62 -0
- package/src/plugins/builtin/research-search/focus-handoff.ts +47 -0
- package/src/plugins/builtin/research-search/index.tsx +85 -0
- package/src/plugins/builtin/research-search/model.test.ts +40 -0
- package/src/plugins/builtin/research-search/model.ts +291 -0
- package/src/plugins/builtin/research-search/pane.test.tsx +241 -0
- package/src/plugins/builtin/research-search/pane.tsx +678 -0
- package/src/plugins/builtin/research-search/saved-view.tsx +171 -0
- package/src/plugins/builtin/research-search/snippet-text.tsx +35 -0
- package/src/plugins/builtin/research-search/snippet.test.ts +78 -0
- package/src/plugins/builtin/research-search/snippet.ts +134 -0
- package/src/plugins/builtin/scanner/flow-model.test.ts +11 -1
- package/src/plugins/builtin/scanner/flow-model.ts +29 -1
- package/src/plugins/builtin/scanner/flow-pane.tsx +78 -22
- package/src/plugins/builtin/scanner/index.ts +2 -0
- package/src/plugins/builtin/sec/index.tsx +1 -0
- package/src/plugins/builtin/sectors/index.tsx +1 -0
- package/src/plugins/builtin/shared/series-cache.ts +93 -0
- package/src/plugins/builtin/short-interest/index.tsx +1 -0
- package/src/plugins/builtin/short-interest/pane.tsx +1 -1
- package/src/plugins/builtin/thirteenf/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +3 -5
- package/src/plugins/builtin/ticker-detail/index.tsx +2 -14
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +1 -1
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/volatility/index.tsx +1 -1
- package/src/plugins/builtin/world-indices/index.tsx +1 -0
- package/src/plugins/builtin/world-venue-map/index.ts +27 -0
- package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +106 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +481 -0
- package/src/plugins/builtin/world-venue-map/model.test.ts +85 -0
- package/src/plugins/builtin/world-venue-map/model.ts +268 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +300 -0
- package/src/plugins/builtin/world-venue-map/world-outlines.ts +2 -0
- package/src/plugins/builtin/yield-curve/index.tsx +1 -1
- package/src/plugins/bundle.test.ts +109 -0
- package/src/plugins/bundle.ts +139 -0
- package/src/plugins/catalog-backend.ts +6 -44
- package/src/plugins/catalog-browser.test.ts +1 -0
- package/src/plugins/catalog-browser.ts +12 -0
- package/src/plugins/catalog-manifest.test.ts +43 -0
- package/src/plugins/catalog-manifest.ts +92 -0
- package/src/plugins/catalog-ui.ts +20 -4
- package/src/plugins/catalog.ts +9 -2
- package/src/plugins/current-target.ts +28 -0
- package/src/plugins/host-contract.ts +37 -0
- package/src/plugins/host-link.ts +158 -0
- package/src/plugins/host-modules.ts +61 -0
- package/src/plugins/loader.ts +41 -22
- package/src/plugins/ownership.ts +1 -0
- package/src/plugins/prediction-markets/index.tsx +1 -0
- package/src/plugins/registry/context.ts +3 -0
- package/src/plugins/registry/contributions.ts +27 -0
- package/src/plugins/registry/index.test.ts +25 -0
- package/src/plugins/registry/index.ts +8 -0
- package/src/plugins/registry/pane-settings.test.ts +53 -0
- package/src/plugins/registry/pane-settings.ts +29 -3
- package/src/plugins/seed.test.ts +83 -0
- package/src/plugins/seed.ts +80 -0
- package/src/public/broker.ts +31 -0
- package/src/public/market-data.ts +9 -0
- package/src/public/pane-hooks.ts +57 -0
- package/src/public/public-api.test.ts +285 -0
- package/src/public/react.ts +62 -0
- package/src/public/test-support.ts +23 -0
- package/src/public/time-series.ts +8 -0
- package/src/public/utils.ts +77 -0
- package/src/remote/layout-helpers.ts +6 -8
- package/src/remote/resources.ts +2 -0
- package/src/remote/schema.ts +1 -0
- package/src/remote/semantic-tree.test.tsx +105 -0
- package/src/remote/semantic-tree.tsx +53 -35
- package/src/renderers/browser/main.tsx +6 -0
- package/src/renderers/browser/ui-host.tsx +11 -0
- package/src/renderers/cloudflare/worker.test.ts +19 -0
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -2
- package/src/renderers/electrobun/bun/external-plugins.ts +140 -0
- package/src/renderers/electrobun/bun/index.ts +6 -2
- package/src/renderers/electrobun/shared/protocol.ts +25 -0
- package/src/renderers/electrobun/view/build-assets.ts +0 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +51 -1
- package/src/renderers/electrobun/view/external-plugins.test.ts +45 -0
- package/src/renderers/electrobun/view/external-plugins.ts +63 -0
- package/src/renderers/electrobun/view/host/ascii-text.test.ts +48 -0
- package/src/renderers/electrobun/view/host/ascii-text.ts +11 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +38 -32
- package/src/renderers/electrobun/view/host/mouse.ts +16 -2
- package/src/renderers/electrobun/view/main.tsx +27 -2
- package/src/renderers/electrobun/view/styles.css +5 -0
- package/src/renderers/electrobun/view/toast-host.tsx +18 -0
- package/src/renderers/electrobun/view/ui-host.tsx +3 -0
- package/src/renderers/opentui/chart-surface.tsx +5 -1
- package/src/renderers/opentui/host.tsx +20 -2
- package/src/renderers/opentui/interaction-performance.test.ts +79 -0
- package/src/renderers/opentui/interaction-performance.ts +188 -0
- package/src/renderers/opentui/start.tsx +26 -1
- package/src/renderers/opentui/test-utils.tsx +13 -0
- package/src/renderers/opentui/toast-host.tsx +26 -2
- package/src/renderers/opentui/ui-host.tsx +1 -0
- package/src/sources/provider-router/search.test.ts +191 -0
- package/src/sources/provider-router/search.ts +92 -39
- package/src/state/app/context/index.tsx +2 -0
- package/src/state/app/context/selector.test.tsx +33 -1
- package/src/state/hooks/quote-streaming.test.tsx +93 -0
- package/src/state/hooks/quote-streaming.ts +106 -30
- package/src/state/pane-table-export-registry.ts +50 -0
- package/src/theme/color-utils.ts +1 -1
- package/src/theme/colors.ts +50 -0
- package/src/theme/themes.test.ts +15 -2
- package/src/theme/themes.ts +19 -1
- package/src/tickers/search/index.test.ts +26 -0
- package/src/tickers/search/index.ts +42 -17
- package/src/tickers/search/ranking.ts +14 -0
- package/src/time-series/chart-data.test.ts +216 -0
- package/src/time-series/range.ts +12 -0
- package/src/time-series/resolution.test.ts +25 -26
- package/src/time-series/resolution.ts +44 -25
- package/src/time-series/resolve.ts +7 -0
- package/src/time-series/spec.ts +5 -5
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.ts +5 -0
- package/src/types/config.ts +123 -3
- package/src/types/data-provider.ts +11 -0
- package/src/types/headless.ts +161 -0
- package/src/types/plugin.ts +104 -20
- package/src/ui/host.tsx +19 -1
- package/src/ui/index.tsx +1 -0
- package/src/ui/toast.tsx +8 -4
- package/src/utils/csv.test.ts +13 -0
- package/src/utils/csv.ts +37 -0
- package/src/utils/format.ts +35 -0
- package/src/utils/fuzzy-search.test.ts +94 -0
- package/src/utils/fuzzy-search.ts +81 -22
- package/src/utils/save-text-file.test.ts +24 -0
- package/src/utils/save-text-file.ts +36 -0
- package/src/utils/shortcut-labels.ts +14 -0
- package/src/components/chart/core/axis-format.ts +0 -157
- package/src/components/chart/core/index.test.ts +0 -1075
- package/src/components/chart/core/projection.ts +0 -357
- package/src/components/chart/core/render-utils.ts +0 -4
- package/src/components/chart/core/renderer.ts +0 -244
- package/src/components/chart/core/scene.ts +0 -180
- package/src/components/chart/core/time-axis.ts +0 -330
- package/src/components/chart/cursor-motion.ts +0 -47
- package/src/components/chart/indicators/types.ts +0 -26
- package/src/components/chart/market-session.ts +0 -176
- package/src/components/chart/multi-line/renderer.test.ts +0 -83
- package/src/components/chart/multi-line/renderer.ts +0 -161
- package/src/components/chart/multi-line/scene.ts +0 -188
- package/src/components/chart/native/raster/layout.ts +0 -129
- package/src/components/chart/native/raster/price-chart.ts +0 -244
- package/src/components/chart/rendering/chart-draw.ts +0 -270
- package/src/components/chart/rendering/geometry.ts +0 -95
- package/src/components/chart/rendering/pixel-buffer.ts +0 -267
- package/src/components/chart/scatter-chart-renderer.test.ts +0 -31
- package/src/components/chart/scatter-chart-renderer.ts +0 -223
- package/src/components/chart/static/chart/surface.tsx +0 -358
- package/src/components/command-bar/routes/root/article-results.test.ts +0 -83
- package/src/components/command-bar/routes/root/article-results.ts +0 -55
- package/src/plugins/builtin/news/wire/article-search.test.ts +0 -72
- package/src/plugins/builtin/news/wire/article-search.ts +0 -140
- package/src/plugins/builtin/substack/api/auth.ts +0 -185
- package/src/plugins/builtin/substack/api/cache.ts +0 -82
- package/src/plugins/builtin/substack/api/loaders.ts +0 -170
- package/src/plugins/builtin/substack/api/store.ts +0 -186
- package/src/plugins/builtin/substack/api/types.ts +0 -42
- package/src/plugins/builtin/substack/api.test.ts +0 -298
- package/src/plugins/builtin/substack/article-detail.tsx +0 -397
- package/src/plugins/builtin/substack/article-stack.tsx +0 -133
- package/src/plugins/builtin/substack/content.ts +0 -478
- package/src/plugins/builtin/substack/feed-tabs.tsx +0 -44
- package/src/plugins/builtin/substack/index.tsx +0 -49
- package/src/plugins/builtin/substack/login-view.tsx +0 -126
- package/src/plugins/builtin/substack/model.test.ts +0 -155
- package/src/plugins/builtin/substack/normalize.ts +0 -343
- package/src/plugins/builtin/substack/pane-footer.ts +0 -52
- package/src/plugins/builtin/substack/pane-state.ts +0 -170
- package/src/plugins/builtin/substack/pane.tsx +0 -547
- package/src/plugins/builtin/substack/read-state.ts +0 -30
- package/src/plugins/builtin/substack/table.ts +0 -111
- package/src/plugins/builtin/substack/types.ts +0 -71
- package/src/plugins/builtin/substack/utils.ts +0 -131
- package/src/plugins/builtin/ticker-detail/data-panes/provider-search.tsx +0 -229
- package/src/plugins/ibkr/account-cache.test.ts +0 -102
- package/src/plugins/ibkr/account-cache.ts +0 -24
- package/src/plugins/ibkr/broker-adapter.ts +0 -286
- package/src/plugins/ibkr/config.test.ts +0 -79
- package/src/plugins/ibkr/config.ts +0 -250
- package/src/plugins/ibkr/dialogs.tsx +0 -40
- package/src/plugins/ibkr/flex/index.test.ts +0 -264
- package/src/plugins/ibkr/flex/index.ts +0 -367
- package/src/plugins/ibkr/flex/statement-client.ts +0 -235
- package/src/plugins/ibkr/fundamental-parser.ts +0 -149
- package/src/plugins/ibkr/gateway/account-loaders.ts +0 -266
- package/src/plugins/ibkr/gateway/account-summary.ts +0 -164
- package/src/plugins/ibkr/gateway/client-lock.ts +0 -154
- package/src/plugins/ibkr/gateway/connection-events.ts +0 -114
- package/src/plugins/ibkr/gateway/connection.ts +0 -152
- package/src/plugins/ibkr/gateway/contracts.ts +0 -132
- package/src/plugins/ibkr/gateway/fundamentals.ts +0 -83
- package/src/plugins/ibkr/gateway/helpers.ts +0 -33
- package/src/plugins/ibkr/gateway/history-requests.ts +0 -158
- package/src/plugins/ibkr/gateway/history.ts +0 -120
- package/src/plugins/ibkr/gateway/instrument-lookup.ts +0 -117
- package/src/plugins/ibkr/gateway/market-data.ts +0 -345
- package/src/plugins/ibkr/gateway/order-execution.ts +0 -218
- package/src/plugins/ibkr/gateway/orders.ts +0 -63
- package/src/plugins/ibkr/gateway/price-normalization.test.ts +0 -44
- package/src/plugins/ibkr/gateway/price-normalization.ts +0 -50
- package/src/plugins/ibkr/gateway/quote-stream-controller.ts +0 -203
- package/src/plugins/ibkr/gateway/quote-stream.ts +0 -171
- package/src/plugins/ibkr/gateway/selection.ts +0 -51
- package/src/plugins/ibkr/gateway/service/index.test.ts +0 -675
- package/src/plugins/ibkr/gateway/service/index.ts +0 -429
- package/src/plugins/ibkr/gateway/service/lifecycle.ts +0 -191
- package/src/plugins/ibkr/gateway/service/manager.ts +0 -52
- package/src/plugins/ibkr/gateway/service/market-data.ts +0 -48
- package/src/plugins/ibkr/gateway/service/native-loader.ts +0 -12
- package/src/plugins/ibkr/gateway/service/native.ts +0 -543
- package/src/plugins/ibkr/gateway/timeouts.ts +0 -13
- package/src/plugins/ibkr/gateway/types.ts +0 -27
- package/src/plugins/ibkr/index.test.tsx +0 -162
- package/src/plugins/ibkr/index.tsx +0 -159
- package/src/plugins/ibkr/instance-selection.test.ts +0 -120
- package/src/plugins/ibkr/instance-selection.ts +0 -36
- package/src/plugins/ibkr/portfolio-performance.test.ts +0 -32
- package/src/plugins/ibkr/portfolio-performance.ts +0 -129
- package/src/plugins/ibkr/trade/badge.tsx +0 -28
- package/src/plugins/ibkr/trade/dialogs.tsx +0 -44
- package/src/plugins/ibkr/trade/preview-panel.tsx +0 -130
- package/src/plugins/ibkr/trade/tab/actions.tsx +0 -443
- package/src/plugins/ibkr/trade/tab/field-editors.tsx +0 -79
- package/src/plugins/ibkr/trade/tab/footer.ts +0 -53
- package/src/plugins/ibkr/trade/tab/header.tsx +0 -167
- package/src/plugins/ibkr/trade/tab/index.test.tsx +0 -178
- package/src/plugins/ibkr/trade/tab/index.tsx +0 -298
- package/src/plugins/ibkr/trade/tab/model.ts +0 -159
- package/src/plugins/ibkr/trade/tab/order-request.ts +0 -64
- package/src/plugins/ibkr/trade/tab/shortcuts.ts +0 -89
- package/src/plugins/ibkr/trade/tab/state-sync.ts +0 -86
- package/src/plugins/ibkr/trade/ticket-panel.tsx +0 -301
- package/src/plugins/ibkr/trade/utils.test.ts +0 -175
- package/src/plugins/ibkr/trade/utils.ts +0 -144
- package/src/plugins/ibkr/trading/pane-view.tsx +0 -237
- package/src/plugins/ibkr/trading/pane.tsx +0 -332
- package/src/plugins/ibkr/trading/state.test.ts +0 -109
- package/src/plugins/ibkr/trading/state.ts +0 -335
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { formatNumber } from "../../../utils/format";
|
|
2
|
+
import type { IndicatorDef, SeriesDef, ShillerField } from "./defs";
|
|
3
|
+
|
|
4
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
5
|
+
const MILLIONS_TO_BILLIONS = 0.001;
|
|
6
|
+
|
|
7
|
+
/** Z.1 lands ~10 weeks after quarter end, then holds until the next quarter's release. */
|
|
8
|
+
const QUARTERLY_STALE_MS = 270 * DAY_MS;
|
|
9
|
+
/** Shiller republishes monthly; two missed months means something is wrong. */
|
|
10
|
+
const MONTHLY_STALE_MS = 75 * DAY_MS;
|
|
11
|
+
const DAILY_STALE_MS = 5 * DAY_MS;
|
|
12
|
+
|
|
13
|
+
function percent(value: number): string {
|
|
14
|
+
return `${Math.round(value)}%`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function percentTenths(value: number): string {
|
|
18
|
+
return `${formatNumber(value, 1)}%`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ratio(value: number): string {
|
|
22
|
+
return formatNumber(value, 2);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Total US market value. FRED discontinued the WILL5000* family, so this comes
|
|
27
|
+
* from the cloud's own price history rather than the econ proxy.
|
|
28
|
+
*/
|
|
29
|
+
const WILSHIRE_5000: SeriesDef = {
|
|
30
|
+
key: "W5000",
|
|
31
|
+
scaleToBillions: 1,
|
|
32
|
+
source: {
|
|
33
|
+
kind: "market-history",
|
|
34
|
+
symbol: "^W5000",
|
|
35
|
+
exchange: "INDEX",
|
|
36
|
+
startDate: "1970-01-01",
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const NOMINAL_GDP: SeriesDef = {
|
|
41
|
+
key: "GDP",
|
|
42
|
+
scaleToBillions: 1,
|
|
43
|
+
source: { kind: "fred", seriesId: "GDP", limit: 340 },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const M2: SeriesDef = {
|
|
47
|
+
key: "M2SL",
|
|
48
|
+
scaleToBillions: 1,
|
|
49
|
+
source: { kind: "fred", seriesId: "M2SL", limit: 900 },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
function shillerSeries(key: string, field: ShillerField): SeriesDef {
|
|
53
|
+
return { key, scaleToBillions: 1, source: { kind: "shiller", field } };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const BUFFETT_INDICATOR: IndicatorDef = {
|
|
57
|
+
id: "buffett",
|
|
58
|
+
label: "Buffett Indicator",
|
|
59
|
+
shortLabel: "Buffett",
|
|
60
|
+
description: "US total market cap over nominal GDP.",
|
|
61
|
+
input: {
|
|
62
|
+
kind: "ratio",
|
|
63
|
+
numerator: WILSHIRE_5000,
|
|
64
|
+
denominator: NOMINAL_GDP,
|
|
65
|
+
levels: { numeratorLabel: "Mkt cap", denominatorLabel: "GDP" },
|
|
66
|
+
},
|
|
67
|
+
ratioScale: 100,
|
|
68
|
+
formatValue: percent,
|
|
69
|
+
axisUnit: "%",
|
|
70
|
+
zones: [
|
|
71
|
+
{ max: 75, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
72
|
+
{ max: 90, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
73
|
+
{ max: 115, id: "fair", label: "Fair Valued" },
|
|
74
|
+
{ max: 135, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
75
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
76
|
+
],
|
|
77
|
+
zoneScale: { min: 0, max: 250, edges: [0, 75, 90, 115, 135, 250], ticks: [0, 75, 100, 135, 250] },
|
|
78
|
+
reference: { value: 100, label: "parity" },
|
|
79
|
+
chartGridStep: 150,
|
|
80
|
+
trendModel: "log",
|
|
81
|
+
staleAfterMs: DAILY_STALE_MS,
|
|
82
|
+
notes: [
|
|
83
|
+
"Total US market value against one year of economic output. Warren Buffett called it probably the best single measure of where valuations stand at any given moment, in a December 2001 Fortune essay written with Carol Loomis.",
|
|
84
|
+
"Rates, buybacks, and a larger listed share of the economy have all raised what fair looks like since 2001, so read the trend deviation alongside the absolute zone.",
|
|
85
|
+
],
|
|
86
|
+
link: {
|
|
87
|
+
url: "https://en.wikipedia.org/wiki/Buffett_indicator",
|
|
88
|
+
label: "Buffett indicator, Wikipedia",
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const TOBINS_Q: IndicatorDef = {
|
|
93
|
+
id: "tobins-q",
|
|
94
|
+
label: "Tobin's Q",
|
|
95
|
+
shortLabel: "Tobin Q",
|
|
96
|
+
description: "Corporate equity market value over replacement cost of net assets.",
|
|
97
|
+
input: {
|
|
98
|
+
kind: "ratio",
|
|
99
|
+
numerator: {
|
|
100
|
+
key: "NCBEILQ027S",
|
|
101
|
+
scaleToBillions: MILLIONS_TO_BILLIONS,
|
|
102
|
+
source: { kind: "fred", seriesId: "NCBEILQ027S", limit: 400 },
|
|
103
|
+
},
|
|
104
|
+
denominator: {
|
|
105
|
+
key: "TNWMVBSNNCB",
|
|
106
|
+
scaleToBillions: MILLIONS_TO_BILLIONS,
|
|
107
|
+
source: { kind: "fred", seriesId: "TNWMVBSNNCB", limit: 400 },
|
|
108
|
+
},
|
|
109
|
+
levels: { numeratorLabel: "Equities", denominatorLabel: "Net worth" },
|
|
110
|
+
},
|
|
111
|
+
ratioScale: 1,
|
|
112
|
+
formatValue: ratio,
|
|
113
|
+
axisUnit: "",
|
|
114
|
+
// Bands anchored on the 1945-2026 distribution: p25 0.54, median 0.93, p75 1.34.
|
|
115
|
+
zones: [
|
|
116
|
+
{ max: 0.55, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
117
|
+
{ max: 0.8, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
118
|
+
{ max: 1.1, id: "fair", label: "Fair Valued" },
|
|
119
|
+
{ max: 1.4, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
120
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
121
|
+
],
|
|
122
|
+
zoneScale: { min: 0, max: 2, edges: [0, 0.55, 0.8, 1.1, 1.4, 2], ticks: [0, 0.55, 1, 1.4, 2] },
|
|
123
|
+
reference: { value: 1, label: "replacement cost" },
|
|
124
|
+
chartGridStep: 0.5,
|
|
125
|
+
trendModel: "log",
|
|
126
|
+
staleAfterMs: QUARTERLY_STALE_MS,
|
|
127
|
+
notes: [
|
|
128
|
+
"Equity market value against what it would cost to rebuild the assets behind it. Q above 1 means the market pays more than replacement cost.",
|
|
129
|
+
"Built from the Fed's quarterly Z.1 financial accounts for nonfinancial corporate business, so it moves in quarterly steps and revises with each release.",
|
|
130
|
+
],
|
|
131
|
+
link: { url: "https://en.wikipedia.org/wiki/Tobin%27s_q", label: "Tobin's q, Wikipedia" },
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const SHILLER_CAPE: IndicatorDef = {
|
|
135
|
+
id: "shiller-cape",
|
|
136
|
+
label: "Shiller CAPE",
|
|
137
|
+
shortLabel: "CAPE",
|
|
138
|
+
description: "S&P 500 price over ten years of inflation-adjusted earnings.",
|
|
139
|
+
input: { kind: "direct", series: shillerSeries("SHILLER_CAPE", "cape") },
|
|
140
|
+
ratioScale: 1,
|
|
141
|
+
formatValue: (value) => formatNumber(value, 1),
|
|
142
|
+
axisUnit: "",
|
|
143
|
+
// Bands anchored on the 1881-2026 distribution: p25 12.0, median 16.6, p75 21.5.
|
|
144
|
+
zones: [
|
|
145
|
+
{ max: 12, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
146
|
+
{ max: 15, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
147
|
+
{ max: 22, id: "fair", label: "Fair Valued" },
|
|
148
|
+
{ max: 30, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
149
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
150
|
+
],
|
|
151
|
+
zoneScale: { min: 0, max: 45, edges: [0, 12, 15, 22, 30, 45], ticks: [0, 12, 22, 30, 45] },
|
|
152
|
+
reference: { value: 16.6, label: "median" },
|
|
153
|
+
chartGridStep: 10,
|
|
154
|
+
trendModel: "log",
|
|
155
|
+
staleAfterMs: MONTHLY_STALE_MS,
|
|
156
|
+
notes: [
|
|
157
|
+
"Price divided by the average of ten years of real earnings, which smooths away the profit cycle that makes a one-year P/E swing hardest exactly when it matters most.",
|
|
158
|
+
"Robert Shiller's series runs back to 1881. It has spent decades above its own median without mean-reverting, so treat it as a long-horizon return signal rather than a timing tool.",
|
|
159
|
+
],
|
|
160
|
+
link: {
|
|
161
|
+
url: "https://en.wikipedia.org/wiki/Cyclically_adjusted_price-to-earnings_ratio",
|
|
162
|
+
label: "CAPE ratio, Wikipedia",
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const EXCESS_CAPE_YIELD: IndicatorDef = {
|
|
167
|
+
id: "excess-cape-yield",
|
|
168
|
+
label: "Excess CAPE Yield",
|
|
169
|
+
shortLabel: "ERP (ECY)",
|
|
170
|
+
description: "CAPE earnings yield over the real 10-year Treasury yield.",
|
|
171
|
+
input: { kind: "direct", series: shillerSeries("SHILLER_ECY", "excessCapeYield") },
|
|
172
|
+
// Shiller publishes it as a decimal fraction; show it as a percent.
|
|
173
|
+
ratioScale: 100,
|
|
174
|
+
formatValue: percentTenths,
|
|
175
|
+
axisUnit: "%",
|
|
176
|
+
// A high excess yield means stocks are paid well over bonds, so the bands run the
|
|
177
|
+
// opposite way to a price ratio. Anchored on p25 1.5%, median 3.3%, p75 6.6%.
|
|
178
|
+
zones: [
|
|
179
|
+
{ max: 1.5, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
180
|
+
{ max: 2.5, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
181
|
+
{ max: 4.5, id: "fair", label: "Fair Valued" },
|
|
182
|
+
{ max: 6.5, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
183
|
+
{ max: null, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
184
|
+
],
|
|
185
|
+
zoneScale: { min: -3, max: 12, edges: [-3, 1.5, 2.5, 4.5, 6.5, 12], ticks: [-3, 1.5, 4.5, 6.5, 12] },
|
|
186
|
+
reference: { value: 0, label: "no premium" },
|
|
187
|
+
chartGridStep: 5,
|
|
188
|
+
// The spread has been negative, so a log fit would silently drop those years.
|
|
189
|
+
trendModel: "linear",
|
|
190
|
+
staleAfterMs: MONTHLY_STALE_MS,
|
|
191
|
+
notes: [
|
|
192
|
+
"What stocks yield over inflation-protected bonds: the CAPE earnings yield minus the real ten-year Treasury yield. It is the equity risk premium in the form Shiller publishes.",
|
|
193
|
+
"Unlike a price ratio, higher is cheaper. It went negative before the 1929 and 2000 peaks, when bonds out-yielded stocks outright.",
|
|
194
|
+
],
|
|
195
|
+
link: {
|
|
196
|
+
url: "https://en.wikipedia.org/wiki/Equity_premium_puzzle",
|
|
197
|
+
label: "Equity risk premium, Wikipedia",
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const SP500_DIVIDEND_YIELD: IndicatorDef = {
|
|
202
|
+
id: "sp500-dividend-yield",
|
|
203
|
+
label: "S&P 500 Dividend Yield",
|
|
204
|
+
shortLabel: "Div yield",
|
|
205
|
+
description: "Index dividend over index price.",
|
|
206
|
+
input: {
|
|
207
|
+
kind: "ratio",
|
|
208
|
+
numerator: shillerSeries("SHILLER_DIVIDEND", "dividend"),
|
|
209
|
+
denominator: shillerSeries("SHILLER_PRICE", "price"),
|
|
210
|
+
},
|
|
211
|
+
ratioScale: 100,
|
|
212
|
+
formatValue: percentTenths,
|
|
213
|
+
axisUnit: "%",
|
|
214
|
+
// Higher yield is cheaper, so the bands invert. Anchored on p25 3.0%, median 4.2%.
|
|
215
|
+
zones: [
|
|
216
|
+
{ max: 2, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
217
|
+
{ max: 3, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
218
|
+
{ max: 5, id: "fair", label: "Fair Valued" },
|
|
219
|
+
{ max: 6.5, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
220
|
+
{ max: null, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
221
|
+
],
|
|
222
|
+
zoneScale: { min: 0, max: 10, edges: [0, 2, 3, 5, 6.5, 10], ticks: [0, 2, 5, 6.5, 10] },
|
|
223
|
+
reference: { value: 4.2, label: "median" },
|
|
224
|
+
chartGridStep: 4,
|
|
225
|
+
trendModel: "log",
|
|
226
|
+
staleAfterMs: MONTHLY_STALE_MS,
|
|
227
|
+
notes: [
|
|
228
|
+
"What the index pays out against what it costs. Buybacks have moved a large share of shareholder return off this line since the 1980s, so the modern level is structurally lower than the pre-1990 record.",
|
|
229
|
+
"Read it against its own recent decades rather than the full history for that reason.",
|
|
230
|
+
],
|
|
231
|
+
link: { url: "https://en.wikipedia.org/wiki/Dividend_yield", label: "Dividend yield, Wikipedia" },
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export const HOUSEHOLD_EQUITY_ALLOCATION: IndicatorDef = {
|
|
235
|
+
id: "household-equity-allocation",
|
|
236
|
+
label: "Investor Equity Allocation",
|
|
237
|
+
shortLabel: "Equity alloc",
|
|
238
|
+
description: "Share of household financial assets held in equities.",
|
|
239
|
+
input: {
|
|
240
|
+
kind: "direct",
|
|
241
|
+
series: {
|
|
242
|
+
key: "BOGZ1FL153064486Q",
|
|
243
|
+
scaleToBillions: 1,
|
|
244
|
+
source: { kind: "fred", seriesId: "BOGZ1FL153064486Q", limit: 400 },
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
// FRED publishes it as a percentage already, so it needs no rescaling.
|
|
248
|
+
ratioScale: 1,
|
|
249
|
+
formatValue: percentTenths,
|
|
250
|
+
axisUnit: "%",
|
|
251
|
+
// Bands anchored on the 1945-2026 distribution: p25 17.7%, median 24.3%, p75 30.0%.
|
|
252
|
+
zones: [
|
|
253
|
+
{ max: 18, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
254
|
+
{ max: 22, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
255
|
+
{ max: 28, id: "fair", label: "Fair Valued" },
|
|
256
|
+
{ max: 34, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
257
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
258
|
+
],
|
|
259
|
+
zoneScale: { min: 0, max: 50, edges: [0, 18, 22, 28, 34, 50], ticks: [0, 18, 28, 34, 50] },
|
|
260
|
+
reference: { value: 24.3, label: "median" },
|
|
261
|
+
chartGridStep: 10,
|
|
262
|
+
trendModel: "log",
|
|
263
|
+
staleAfterMs: QUARTERLY_STALE_MS,
|
|
264
|
+
notes: [
|
|
265
|
+
"How much of what households own sits in stocks. When investors are already all-in there is little cash left to bid prices higher, which is why this has tracked ten-year forward returns more closely than any price ratio.",
|
|
266
|
+
"From the Fed's quarterly Z.1 accounts, counting equities held directly and through funds.",
|
|
267
|
+
],
|
|
268
|
+
link: {
|
|
269
|
+
url: "https://fred.stlouisfed.org/series/BOGZ1FL153064486Q",
|
|
270
|
+
label: "Household equity share, FRED",
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export const MARKET_CAP_TO_M2: IndicatorDef = {
|
|
275
|
+
id: "market-cap-m2",
|
|
276
|
+
label: "Market Cap to M2",
|
|
277
|
+
shortLabel: "Cap / M2",
|
|
278
|
+
description: "US total market cap against the money supply.",
|
|
279
|
+
input: {
|
|
280
|
+
kind: "ratio",
|
|
281
|
+
numerator: WILSHIRE_5000,
|
|
282
|
+
denominator: M2,
|
|
283
|
+
levels: { numeratorLabel: "Mkt cap", denominatorLabel: "M2" },
|
|
284
|
+
},
|
|
285
|
+
ratioScale: 100,
|
|
286
|
+
formatValue: percent,
|
|
287
|
+
axisUnit: "%",
|
|
288
|
+
// Bands anchored on the 1989-2026 distribution: p25 142%, median 180%, p75 206%.
|
|
289
|
+
zones: [
|
|
290
|
+
{ max: 130, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
291
|
+
{ max: 160, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
292
|
+
{ max: 210, id: "fair", label: "Fair Valued" },
|
|
293
|
+
{ max: 260, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
294
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
295
|
+
],
|
|
296
|
+
zoneScale: { min: 0, max: 350, edges: [0, 130, 160, 210, 260, 350], ticks: [0, 130, 210, 260, 350] },
|
|
297
|
+
reference: { value: 180, label: "median" },
|
|
298
|
+
chartGridStep: 100,
|
|
299
|
+
trendModel: "log",
|
|
300
|
+
staleAfterMs: DAILY_STALE_MS,
|
|
301
|
+
notes: [
|
|
302
|
+
"Market value measured against the money supply rather than output, which is the liquidity-adjusted read on the same question the Buffett indicator asks.",
|
|
303
|
+
"It falls when the Fed expands M2 faster than equities rise, so the 2020 surge shows up here as cheapening even while price ratios were climbing.",
|
|
304
|
+
],
|
|
305
|
+
link: { url: "https://fred.stlouisfed.org/series/M2SL", label: "M2 money stock, FRED" },
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export const MARGIN_DEBT_TO_GDP: IndicatorDef = {
|
|
309
|
+
id: "margin-debt-gdp",
|
|
310
|
+
label: "Margin Debt to GDP",
|
|
311
|
+
shortLabel: "Margin debt",
|
|
312
|
+
description: "Borrowing against securities, against the size of the economy.",
|
|
313
|
+
input: {
|
|
314
|
+
kind: "ratio",
|
|
315
|
+
numerator: {
|
|
316
|
+
key: "BOGZ1FL663067003Q",
|
|
317
|
+
scaleToBillions: MILLIONS_TO_BILLIONS,
|
|
318
|
+
source: { kind: "fred", seriesId: "BOGZ1FL663067003Q", limit: 400 },
|
|
319
|
+
},
|
|
320
|
+
denominator: NOMINAL_GDP,
|
|
321
|
+
levels: { numeratorLabel: "Margin debt", denominatorLabel: "GDP" },
|
|
322
|
+
},
|
|
323
|
+
ratioScale: 100,
|
|
324
|
+
formatValue: percentTenths,
|
|
325
|
+
axisUnit: "%",
|
|
326
|
+
// Bands anchored on the 1945-2026 distribution: p25 0.71%, median 0.92%, p75 1.40%.
|
|
327
|
+
zones: [
|
|
328
|
+
{ max: 0.7, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
329
|
+
{ max: 0.9, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
330
|
+
{ max: 1.4, id: "fair", label: "Fair Valued" },
|
|
331
|
+
{ max: 1.8, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
332
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
333
|
+
],
|
|
334
|
+
zoneScale: { min: 0, max: 3, edges: [0, 0.7, 0.9, 1.4, 1.8, 3], ticks: [0, 0.9, 1.4, 1.8, 3] },
|
|
335
|
+
reference: { value: 0.92, label: "median" },
|
|
336
|
+
chartGridStep: 1,
|
|
337
|
+
trendModel: "log",
|
|
338
|
+
staleAfterMs: QUARTERLY_STALE_MS,
|
|
339
|
+
notes: [
|
|
340
|
+
"How much investors have borrowed against their holdings. Leverage is what turns a decline into forced selling, so it is froth rather than value, but it peaks where valuations do.",
|
|
341
|
+
"Its two highest readings are the first quarter of 2000 and the third of 2008. From the Fed's Z.1 accounts, which reach further back than FINRA's own margin table.",
|
|
342
|
+
],
|
|
343
|
+
link: {
|
|
344
|
+
url: "https://fred.stlouisfed.org/series/BOGZ1FL663067003Q",
|
|
345
|
+
label: "Margin account receivables, FRED",
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
export const MARKET_CAP_TO_PROFITS: IndicatorDef = {
|
|
350
|
+
id: "market-cap-profits",
|
|
351
|
+
label: "Market Cap to Corporate Profits",
|
|
352
|
+
shortLabel: "Cap / profits",
|
|
353
|
+
description: "US total market cap over after-tax corporate profits.",
|
|
354
|
+
input: {
|
|
355
|
+
kind: "ratio",
|
|
356
|
+
numerator: WILSHIRE_5000,
|
|
357
|
+
denominator: {
|
|
358
|
+
key: "CPROFIT",
|
|
359
|
+
scaleToBillions: 1,
|
|
360
|
+
source: { kind: "fred", seriesId: "CPROFIT", limit: 400 },
|
|
361
|
+
},
|
|
362
|
+
levels: { numeratorLabel: "Mkt cap", denominatorLabel: "Profits" },
|
|
363
|
+
},
|
|
364
|
+
ratioScale: 1,
|
|
365
|
+
formatValue: (value) => formatNumber(value, 1),
|
|
366
|
+
axisUnit: "",
|
|
367
|
+
// Bands anchored on the 1989-2026 distribution: p25 7.9, median 9.1, p75 12.3.
|
|
368
|
+
zones: [
|
|
369
|
+
{ max: 8, id: "significantly-undervalued", label: "Significantly Undervalued" },
|
|
370
|
+
{ max: 9, id: "modestly-undervalued", label: "Modestly Undervalued" },
|
|
371
|
+
{ max: 12, id: "fair", label: "Fair Valued" },
|
|
372
|
+
{ max: 15, id: "modestly-overvalued", label: "Modestly Overvalued" },
|
|
373
|
+
{ max: null, id: "significantly-overvalued", label: "Significantly Overvalued" },
|
|
374
|
+
],
|
|
375
|
+
zoneScale: { min: 0, max: 20, edges: [0, 8, 9, 12, 15, 20], ticks: [0, 9, 12, 15, 20] },
|
|
376
|
+
reference: { value: 9.1, label: "median" },
|
|
377
|
+
chartGridStep: 5,
|
|
378
|
+
trendModel: "log",
|
|
379
|
+
staleAfterMs: DAILY_STALE_MS,
|
|
380
|
+
notes: [
|
|
381
|
+
"A price-to-earnings ratio for the whole economy rather than the index, using what every US corporation actually earned after tax.",
|
|
382
|
+
"Profits are near a record share of GDP, so this asks whether the market is dear even against unusually good earnings. Its highest reading is March 2000.",
|
|
383
|
+
],
|
|
384
|
+
link: {
|
|
385
|
+
url: "https://fred.stlouisfed.org/series/CPROFIT",
|
|
386
|
+
label: "Corporate profits after tax, FRED",
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
export const INDICATORS: readonly IndicatorDef[] = [
|
|
391
|
+
BUFFETT_INDICATOR,
|
|
392
|
+
SHILLER_CAPE,
|
|
393
|
+
EXCESS_CAPE_YIELD,
|
|
394
|
+
TOBINS_Q,
|
|
395
|
+
HOUSEHOLD_EQUITY_ALLOCATION,
|
|
396
|
+
SP500_DIVIDEND_YIELD,
|
|
397
|
+
MARGIN_DEBT_TO_GDP,
|
|
398
|
+
MARKET_CAP_TO_PROFITS,
|
|
399
|
+
MARKET_CAP_TO_M2,
|
|
400
|
+
];
|
|
401
|
+
|
|
402
|
+
export const DEFAULT_INDICATOR_ID = BUFFETT_INDICATOR.id;
|
|
403
|
+
|
|
404
|
+
export function findIndicator(id: string | null | undefined): IndicatorDef {
|
|
405
|
+
const normalized = id?.trim().toLowerCase();
|
|
406
|
+
return INDICATORS.find((entry) => entry.id === normalized) ?? BUFFETT_INDICATOR;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** Resolves shortcut arguments like `VAL cape` or `VAL buffett` onto an indicator. */
|
|
410
|
+
export function resolveIndicatorArg(arg: string | null | undefined): IndicatorDef | null {
|
|
411
|
+
const query = arg?.trim().toLowerCase();
|
|
412
|
+
if (!query) return null;
|
|
413
|
+
const direct = INDICATORS.find((entry) => entry.id === query);
|
|
414
|
+
if (direct) return direct;
|
|
415
|
+
return INDICATORS.find((entry) =>
|
|
416
|
+
entry.shortLabel.toLowerCase() === query
|
|
417
|
+
|| entry.label.toLowerCase() === query
|
|
418
|
+
|| entry.id.startsWith(query)
|
|
419
|
+
|| entry.label.toLowerCase().startsWith(query)
|
|
420
|
+
|| entry.shortLabel.toLowerCase().startsWith(query)
|
|
421
|
+
) ?? null;
|
|
422
|
+
}
|