gloomberb 0.16.3 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -91
- package/package.json +7 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
- package/src/account/upgrade-personalization.ts +57 -0
- package/src/account/upgrade-tickers.ts +124 -0
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +58 -18
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +16 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +95 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +46 -10
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +74 -2
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +26 -2
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +61 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +19 -4
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +744 -181
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +425 -0
- package/src/cli/commands/overview.ts +251 -40
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +109 -15
- package/src/cli/commands/system.ts +151 -24
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +149 -40
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +150 -17
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +22 -8
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/glossary.ts +429 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +58 -0
- package/src/cli/index.ts +29 -12
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +595 -26
- package/src/cli/not-a-ticker.ts +44 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +11 -4
- package/src/cli/pane-functions/catalog.ts +48 -7
- package/src/cli/pane-functions/data.ts +48 -13
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +41 -19
- package/src/cli/pane-functions/freshness.ts +531 -32
- package/src/cli/pane-functions/function-help.ts +77 -25
- package/src/cli/pane-functions/headless.ts +50 -21
- package/src/cli/pane-functions/index.ts +66 -10
- package/src/cli/pane-functions/market-session.ts +147 -0
- package/src/cli/pane-functions/options.ts +77 -25
- package/src/cli/pane-functions/report-notices.ts +81 -0
- package/src/cli/pane-functions/report.ts +19 -8
- package/src/cli/pane-functions/resolver.ts +53 -18
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +199 -30
- package/src/cli/registry.ts +2 -1
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +53 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +83 -10
- package/src/components/chart/composite/legend.tsx +88 -8
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +9 -2
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +40 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +26 -2
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +43 -9
- package/src/components/layout/shell/drag/live.ts +87 -6
- package/src/components/layout/shell/drag/runtime.ts +62 -20
- package/src/components/layout/shell/index.tsx +71 -12
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +33 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +216 -28
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +69 -23
- package/src/components/metric-treemap/heat-surface.tsx +37 -9
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +50 -41
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +17 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +49 -0
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +20 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +13 -2
- package/src/components/ui/index.ts +1 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +44 -5
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +75 -5
- package/src/i18n/ja.ts +75 -5
- package/src/i18n/ko.ts +75 -5
- package/src/i18n/zh-cn.ts +75 -5
- package/src/i18n/zh-tw.ts +75 -5
- package/src/layout/desks.ts +2 -3
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +193 -30
- package/src/market-data/market/status.ts +59 -23
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +22 -2
- package/src/market-data/quotes/metadata.ts +8 -9
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +61 -9
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +2 -56
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +37 -8
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +71 -12
- package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +50 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
- package/src/plugins/builtin/cloud/askg/model.ts +156 -78
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
- package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +116 -67
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +23 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +70 -22
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +64 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +114 -20
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +18 -8
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +42 -134
- package/src/plugins/builtin/holders/pane.tsx +14 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +27 -10
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +26 -6
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +27 -12
- package/src/plugins/builtin/iv-history/index.tsx +5 -3
- package/src/plugins/builtin/iv-history/model.ts +172 -20
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +68 -3
- package/src/plugins/builtin/macro-day/headless.ts +18 -12
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +66 -15
- package/src/plugins/builtin/macro-day/pane.tsx +34 -20
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +102 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +11 -3
- package/src/plugins/builtin/market-movers/model.ts +101 -17
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +162 -13
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +5 -2
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +75 -18
- package/src/plugins/builtin/options-scenario/headless.ts +72 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -8
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +32 -6
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +90 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
- package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +8 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +69 -0
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +59 -2
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +21 -4
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +3 -10
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
- package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +125 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +129 -64
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +173 -28
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +25 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +126 -59
- package/src/remote/matching.ts +69 -0
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +63 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +32 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +21 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +4 -1
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +14 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +74 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +6 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +26 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +14 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +9 -5
- package/src/sources/provider-router/financial-routes.ts +12 -5
- package/src/sources/provider-router/financials.ts +55 -15
- package/src/sources/provider-router/history.ts +68 -34
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +5 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +67 -9
- package/src/tickers/search/ranking.ts +78 -18
- package/src/tickers/search/types.ts +10 -2
- package/src/tickers/starter-symbols.ts +8 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +96 -30
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +67 -1
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +72 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +68 -3
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +26 -4
- package/src/ui/index.tsx +2 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +21 -2
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +120 -1
- package/src/utils/format.ts +17 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +44 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +130 -40
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +178 -36
- package/src/utils/sec.ts +98 -40
- package/src/utils/throttled-fetch.ts +51 -22
- package/src/utils/utc-time.ts +51 -4
|
@@ -12,6 +12,7 @@ import { useLiveQuoteEntries } from "../../../state/hooks/quote-streaming";
|
|
|
12
12
|
import { buildQuoteKey, resolveEntryData } from "../../../market-data/selectors";
|
|
13
13
|
import type { QuoteSubscriptionTarget } from "../../../types/data-provider";
|
|
14
14
|
import type { Quote } from "../../../types/financials";
|
|
15
|
+
import type { ExtendedSession } from "../../../market-data/market/status";
|
|
15
16
|
import { useAutoRefresh, useUpdatedAgo } from "../../../react/auto-refresh";
|
|
16
17
|
import { useLiveStreamingSetting } from "../../../state/hooks/live-streaming";
|
|
17
18
|
import { isStreamCarryingQuote, useVisibleBoardSymbols } from "../shared/use-quote-board";
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
nextSortPreference,
|
|
34
35
|
normalizeRowsForCollection,
|
|
35
36
|
overlayLiveSectorQuote,
|
|
37
|
+
sectorExtendedSessions,
|
|
36
38
|
sectorRowFollowsQuote,
|
|
37
39
|
sectorRowIssues,
|
|
38
40
|
sortRows,
|
|
@@ -149,7 +151,6 @@ function EtfBoard({ collectionId, focused, width, height, rootBefore }: EtfBoard
|
|
|
149
151
|
const fetchGenRef = useRef(0);
|
|
150
152
|
const [loadError, setLoadError] = useState<string | null>(null);
|
|
151
153
|
|
|
152
|
-
const columns = useMemo(() => buildSectorColumns(width), [width]);
|
|
153
154
|
const rows = useMemo(
|
|
154
155
|
() => normalizeRowsForCollection(rowsByCollection, activeCollection.id, activeItems),
|
|
155
156
|
[activeCollection.id, activeItems, rowsByCollection],
|
|
@@ -203,6 +204,12 @@ function EtfBoard({ collectionId, focused, width, height, rootBefore }: EtfBoard
|
|
|
203
204
|
return carried && !!quote && sectorRowFollowsQuote(row, quote);
|
|
204
205
|
}), [freshnessNow, liveEntries, liveStreaming, rows, subscriptionStartedAt]);
|
|
205
206
|
const sortedRows = useMemo(() => sortRows(liveRows, sortPreference), [liveRows, sortPreference]);
|
|
207
|
+
// A pre-market or after-hours column only while a fund has such a print.
|
|
208
|
+
const extendedSessionsKey = sectorExtendedSessions(liveRows).join(",");
|
|
209
|
+
const columns = useMemo(
|
|
210
|
+
() => buildSectorColumns(width, extendedSessionsKey ? extendedSessionsKey.split(",") as ExtendedSession[] : []),
|
|
211
|
+
[extendedSessionsKey, width],
|
|
212
|
+
);
|
|
206
213
|
const lastRefreshMs = lastRefreshByCollection[activeCollection.id] ?? null;
|
|
207
214
|
const loading = rows.some((row) => row.loading);
|
|
208
215
|
/**
|
|
@@ -296,6 +303,16 @@ function EtfBoard({ collectionId, focused, width, height, rootBefore }: EtfBoard
|
|
|
296
303
|
text: row.changePercent !== null ? formatPercentRaw(shownPercent(row.changePercent)) : "—",
|
|
297
304
|
color: row.changePercent !== null ? priceColor(shownPercent(row.changePercent)) : colors.textDim,
|
|
298
305
|
};
|
|
306
|
+
case "preMarket":
|
|
307
|
+
case "afterHours": {
|
|
308
|
+
// The extended print's move from the close in LAST.
|
|
309
|
+
const move = row.extendedSession === (column.id === "preMarket" ? "PRE" : "POST") ? row.extendedChangePercent ?? null : null;
|
|
310
|
+
return {
|
|
311
|
+
text: move !== null ? formatPercentRaw(shownPercent(move)) : "—",
|
|
312
|
+
value: move,
|
|
313
|
+
color: move !== null ? priceColor(shownPercent(move)) : colors.textDim,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
299
316
|
case "return1M":
|
|
300
317
|
return {
|
|
301
318
|
text: row.loading && row.return1M === null ? "…" : row.return1M !== null ? formatPercentRaw(shownPercent(row.return1M)) : "—",
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { DataTableColumn } from "../../../components";
|
|
2
|
+
import { getTableWidth, tableColumnWidth } from "../../../components/ui/table-layout";
|
|
2
3
|
import type { PricePoint, Quote } from "../../../types/financials";
|
|
3
4
|
import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
|
|
4
5
|
import { getPricePointTimestamp } from "../../../utils/price-history";
|
|
5
6
|
import { mergePriceHistoryIntegrity, pricePointIntegrity, type PriceHistoryIntegrity } from "../../../utils/price-history-integrity";
|
|
7
|
+
import {
|
|
8
|
+
getExtendedSessionDisplay,
|
|
9
|
+
getRegularSessionDisplay,
|
|
10
|
+
marketStateLabel,
|
|
11
|
+
type ExtendedSession,
|
|
12
|
+
} from "../../../market-data/market/status";
|
|
6
13
|
import {
|
|
7
14
|
getSectorCollection,
|
|
8
15
|
type SectorCollectionId,
|
|
@@ -12,8 +19,21 @@ import {
|
|
|
12
19
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
13
20
|
export const DEFAULT_COLLECTION_ID: SectorCollectionId = "sectors";
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
/**
|
|
23
|
+
* The pre-market or after-hours print beside a row's regular close, measured
|
|
24
|
+
* from that close (getExtendedSessionDisplay); all null without one.
|
|
25
|
+
*/
|
|
26
|
+
export interface SectorExtendedFields {
|
|
27
|
+
extendedSession?: ExtendedSession | null;
|
|
28
|
+
extendedPrice?: number | null;
|
|
29
|
+
extendedChange?: number | null;
|
|
30
|
+
extendedChangePercent?: number | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SectorRow extends SectorDef, SectorExtendedFields {
|
|
34
|
+
/** The regular session's price: its close once it is over, never an extended print. */
|
|
16
35
|
price: number | null;
|
|
36
|
+
/** The regular session's move, as `ticker` reports it. */
|
|
17
37
|
changePercent: number | null;
|
|
18
38
|
return1M: number | null;
|
|
19
39
|
return1Y: number | null;
|
|
@@ -33,7 +53,7 @@ export interface SectorRow extends SectorDef {
|
|
|
33
53
|
return1YStartDate?: string | null;
|
|
34
54
|
}
|
|
35
55
|
|
|
36
|
-
type SectorColumnId = "name" | "etf" | "price" | "changePercent" | "return1M" | "return1Y" | "bar";
|
|
56
|
+
type SectorColumnId = "name" | "etf" | "price" | "changePercent" | "preMarket" | "afterHours" | "return1M" | "return1Y" | "bar";
|
|
37
57
|
export type SectorColumn = DataTableColumn & { id: SectorColumnId };
|
|
38
58
|
export type SectorRowsByCollection = Record<SectorCollectionId, SectorRow[]>;
|
|
39
59
|
export type SectorRefreshByCollection = Partial<Record<SectorCollectionId, number>>;
|
|
@@ -48,6 +68,45 @@ export const DEFAULT_SORT_PREFERENCE: SectorSortPreference = {
|
|
|
48
68
|
direction: "desc",
|
|
49
69
|
};
|
|
50
70
|
|
|
71
|
+
const NO_EXTENDED_PRINT: Required<SectorExtendedFields> = {
|
|
72
|
+
extendedSession: null,
|
|
73
|
+
extendedPrice: null,
|
|
74
|
+
extendedChange: null,
|
|
75
|
+
extendedChangePercent: null,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** A quote's pre-market or after-hours print, from the regular close a row shows, as row fields. */
|
|
79
|
+
export function sectorExtendedFields(quote: Quote | null | undefined): Required<SectorExtendedFields> {
|
|
80
|
+
const extended = getExtendedSessionDisplay(quote);
|
|
81
|
+
if (!extended || !Number.isFinite(extended.price)) return NO_EXTENDED_PRINT;
|
|
82
|
+
return {
|
|
83
|
+
extendedSession: extended.session,
|
|
84
|
+
extendedPrice: extended.price,
|
|
85
|
+
extendedChange: Number.isFinite(extended.change) ? extended.change! : null,
|
|
86
|
+
extendedChangePercent: Number.isFinite(extended.changePercent) ? extended.changePercent! : null,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function extendedFieldsOf(row: SectorExtendedFields | undefined): Required<SectorExtendedFields> {
|
|
91
|
+
return {
|
|
92
|
+
extendedSession: row?.extendedSession ?? null,
|
|
93
|
+
extendedPrice: row?.extendedPrice ?? null,
|
|
94
|
+
extendedChange: row?.extendedChange ?? null,
|
|
95
|
+
extendedChangePercent: row?.extendedChangePercent ?? null,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function sameExtended(left: SectorExtendedFields, right: SectorExtendedFields): boolean {
|
|
100
|
+
return (left.extendedSession ?? null) === (right.extendedSession ?? null)
|
|
101
|
+
&& (left.extendedPrice ?? null) === (right.extendedPrice ?? null)
|
|
102
|
+
&& (left.extendedChangePercent ?? null) === (right.extendedChangePercent ?? null);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The extended sessions some row has a print for, in the order their columns go. */
|
|
106
|
+
export function sectorExtendedSessions(rows: readonly SectorExtendedFields[]): ExtendedSession[] {
|
|
107
|
+
return (["PRE", "POST"] as const).filter((session) => rows.some((row) => row.extendedSession === session));
|
|
108
|
+
}
|
|
109
|
+
|
|
51
110
|
/** Full length at a 5% session move, which covers all but crash days. */
|
|
52
111
|
const MOVE_BAR_FULL_SCALE_PERCENT = 5;
|
|
53
112
|
|
|
@@ -99,6 +158,7 @@ export function normalizeRowsForCollection(
|
|
|
99
158
|
quoteIssue: existing?.quoteIssue ?? null,
|
|
100
159
|
lastReportedPrice: existing?.lastReportedPrice ?? null,
|
|
101
160
|
quoteUpdatedAt: existing?.quoteUpdatedAt ?? null,
|
|
161
|
+
...extendedFieldsOf(existing),
|
|
102
162
|
returnIntegrity: existing?.returnIntegrity ?? {},
|
|
103
163
|
returnAsOfDate: existing?.returnAsOfDate ?? null,
|
|
104
164
|
return1MStartDate: existing?.return1MStartDate ?? null,
|
|
@@ -138,6 +198,7 @@ const UNAVAILABLE_SECTOR_ROW: Partial<SectorRow> = {
|
|
|
138
198
|
lastReportedPrice: null,
|
|
139
199
|
quoteUpdatedAt: null,
|
|
140
200
|
returnIntegrity: {},
|
|
201
|
+
...NO_EXTENDED_PRINT,
|
|
141
202
|
};
|
|
142
203
|
|
|
143
204
|
function sameSectorRow(left: SectorRow, right: SectorRow): boolean {
|
|
@@ -276,33 +337,49 @@ export function sectorRowIssues(row: SectorRow): string[] {
|
|
|
276
337
|
return issues;
|
|
277
338
|
}
|
|
278
339
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
{ id: "
|
|
296
|
-
{ id: "
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
340
|
+
const EXTENDED_COLUMN_WIDTH = 9;
|
|
341
|
+
/** The longest name in either collection ("Consumer Staples"), which a narrow pane keeps whole as long as it can. */
|
|
342
|
+
const FULL_NAME_WIDTH = 16;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* The board's columns at `width`. A pre-market or after-hours column follows
|
|
346
|
+
* 1D for each session in `extendedSessions`. A narrow pane gives up the move
|
|
347
|
+
* bar first, then that column, before it cuts a sector's name.
|
|
348
|
+
*/
|
|
349
|
+
export function buildSectorColumns(width: number, extendedSessions: readonly ExtendedSession[] = []): SectorColumn[] {
|
|
350
|
+
const lead: SectorColumn[] = [
|
|
351
|
+
{ id: "etf", label: "ETF", width: 4, align: "left" },
|
|
352
|
+
{ id: "price", label: "LAST", width: 8, align: "right" },
|
|
353
|
+
{ id: "changePercent", label: "1D", width: 8, align: "right" },
|
|
354
|
+
];
|
|
355
|
+
const returns: SectorColumn[] = [
|
|
356
|
+
{ id: "return1M", label: "1M", width: 8, align: "right" },
|
|
357
|
+
{ id: "return1Y", label: "1Y", width: 8, align: "right" },
|
|
358
|
+
];
|
|
359
|
+
const extendedColumns = extendedSessions.map((session): SectorColumn => ({
|
|
360
|
+
id: session === "PRE" ? "preMarket" : "afterHours",
|
|
361
|
+
// Named for the session it trades in, as the header labels it.
|
|
362
|
+
label: marketStateLabel(session),
|
|
363
|
+
width: EXTENDED_COLUMN_WIDTH,
|
|
364
|
+
align: "right",
|
|
365
|
+
}));
|
|
366
|
+
// Measured the way the table draws them (a header and its sort mark widen a
|
|
367
|
+
// column, gaps between them); the name adds its own width and a gap.
|
|
368
|
+
const nameRoom = (columns: SectorColumn[]) => width - getTableWidth(columns) - 1;
|
|
369
|
+
const shownExtended = extendedColumns.length > 0 && nameRoom([...lead, ...extendedColumns, ...returns]) >= FULL_NAME_WIDTH
|
|
370
|
+
? extendedColumns
|
|
371
|
+
: [];
|
|
372
|
+
const extendedWidth = shownExtended.reduce((total, column) => total + tableColumnWidth(column) + 1, 0);
|
|
373
|
+
const barWidth = width - extendedWidth < 82 ? 6 : Math.max(8, Math.min(18, Math.floor(width * 0.16)));
|
|
374
|
+
// Labelled with the window it encodes: it sits after 1Y but tracks 1D.
|
|
375
|
+
const bar: SectorColumn = { id: "bar", label: "1D MOVE", width: barWidth, align: "left" };
|
|
376
|
+
const withBar = [...lead, ...shownExtended, ...returns, bar];
|
|
377
|
+
const showBar = width - extendedWidth >= 67 && nameRoom(withBar) >= FULL_NAME_WIDTH;
|
|
378
|
+
const columns = showBar ? withBar : [...lead, ...shownExtended, ...returns];
|
|
379
|
+
return [
|
|
380
|
+
{ id: "name", label: "SECTOR", width: Math.max(10, Math.min(22, nameRoom(columns))), align: "left", flexGrow: 1 },
|
|
381
|
+
...columns,
|
|
300
382
|
];
|
|
301
|
-
if (showBar) {
|
|
302
|
-
// Labelled with the window it encodes: it sits after 1Y but tracks 1D.
|
|
303
|
-
columns.push({ id: "bar", label: "1D MOVE", width: barWidth, align: "left" });
|
|
304
|
-
}
|
|
305
|
-
return columns;
|
|
306
383
|
}
|
|
307
384
|
|
|
308
385
|
function getSortValue(columnId: SectorColumnId, row: SectorRow): string | number | null {
|
|
@@ -315,6 +392,9 @@ function getSortValue(columnId: SectorColumnId, row: SectorRow): string | number
|
|
|
315
392
|
return row.price;
|
|
316
393
|
case "changePercent":
|
|
317
394
|
return row.changePercent;
|
|
395
|
+
case "preMarket":
|
|
396
|
+
case "afterHours":
|
|
397
|
+
return row.extendedSession === (columnId === "preMarket" ? "PRE" : "POST") ? row.extendedChangePercent ?? null : null;
|
|
318
398
|
case "return1M":
|
|
319
399
|
return row.return1M;
|
|
320
400
|
case "return1Y":
|
|
@@ -338,6 +418,8 @@ export function nextSortPreference(current: SectorSortPreference, columnId: stri
|
|
|
338
418
|
return {
|
|
339
419
|
columnId: typedColumnId,
|
|
340
420
|
direction: typedColumnId === "changePercent"
|
|
421
|
+
|| typedColumnId === "preMarket"
|
|
422
|
+
|| typedColumnId === "afterHours"
|
|
341
423
|
|| typedColumnId === "return1M"
|
|
342
424
|
|| typedColumnId === "return1Y"
|
|
343
425
|
|| typedColumnId === "bar"
|
|
@@ -373,17 +455,30 @@ export function sectorQuoteSessionDate(quote: Quote): string | null {
|
|
|
373
455
|
/**
|
|
374
456
|
* A live quote extends a loaded row only inside the session its returns are
|
|
375
457
|
* measured to. Every fund shares that session, so a pre-market print (the
|
|
376
|
-
* next session) or a quote older than the snapshot leaves the row
|
|
377
|
-
* the board keeps ranking on one completed session. The 1M and 1Y
|
|
378
|
-
* keep their baselines: the row's own return and price imply the
|
|
458
|
+
* next session) or a quote older than the snapshot leaves the row's price
|
|
459
|
+
* alone and the board keeps ranking on one completed session. The 1M and 1Y
|
|
460
|
+
* returns keep their baselines: the row's own return and price imply the
|
|
461
|
+
* start close.
|
|
379
462
|
*/
|
|
380
463
|
function isLiveSectorQuote(row: SectorRow, quote: Quote | null | undefined): quote is Quote {
|
|
381
|
-
if (!
|
|
382
|
-
if (!finitePositive(row.price) || !row.returnAsOfDate) return false;
|
|
383
|
-
if (row.quoteUpdatedAt != null && quote.lastUpdated < row.quoteUpdatedAt) return false;
|
|
464
|
+
if (!isCurrentSectorQuote(row, quote) || !finitePositive(getRegularSessionDisplay(quote)?.price)) return false;
|
|
384
465
|
return sectorQuoteSessionDate(quote) === row.returnAsOfDate;
|
|
385
466
|
}
|
|
386
467
|
|
|
468
|
+
/** A usable quote no older than the snapshot behind a loaded row. */
|
|
469
|
+
function isCurrentSectorQuote(row: SectorRow, quote: Quote | null | undefined): quote is Quote {
|
|
470
|
+
if (!quote || quote.stale === true) return false;
|
|
471
|
+
if (!finitePositive(row.price) || !row.returnAsOfDate) return false;
|
|
472
|
+
return row.quoteUpdatedAt == null || quote.lastUpdated >= row.quoteUpdatedAt;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/** A pre-market print of the session after the row's, which moves only the extended column. */
|
|
476
|
+
function isNextPreMarketQuote(row: SectorRow, quote: Quote): boolean {
|
|
477
|
+
if (quote.marketState !== "PRE" && quote.marketState !== "PREPRE") return false;
|
|
478
|
+
const session = sectorQuoteSessionDate(quote);
|
|
479
|
+
return !!session && !!row.returnAsOfDate && session > row.returnAsOfDate;
|
|
480
|
+
}
|
|
481
|
+
|
|
387
482
|
/**
|
|
388
483
|
* Whether the feed keeps a loaded row as current as a snapshot reload would,
|
|
389
484
|
* given a quote the feed is carrying. It does when the quote belongs to the
|
|
@@ -402,18 +497,32 @@ export function sectorRowFollowsQuote(row: SectorRow, quote: Quote): boolean {
|
|
|
402
497
|
return quote.marketState === "PRE" || quote.marketState === "PREPRE";
|
|
403
498
|
}
|
|
404
499
|
|
|
500
|
+
/**
|
|
501
|
+
* A row with the feed's quote on it. Price and 1D are the regular session,
|
|
502
|
+
* as `ticker` reads them, so they hold at the close; a pre-market or
|
|
503
|
+
* after-hours print moves only the extended column, measured from that close.
|
|
504
|
+
*/
|
|
405
505
|
export function overlayLiveSectorQuote(row: SectorRow, quote: Quote | null | undefined): SectorRow {
|
|
406
|
-
if (!
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
506
|
+
if (!isCurrentSectorQuote(row, quote) || row.price == null) return row;
|
|
507
|
+
if (!isLiveSectorQuote(row, quote)) {
|
|
508
|
+
if (!isNextPreMarketQuote(row, quote)) return row;
|
|
509
|
+
const extended = sectorExtendedFields(quote);
|
|
510
|
+
return sameExtended(extended, row) ? row : { ...row, ...extended };
|
|
511
|
+
}
|
|
512
|
+
const headline = getRegularSessionDisplay(quote)!;
|
|
513
|
+
const extended = sectorExtendedFields(quote);
|
|
514
|
+
const changePercent = Number.isFinite(headline.changePercent) ? headline.changePercent! : row.changePercent;
|
|
515
|
+
if (headline.price === row.price && changePercent === row.changePercent && sameExtended(extended, row)) return row;
|
|
516
|
+
const scale = headline.price / row.price;
|
|
517
|
+
// A held close leaves the returns exactly as they were.
|
|
518
|
+
const rescale = (value: number | null) => (value == null || scale === 1 ? value : ((1 + value / 100) * scale - 1) * 100);
|
|
411
519
|
return {
|
|
412
520
|
...row,
|
|
413
|
-
price:
|
|
414
|
-
lastReportedPrice:
|
|
521
|
+
price: headline.price,
|
|
522
|
+
lastReportedPrice: headline.price,
|
|
415
523
|
changePercent,
|
|
416
524
|
return1M: rescale(row.return1M),
|
|
417
525
|
return1Y: rescale(row.return1Y),
|
|
526
|
+
...extended,
|
|
418
527
|
};
|
|
419
528
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every chart a built-in pane draws, and whether its series is in the data
|
|
3
|
+
* catalog. `series-inventory.test.ts` fails when a module starts drawing a
|
|
4
|
+
* chart without an entry here, when an entry names a series nobody
|
|
5
|
+
* registers, or when a built-in registers a series this list does not name,
|
|
6
|
+
* so the audit cannot drift from the code.
|
|
7
|
+
*
|
|
8
|
+
* `series` lists catalog ids, with a trailing `*` for a prefix. A chart that
|
|
9
|
+
* is not in the catalog says why:
|
|
10
|
+
* - `not-a-time-series`: plotted against something other than dates (a
|
|
11
|
+
* curve by maturity, a surface, a treemap, strikes, a distribution).
|
|
12
|
+
* - `derived`: a chart composer study draws it from catalog series
|
|
13
|
+
* (correlation, realized volatility, a spread between two tickers).
|
|
14
|
+
* - `per-item`: one deal, trial, filing or model run, with no stable id to list.
|
|
15
|
+
* - `account`: built from the user's own portfolio or inputs.
|
|
16
|
+
* - `not-yet`: a dated series that could be registered and is not yet.
|
|
17
|
+
*/
|
|
18
|
+
type SeriesInventoryStatus =
|
|
19
|
+
/** `runtime`: registered while the app runs (files, accounts), so none exist in a test. */
|
|
20
|
+
| { series: readonly string[]; runtime?: true }
|
|
21
|
+
| { notInCatalog: "not-a-time-series" | "derived" | "per-item" | "account" | "not-yet"; reason: string };
|
|
22
|
+
|
|
23
|
+
export type SeriesInventoryEntry = SeriesInventoryStatus & {
|
|
24
|
+
/** The module's folder under `src/plugins/builtin`. */
|
|
25
|
+
module: string;
|
|
26
|
+
/** What the pane draws. */
|
|
27
|
+
chart: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const SERIES_INVENTORY: readonly SeriesInventoryEntry[] = [
|
|
31
|
+
{ module: "chart-composer", chart: "Any ticker field: price, volume, fundamentals, valuation multiples", series: ["field:*", "option:*"] },
|
|
32
|
+
{ module: "chart-composer", chart: "CSV files in the profile's series folder", series: ["user:*"], runtime: true },
|
|
33
|
+
{ module: "ticker-detail", chart: "Price history and the overview's sparklines", series: ["field:market.*"] },
|
|
34
|
+
{ module: "fear-greed", chart: "Fear & Greed index and its seven indicator charts, with their moving averages", series: ["fear-greed:*"] },
|
|
35
|
+
{ module: "volatility", chart: "VIX curve history, the 3M/30D ratio and the cross-asset volatility board", series: ["volatility:*", "fred:VIXCLS", "fred:VXVCLS"] },
|
|
36
|
+
{ module: "iv-history", chart: "A ticker's implied volatility by tenor", series: ["implied-vol:*"] },
|
|
37
|
+
{ module: "realized-vol", chart: "Realized volatility cone and rolling windows", notInCatalog: "derived", reason: "The composer's realized volatility study draws it from any price series." },
|
|
38
|
+
{ module: "vol-surface", chart: "Implied volatility surface by strike and expiry", notInCatalog: "not-a-time-series", reason: "A surface over strike and tenor." },
|
|
39
|
+
{ module: "options-positioning", chart: "Open interest and gamma by strike and expiry", notInCatalog: "not-a-time-series", reason: "Plotted by strike and expiry, not by date." },
|
|
40
|
+
{ module: "options-scenario", chart: "Option payoff by underlying price", notInCatalog: "not-a-time-series", reason: "A payoff curve over prices." },
|
|
41
|
+
{ module: "kelly-sizer", chart: "Position size against win rate", notInCatalog: "account", reason: "Drawn from the inputs typed into the sizer." },
|
|
42
|
+
{ module: "yield-curve", chart: "Treasury curve and each maturity's history", series: ["ust:*", "fred:T10Y2Y", "fred:T10Y3M", "fred:DFII*"] },
|
|
43
|
+
{ module: "yield-curve", chart: "Government curves for Germany, the UK, Japan, Canada and euro AAA", series: ["bond-yield:*"] },
|
|
44
|
+
{ module: "rate-path", chart: "Implied policy path by meeting", notInCatalog: "not-a-time-series", reason: "A path over future meetings; the rates it starts from are FRED series in the catalog." },
|
|
45
|
+
{ module: "money-markets", chart: "Money market rates, bill yields, liquidity and net liquidity", series: ["money-markets:*", "fred:SOFR", "fred:EFFR", "fred:IORB", "fred:OBFR", "fred:DTB*", "fred:RRPONTSYD", "fred:WDTGAL", "fred:WRESBAL", "fred:WALCL"] },
|
|
46
|
+
{ module: "central-bank-rates", chart: "Policy rate history for each central bank", series: ["policy-rate:*"] },
|
|
47
|
+
{ module: "econ", chart: "Release history of each economic calendar event", series: ["fred:*"] },
|
|
48
|
+
{ module: "econ-statistics", chart: "Inflation, labor and growth statistics with their ranges", series: ["fred:CPIAUCNS", "fred:CPILFENS", "fred:PCEPI", "fred:PCEPILFE", "fred:PPIFID", "fred:UNRATE", "fred:PAYEMS", "fred:ICSA", "fred:JTSJOL", "fred:GDPC1", "fred:INDPRO"] },
|
|
49
|
+
{ module: "cpi", chart: "CPI components, month on month and year on year", series: ["fred:CPI*", "fred:CUSR*"] },
|
|
50
|
+
{ module: "market-valuation", chart: "Whole-market valuation ratios against their history", series: ["market-valuation:*"] },
|
|
51
|
+
{ module: "credit-conditions", chart: "Corporate bond spreads by rating", series: ["fred:BAML*"] },
|
|
52
|
+
{ module: "credit-boards", chart: "Index CDS (CDX, iTraxx) and sovereign 5Y CDS", series: ["cdx:*", "sovereign-cds:*"] },
|
|
53
|
+
{ module: "cds", chart: "A company's 5Y CDS spread", series: ["cds:*"] },
|
|
54
|
+
{ module: "credit-documents", chart: "Principal due by year", notInCatalog: "not-a-time-series", reason: "A maturity schedule, not a history." },
|
|
55
|
+
{ module: "debt-maturities", chart: "A company's principal and the share due soon, across annual filings", series: ["debt-maturities:*"] },
|
|
56
|
+
{ module: "debt-maturities", chart: "A company's maturity wall", notInCatalog: "not-a-time-series", reason: "A schedule by maturity year from one filing; its total and near-term shares across filings are in the catalog." },
|
|
57
|
+
{ module: "doe", chart: "Weekly oil and gas inventories against their five-year range", series: ["doe:*"] },
|
|
58
|
+
{ module: "cot", chart: "Net positioning by trader class, over the front-month price", series: ["cot:*"] },
|
|
59
|
+
{ module: "futures", chart: "Front-month futures board, charted from the board", series: ["fut:*"] },
|
|
60
|
+
{ module: "futures-curve", chart: "Futures curve by contract month", notInCatalog: "not-a-time-series", reason: "Plotted by delivery month; each front month is in the catalog as FUT:code." },
|
|
61
|
+
{ module: "crypto-board", chart: "Price sparklines for the large coins", series: ["crypto:*"] },
|
|
62
|
+
{ module: "perps", chart: "Perpetual funding, open interest, premium and long/short account share", series: ["perps:*"] },
|
|
63
|
+
{ module: "perps", chart: "Perpetual mark price", notInCatalog: "not-yet", reason: "The pair's price is in the catalog; the perpetual's own mark price could be a crypto series." },
|
|
64
|
+
{ module: "short-interest", chart: "A ticker's short interest and days to cover", series: ["short-interest:*"] },
|
|
65
|
+
{ module: "short-volume", chart: "A ticker's daily short volume ratio", series: ["short-volume:*"] },
|
|
66
|
+
{ module: "social-mentions", chart: "A ticker's daily posts", series: ["social-mentions:*"] },
|
|
67
|
+
{ module: "jobs", chart: "A company's open job postings", series: ["jobs:*"] },
|
|
68
|
+
{ module: "attention", chart: "Research hours on a ticker, hour by hour", series: ["attention:*"] },
|
|
69
|
+
{ module: "company-attention", chart: "A company's weekly open roles and daily app attention score", series: ["hiring:*", "app-attention:*"] },
|
|
70
|
+
{ module: "gpu", chart: "GPU rental list index per model", series: ["gpu:*"] },
|
|
71
|
+
{ module: "gpu", chart: "GPU rental prices per provider listing", notInCatalog: "per-item", reason: "One provider listing each, listed by the server and changing without a release." },
|
|
72
|
+
{ module: "power", chart: "Interconnection queue capacity and project generation", notInCatalog: "per-item", reason: "Per project and per queue filter." },
|
|
73
|
+
{ module: "awards", chart: "A company's government award totals by period", series: ["awards:*"] },
|
|
74
|
+
{ module: "company-kpis", chart: "A company's reported operating metrics", notInCatalog: "per-item", reason: "Each company reports its own metrics, with no shared list to register." },
|
|
75
|
+
{ module: "estimate-revisions", chart: "Consensus estimate for one fiscal period over time", notInCatalog: "per-item", reason: "One fiscal period of one company." },
|
|
76
|
+
{ module: "earnings", chart: "Implied and actual moves around past earnings", notInCatalog: "per-item", reason: "One bar per earnings event." },
|
|
77
|
+
{ module: "dividend-yield", chart: "A ticker's trailing 12-month cash dividends", series: ["dividends:*"] },
|
|
78
|
+
{ module: "pe-band", chart: "Price against P/E multiples", notInCatalog: "derived", reason: "The composer charts price and the P/E fields for any ticker." },
|
|
79
|
+
{ module: "research", chart: "Analyst price targets over price", notInCatalog: "per-item", reason: "Targets are dated events on one ticker." },
|
|
80
|
+
{ module: "catalysts", chart: "Clinical trial enrollment", notInCatalog: "per-item", reason: "One trial." },
|
|
81
|
+
{ module: "mna", chart: "Deal spread for one merger", notInCatalog: "per-item", reason: "One deal." },
|
|
82
|
+
{ module: "correlation", chart: "Rolling correlation of two tickers and the matrix", notInCatalog: "derived", reason: "The composer's correlation study draws it for any two series." },
|
|
83
|
+
{ module: "relative-rotation", chart: "Relative strength and momentum against a benchmark", notInCatalog: "derived", reason: "Built from two price series; the rotation plot is not dated." },
|
|
84
|
+
{ module: "seasonality", chart: "Average returns by month and weekday", notInCatalog: "not-a-time-series", reason: "Plotted by calendar month, not by date." },
|
|
85
|
+
{ module: "backtest", chart: "A strategy's equity curve", notInCatalog: "account", reason: "One run of the user's own strategy settings." },
|
|
86
|
+
{ module: "analytics", chart: "Portfolio value, drawdown and factor exposure", notInCatalog: "account", reason: "Built from the user's own portfolio; the factor legs are tickers in the catalog." },
|
|
87
|
+
{ module: "holders", chart: "Holders treemap", notInCatalog: "not-a-time-series", reason: "A treemap of one filing date." },
|
|
88
|
+
{ module: "market-heatmap", chart: "Market heat map", notInCatalog: "not-a-time-series", reason: "A treemap of today's moves." },
|
|
89
|
+
{ module: "portfolio-list", chart: "Portfolio treemap", notInCatalog: "not-a-time-series", reason: "A treemap of current positions." },
|
|
90
|
+
{ module: "world-venue-map", chart: "Chokepoint transits and the map's place series", series: ["geo:*"] },
|
|
91
|
+
];
|
|
@@ -12,7 +12,7 @@ import { requestAccountManagementTab } from "../account-management/navigation";
|
|
|
12
12
|
import { resolvePlanAccess, usePlanAccess, type PlanAccess } from "../../../api-client/plan-access";
|
|
13
13
|
import { useViewport } from "../../../react/input";
|
|
14
14
|
import { useOptionalDialog } from "../../../ui/dialog";
|
|
15
|
-
import { promptCloudUpgrade } from "
|
|
15
|
+
import { promptCloudUpgrade } from "../../../account/upgrade-dialog";
|
|
16
16
|
|
|
17
17
|
const CLOUD_UPGRADE_URL = "https://gloom.sh/cloud?upgrade=pro";
|
|
18
18
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import { usePluginPaneState } from "../../../public/react";
|
|
3
|
+
import { usePaneInstance } from "../../../state/app/context";
|
|
4
|
+
import type { PaneTemplateDef, PaneTemplateInstanceConfig } from "../../../types/plugin";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A command's request (a market, a record), stamped so a later command can ask again: a pane the command reuses
|
|
8
|
+
* sees the newer stamp even when it asks for the same thing.
|
|
9
|
+
*/
|
|
10
|
+
export function commandRequestParams(params: Record<string, string>): Record<string, string> {
|
|
11
|
+
return { ...params, tabAt: String(Date.now()) };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** A command's request to show one tab, stamped so a later command can ask again. */
|
|
15
|
+
export function commandTabParams(tab: string, params?: Record<string, string>): Record<string, string> {
|
|
16
|
+
return commandRequestParams({ ...(params ?? {}), tab });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** The template's pane, with the command's tab written onto the instance. */
|
|
20
|
+
function stampCommandTab(instance: PaneTemplateInstanceConfig | null, tab: string): PaneTemplateInstanceConfig | null {
|
|
21
|
+
return instance ? { ...instance, params: commandTabParams(tab, instance.params) } : null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function withCommandTab(template: PaneTemplateDef, tab: string): PaneTemplateDef {
|
|
25
|
+
const create = template.createInstance;
|
|
26
|
+
return {
|
|
27
|
+
...template,
|
|
28
|
+
createInstance: (context, options) => {
|
|
29
|
+
const created = create?.(context, options);
|
|
30
|
+
if (!created) return null;
|
|
31
|
+
return created instanceof Promise ? created.then((instance) => stampCommandTab(instance, tab)) : stampCommandTab(created, tab);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A value a command asked this pane to show, kept in pane state like a choice made in the pane: the stored
|
|
38
|
+
* choice wins until a newer command arrives. `read` takes the value from the command's params, null when the
|
|
39
|
+
* command names none. Another pane's params, such as Ticker Research around a nested tab, are ignored.
|
|
40
|
+
*/
|
|
41
|
+
export function useCommandValue<T>(
|
|
42
|
+
paneId: string,
|
|
43
|
+
stateKey: string,
|
|
44
|
+
read: (params: Readonly<Record<string, string>>) => T | null,
|
|
45
|
+
fallback: T,
|
|
46
|
+
): [T, (next: T) => void] {
|
|
47
|
+
const instance = usePaneInstance();
|
|
48
|
+
const params = instance?.paneId === paneId ? instance.params : undefined;
|
|
49
|
+
const requested = params ? read(params) : null;
|
|
50
|
+
const requestAt = params?.tabAt ?? "";
|
|
51
|
+
const [value, setValue] = usePluginPaneState<T>(stateKey, requested ?? fallback);
|
|
52
|
+
const seen = useRef(requestAt);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (requested === null || requestAt === seen.current) return;
|
|
55
|
+
seen.current = requestAt;
|
|
56
|
+
setValue(requested);
|
|
57
|
+
}, [requestAt, requested, setValue]);
|
|
58
|
+
return [value, setValue];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The tab a command asked this pane to show, one of `tabs`. */
|
|
62
|
+
export function useCommandTab<T extends string>(
|
|
63
|
+
paneId: string,
|
|
64
|
+
stateKey: string,
|
|
65
|
+
tabs: readonly T[],
|
|
66
|
+
fallback: T,
|
|
67
|
+
): [T, (next: T) => void] {
|
|
68
|
+
return useCommandValue<T>(paneId, stateKey, (params) => (tabs as readonly string[]).includes(params.tab ?? "") ? params.tab as T : null, fallback);
|
|
69
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { EarningsDateStatus, EarningsEpsBasis } from "../../../types/financials";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How every earnings surface (ERN, EE, the corporate-actions events and
|
|
5
|
+
* their headless rows) reads and names a reported quarter's EPS basis and a
|
|
6
|
+
* report date's status. Gloom Cloud resolves one figure per quarter; this
|
|
7
|
+
* keeps the panes from naming it differently.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const BASES: ReadonlySet<string> = new Set<EarningsEpsBasis>(["gaap", "adjusted"]);
|
|
11
|
+
const STATUSES: ReadonlySet<string> = new Set<EarningsDateStatus>(["reported", "confirmed", "projected"]);
|
|
12
|
+
|
|
13
|
+
/** A server value read defensively: anything unrecognised is an unknown basis. */
|
|
14
|
+
export function earningsEpsBasis(value: unknown): EarningsEpsBasis | null {
|
|
15
|
+
return typeof value === "string" && BASES.has(value) ? value as EarningsEpsBasis : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function earningsDateStatus(value: unknown): EarningsDateStatus | null {
|
|
19
|
+
return typeof value === "string" && STATUSES.has(value) ? value as EarningsDateStatus : null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The per-ticker calendar flags an estimated date; it says nothing about a date it does not flag. */
|
|
23
|
+
export function dateStatusFromEstimateFlag(isDateEstimate: boolean | null | undefined): EarningsDateStatus | null {
|
|
24
|
+
return isDateEstimate === true ? "projected" : isDateEstimate === false ? "confirmed" : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type EpsBasisName = "GAAP" | "adjusted" | "unknown";
|
|
28
|
+
|
|
29
|
+
/** What the basis names mean, in every report's metadata. */
|
|
30
|
+
export const EPS_BASIS_NOTE = "One reported EPS per quarter. GAAP: the quarter's diluted statement EPS. adjusted: the consensus-basis figure the estimate is measured against, which leaves out items the statements include. unknown: no statement on a comparable share basis to tell.";
|
|
31
|
+
|
|
32
|
+
/** The basis as rows, exports and tools name it. */
|
|
33
|
+
export function epsBasisName(basis: EarningsEpsBasis | null): EpsBasisName {
|
|
34
|
+
return basis === "gaap" ? "GAAP" : basis === "adjusted" ? "adjusted" : "unknown";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The basis in a table cell or a detail line. */
|
|
38
|
+
export function epsBasisShort(basis: EarningsEpsBasis | null): string {
|
|
39
|
+
return basis === "gaap" ? "GAAP" : basis === "adjusted" ? "adj" : "?";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Actual over estimate minus one, against the estimate's size so a negative estimate reads the right way. */
|
|
43
|
+
export function epsSurprise(actual: number | null | undefined, estimate: number | null | undefined): number | null {
|
|
44
|
+
if (actual == null || estimate == null || estimate === 0) return null;
|
|
45
|
+
return (actual - estimate) / Math.abs(estimate);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A fiscal quarter end month (YYYY-MM) holds a period end in that month, or a 52/53-week end a few days either side. */
|
|
49
|
+
export function inFiscalMonth(periodEnd: string | null | undefined, fiscalPeriod: string | null | undefined): boolean {
|
|
50
|
+
const month = /^(\d{4})-(\d{2})$/.exec(fiscalPeriod ?? "");
|
|
51
|
+
const end = Date.parse(`${periodEnd ?? ""}T00:00:00Z`);
|
|
52
|
+
if (!month || !Number.isFinite(end)) return false;
|
|
53
|
+
const monthEnd = Date.UTC(Number(month[1]), Number(month[2]), 0);
|
|
54
|
+
return end >= monthEnd - 35 * 86_400_000 && end <= monthEnd + 10 * 86_400_000;
|
|
55
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { apiClient } from "../../../api-client";
|
|
2
|
+
import { loadCachedFredSeries } from "../../../sources/gloomberb-cloud/fred-series";
|
|
3
|
+
|
|
4
|
+
/** A FRED series from `start` on, oldest first, through the shared FRED cache. */
|
|
5
|
+
export async function loadFredPoints(seriesId: string, start?: Date): Promise<{
|
|
6
|
+
points: Array<{ date: string; value: number | null }>;
|
|
7
|
+
stale: boolean;
|
|
8
|
+
refreshError?: string;
|
|
9
|
+
}> {
|
|
10
|
+
const startDate = start ? start.toISOString().slice(0, 10) : "1900-01-01";
|
|
11
|
+
const result = await loadCachedFredSeries(
|
|
12
|
+
{ seriesId, startDate, sortOrder: "asc" },
|
|
13
|
+
() => apiClient.getCloudFredSeries(seriesId, { startDate, sortOrder: "asc" }),
|
|
14
|
+
);
|
|
15
|
+
return {
|
|
16
|
+
points: (result.data.observations ?? []).map((row) => ({ date: row.date, value: row.value })),
|
|
17
|
+
stale: result.stale,
|
|
18
|
+
...(result.refreshError ? { refreshError: result.refreshError } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|