gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
type ManualChartResolution,
|
|
10
10
|
} from "../../../../time-series/resolution";
|
|
11
11
|
import type { PricePoint } from "../../../../types/financials";
|
|
12
|
-
import { isAlwaysOpenExchange, isRegularSessionTime, latestRegularSessionClose } from "../../../../market-data/market/freshness";
|
|
12
|
+
import { isAlwaysOpenExchange, isRegularSessionTime, latestRegularSessionClose, sessionCalendarTimeZone } from "../../../../market-data/market/freshness";
|
|
13
|
+
import { barLastSession } from "../../../../market-data/market/bar-period";
|
|
14
|
+
import {
|
|
15
|
+
barCloseDay, barSessionDay, isIntradayDailyBar, isReturnPeriod, periodBaseDay, periodBaseIndex,
|
|
16
|
+
} from "../../../../market-data/market/period-return";
|
|
13
17
|
import { isRoundTheClockCoin } from "../../../../utils/crypto-pair";
|
|
14
18
|
import { currentFxClosureStart, isCurrencyPairListing } from "../../../../utils/fx-market-hours";
|
|
15
19
|
import { pricePointValues } from "../../../../utils/price-history-integrity";
|
|
@@ -49,12 +53,56 @@ export function returnWindowStart(range: ReturnRange, end: number): number {
|
|
|
49
53
|
return subtractTimeRange(new Date(end), range).getTime();
|
|
50
54
|
}
|
|
51
55
|
|
|
56
|
+
const utcDay = (time: number) => new Date(time).toISOString().slice(0, 10);
|
|
57
|
+
|
|
58
|
+
/** The session date of `time` at a venue, on its clock; the UTC date where its sessions are unknown. */
|
|
59
|
+
function venueDay(time: number, venue: string | undefined): string {
|
|
60
|
+
const zone = venue ? sessionCalendarTimeZone(venue) : null;
|
|
61
|
+
return zone ? zonedDateKey(time, zone) : utcDay(time);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The calendar date a 1W to 5Y window ending at `end` is measured from, the
|
|
66
|
+
* close on or before which is the base of its returns (periodBaseDay), as CMP
|
|
67
|
+
* and every period return measure it: 1M ending Wed 21 Oct is from Mon 21
|
|
68
|
+
* Sep's close. Null for 6H, 1D and 5D, which are spans of time, and ALL.
|
|
69
|
+
*/
|
|
70
|
+
export function returnBaseDay(range: ReturnRange, end: number, venue?: string): string | null {
|
|
71
|
+
return isReturnPeriod(range) ? periodBaseDay(venueDay(end, venue), range) : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Where the rows after a base day start, exclusive: past the base day's
|
|
76
|
+
* session close for intraday bars, and before the first bar whose close is
|
|
77
|
+
* from after it for daily (stamped by their date at midnight UTC), weekly
|
|
78
|
+
* and monthly ones (stamped by their period's first day, barCloseDay). For
|
|
79
|
+
* daily and longer bars this is what a request reaches back from; the rows
|
|
80
|
+
* start where returnRowsFrom finds the base among the loaded bars.
|
|
81
|
+
*/
|
|
82
|
+
function afterBaseDay(baseDay: string, resolution: ManualChartResolution, venue: string | undefined): number {
|
|
83
|
+
const nextDay = Date.parse(`${baseDay}T00:00:00Z`) + DAY_MS;
|
|
84
|
+
if (isIntradayResolution(resolution)) {
|
|
85
|
+
// Midnight UTC after the base day is past every venue's close of it and before its next one.
|
|
86
|
+
const close = venue ? latestRegularSessionClose(venue, nextDay) : null;
|
|
87
|
+
return close && close.date <= baseDay ? close.close - 1 : nextDay - 1;
|
|
88
|
+
}
|
|
89
|
+
for (let day = nextDay - 40 * DAY_MS; day <= nextDay; day += DAY_MS) {
|
|
90
|
+
if (barCloseDay(utcDay(day), resolution, venue) > baseDay) return day - 1;
|
|
91
|
+
}
|
|
92
|
+
return nextDay - 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
52
95
|
/**
|
|
53
|
-
* Where the rows start, exclusive
|
|
54
|
-
*
|
|
55
|
-
*
|
|
96
|
+
* Where the rows start, exclusive, before the bars are loaded: what the
|
|
97
|
+
* request reaches back from. A 1W to 5Y window starts after its base day
|
|
98
|
+
* (returnBaseDay), so the close on or before it is the bar before the rows
|
|
99
|
+
* and the base of every return. Otherwise the window's start for intraday
|
|
100
|
+
* bars; a daily or longer bar is stamped with its date at midnight UTC, so
|
|
101
|
+
* the window takes every bar from its start date on.
|
|
56
102
|
*/
|
|
57
|
-
export function returnVisibleFrom(range: ReturnRange, resolution: ManualChartResolution, end: number): number {
|
|
103
|
+
export function returnVisibleFrom(range: ReturnRange, resolution: ManualChartResolution, end: number, venue?: string): number {
|
|
104
|
+
const baseDay = returnBaseDay(range, end, venue);
|
|
105
|
+
if (baseDay) return afterBaseDay(baseDay, resolution, venue);
|
|
58
106
|
const start = returnWindowStart(range, end);
|
|
59
107
|
if (isIntradayResolution(resolution)) return start;
|
|
60
108
|
const day = new Date(start);
|
|
@@ -62,6 +110,31 @@ export function returnVisibleFrom(range: ReturnRange, resolution: ManualChartRes
|
|
|
62
110
|
return day.getTime() - 1;
|
|
63
111
|
}
|
|
64
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Where the rows start among the loaded bars, exclusive. A 1W to 5Y window
|
|
115
|
+
* of daily or longer bars starts after the bar on or before its base day,
|
|
116
|
+
* each bar dated by its session day (barSessionDay; a week or month by the
|
|
117
|
+
* day it closes), so that close is the bar before the rows however the feed
|
|
118
|
+
* stamps it: a JPX bar at 00:00 JST is 15:00 UTC the day before. Without a
|
|
119
|
+
* bar on or before the base day, every bar is a row. Otherwise
|
|
120
|
+
* returnVisibleFrom.
|
|
121
|
+
*/
|
|
122
|
+
export function returnRowsFrom(
|
|
123
|
+
points: readonly PricePoint[],
|
|
124
|
+
range: ReturnRange,
|
|
125
|
+
resolution: ManualChartResolution,
|
|
126
|
+
end: number,
|
|
127
|
+
venue?: string,
|
|
128
|
+
): number {
|
|
129
|
+
const estimate = returnVisibleFrom(range, resolution, end, venue);
|
|
130
|
+
const baseDay = returnBaseDay(range, end, venue);
|
|
131
|
+
const bars = toBars(points);
|
|
132
|
+
if (!baseDay || isIntradayResolution(resolution) || !bars.length) return estimate;
|
|
133
|
+
const days = bars.map((bar) => barCloseDay(barSessionDay(bar.timestamp, venue), resolution, venue));
|
|
134
|
+
const index = periodBaseIndex(days, baseDay, Number.POSITIVE_INFINITY);
|
|
135
|
+
return index < 0 ? bars[0]!.timestamp - 1 : bars[index]!.timestamp;
|
|
136
|
+
}
|
|
137
|
+
|
|
65
138
|
/**
|
|
66
139
|
* These windows are shorter than a closed market's gap, so they also end at
|
|
67
140
|
* the latest bar when it is earlier: a venue whose sessions the app does not
|
|
@@ -120,6 +193,11 @@ function lookbackDays(resolution: ManualChartResolution): number {
|
|
|
120
193
|
return 62;
|
|
121
194
|
}
|
|
122
195
|
|
|
196
|
+
/** How far before a dated window (`--from`) the request reaches for the bar before it: a weekend and a holiday. */
|
|
197
|
+
export function returnWindowLookbackMs(resolution: ManualChartResolution): number {
|
|
198
|
+
return lookbackDays(resolution) * DAY_MS;
|
|
199
|
+
}
|
|
200
|
+
|
|
123
201
|
/**
|
|
124
202
|
* How far before the window the request reaches. The bar just before the
|
|
125
203
|
* window is the base of every return, so the request covers a weekend or
|
|
@@ -245,6 +323,35 @@ export function buildReturnRows(
|
|
|
245
323
|
return rows.reverse();
|
|
246
324
|
}
|
|
247
325
|
|
|
326
|
+
/**
|
|
327
|
+
* The session day of the close every return of a window is measured from
|
|
328
|
+
* (buildReturnRows' base): the bar before its rows, else its first priced
|
|
329
|
+
* bar. A daily bar's date, a weekly or monthly bar's last session, an
|
|
330
|
+
* intraday bar's session date at its venue. Null for a window without rows.
|
|
331
|
+
*/
|
|
332
|
+
export function returnBaseCloseDay(
|
|
333
|
+
points: readonly PricePoint[],
|
|
334
|
+
visibleFrom: number,
|
|
335
|
+
resolution: ManualChartResolution,
|
|
336
|
+
venue: string | undefined,
|
|
337
|
+
now: number,
|
|
338
|
+
): string | null {
|
|
339
|
+
const bars = toBars(points);
|
|
340
|
+
const first = bars.findIndex((bar) => bar.timestamp > visibleFrom);
|
|
341
|
+
if (first < 0) return null;
|
|
342
|
+
const base = first > 0 && bars[first - 1]!.close !== null ? bars[first - 1] : bars.slice(first).find((bar) => bar.close !== null);
|
|
343
|
+
if (!base) return null;
|
|
344
|
+
if (isIntradayResolution(resolution)) return venueDay(base.timestamp, venue);
|
|
345
|
+
const day = barSessionDay(base.timestamp, venue);
|
|
346
|
+
const period = resolution === "1wk" ? "week" : resolution === "1mo" ? "month" : null;
|
|
347
|
+
return period ? barLastSession(day, period, venue, now) ?? barCloseDay(day, resolution, venue) : day;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Whether the newest daily row is the session still trading at its venue, which its table marks. */
|
|
351
|
+
export function isTodayReturnRow(row: Pick<ReturnRow, "timestamp"> | undefined, resolution: ManualChartResolution, venue: string | undefined, now: number): boolean {
|
|
352
|
+
return !!row && resolution === "1d" && isIntradayDailyBar(barSessionDay(row.timestamp, venue), venue, now);
|
|
353
|
+
}
|
|
354
|
+
|
|
248
355
|
/** The latest bar time in a loaded history, or null when it has none. */
|
|
249
356
|
export function latestBarTime(points: readonly PricePoint[]): number | null {
|
|
250
357
|
let latest: number | null = null;
|
|
@@ -37,12 +37,16 @@ import {
|
|
|
37
37
|
buildReturnRows,
|
|
38
38
|
closedMarketNote,
|
|
39
39
|
effectiveReturnResolution,
|
|
40
|
+
isTodayReturnRow,
|
|
41
|
+
returnBaseCloseDay,
|
|
40
42
|
RETURN_RANGES,
|
|
41
43
|
type ReturnRange,
|
|
42
44
|
type ReturnRow,
|
|
43
45
|
} from "./returns-model";
|
|
44
46
|
import { loadReturnSeries, type ReturnSeries } from "./returns-history";
|
|
45
47
|
import { formingHistoryBar, formingHistoryBarText, historyBarDate } from "./history-bars";
|
|
48
|
+
import { periodBaseText } from "../../../../market-data/market/period-return";
|
|
49
|
+
import { DAY_SO_FAR_TEXT } from "../../../../time-series/session-bar";
|
|
46
50
|
|
|
47
51
|
type ReturnColumnId = "time" | "price" | "intervalChange" | "intervalPercent" | "cumulativeChange" | "cumulativePercent";
|
|
48
52
|
type ReturnColumn = DataTableColumn & { id: ReturnColumnId };
|
|
@@ -192,15 +196,24 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
192
196
|
() => data ? formingHistoryBar(data.resolution, newestDate, data.venue || undefined, Date.now()) : null,
|
|
193
197
|
[data, newestDate],
|
|
194
198
|
);
|
|
195
|
-
|
|
199
|
+
// Today's daily bar is the session still trading, marked as Historical Prices marks it.
|
|
200
|
+
const dayToDate = !!data && isTodayReturnRow(returnRows[0], data.resolution, data.venue || undefined, Date.now());
|
|
201
|
+
const formingKey = forming || dayToDate ? returnRows[0]?.key : undefined;
|
|
196
202
|
const barSize = data?.resolution ?? shownResolution;
|
|
203
|
+
// The close every total is measured from: `from Mon 21 Sep close`.
|
|
204
|
+
const baseText = useMemo(() => {
|
|
205
|
+
const day = data && returnRows.length ? returnBaseCloseDay(data.points, data.visibleFrom, data.resolution, data.venue || undefined, Date.now()) : null;
|
|
206
|
+
return day ? periodBaseText(day) : null;
|
|
207
|
+
}, [data, returnRows.length]);
|
|
197
208
|
// A shut market's window ends at its last session, which the footer names.
|
|
198
209
|
const marketInfo = useMemo<PaneFooterSegment[]>(() => [
|
|
210
|
+
...baseText ? [{ id: "base", parts: [{ text: baseText, tone: "muted" as const }] }] : [],
|
|
199
211
|
...data?.lastSession
|
|
200
212
|
? [{ id: "market", parts: [{ text: closedMarketNote(data.lastSession, data.visibleTo), tone: "muted" as const }] }]
|
|
201
213
|
: [],
|
|
202
214
|
...forming && newestDate ? [{ id: "forming", parts: [{ text: formingHistoryBarText(forming, newestDate), tone: "muted" as const }] }] : [],
|
|
203
|
-
|
|
215
|
+
...dayToDate ? [{ id: "forming", parts: [{ text: DAY_SO_FAR_TEXT, tone: "muted" as const }] }] : [],
|
|
216
|
+
], [baseText, data, dayToDate, forming, newestDate]);
|
|
204
217
|
usePaneStatusFooter({ registrationId: "returns", loading, error, hints, info: marketInfo });
|
|
205
218
|
|
|
206
219
|
const integrityNotice = priceHistoryIntegrityNotice(returnRows.filter((row) => row.inconsistent).length);
|
|
@@ -288,6 +301,8 @@ export function ReturnsPane({ focused, width, height }: PaneProps) {
|
|
|
288
301
|
["Range", data?.range ?? range],
|
|
289
302
|
["Interval", getChartResolutionLabel(data?.resolution ?? shownResolution)],
|
|
290
303
|
...(forming && newestDate ? [["Partial bar", `${newestDate}, ${formingHistoryBarText(forming, newestDate)}`]] : []),
|
|
304
|
+
...(dayToDate && newestDate ? [["Partial bar", `${newestDate}, ${DAY_SO_FAR_TEXT}`]] : []),
|
|
305
|
+
...(baseText ? [["Base", baseText]] : []),
|
|
291
306
|
["Window", data ? `after ${new Date(data.visibleFrom).toISOString()} through ${new Date(data.visibleTo).toISOString()}` : ""],
|
|
292
307
|
...(data?.lastSession ? [["Market", closedMarketNote(data.lastSession, data.visibleTo)]] : []),
|
|
293
308
|
["Time zone", "UTC, bar open"],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EarningsField, FinancialStatement } from "../../../../types/financials";
|
|
2
2
|
import { completeAvailability, statementFieldAvailability } from "../../../../utils/financial-statements";
|
|
3
3
|
import { hasStatementGap } from "../../../../utils/statement-gaps";
|
|
4
|
+
import { trailingEpsAcrossFiscalYearEnd } from "../../../../utils/trailing-eps";
|
|
4
5
|
|
|
5
6
|
export type FinancialPeriod = "annual" | "quarterly";
|
|
6
7
|
|
|
@@ -159,6 +160,8 @@ const BALANCE_KEYS = new Set<string>([
|
|
|
159
160
|
function aggregateQuarterlyStatements(
|
|
160
161
|
statements: FinancialStatement[],
|
|
161
162
|
date: string,
|
|
163
|
+
/** Every quarter and fiscal year on file, for EPS across a fiscal Q4 that reports none. */
|
|
164
|
+
onFile: { quarterly: readonly FinancialStatement[]; annual: readonly FinancialStatement[] } = { quarterly: [], annual: [] },
|
|
162
165
|
): FinancialTableStatement | null {
|
|
163
166
|
if (statements.length !== 4) return null;
|
|
164
167
|
// A provider may return semiannual reports or skip a quarter. Four rows do
|
|
@@ -215,6 +218,11 @@ function aggregateQuarterlyStatements(
|
|
|
215
218
|
if (values.length === 4) {
|
|
216
219
|
(aggregate as unknown as Record<string, unknown>)[key] = values.reduce((left, right) => left + right, 0);
|
|
217
220
|
retainAvailability(key, statements);
|
|
221
|
+
} else if (key === "eps" || key === "basicEps") {
|
|
222
|
+
const acrossYearEnd = trailingEpsAcrossFiscalYearEnd(statements, onFile.quarterly, onFile.annual, key);
|
|
223
|
+
if (!acrossYearEnd) continue;
|
|
224
|
+
aggregate[key] = acrossYearEnd.value;
|
|
225
|
+
retainAvailability(key, acrossYearEnd.inputs);
|
|
218
226
|
}
|
|
219
227
|
}
|
|
220
228
|
|
|
@@ -252,18 +260,24 @@ function aggregateQuarterlyStatements(
|
|
|
252
260
|
* reads a flow over a year from. Null when fewer than four consecutive
|
|
253
261
|
* quarters end there.
|
|
254
262
|
*/
|
|
255
|
-
export function trailingFourQuarters(
|
|
263
|
+
export function trailingFourQuarters(
|
|
264
|
+
quarterlyStatements: readonly FinancialStatement[],
|
|
265
|
+
end: string,
|
|
266
|
+
annualStatements: readonly FinancialStatement[] = [],
|
|
267
|
+
) {
|
|
256
268
|
const sorted = [...quarterlyStatements].sort((a, b) => a.date.localeCompare(b.date));
|
|
257
269
|
const index = sorted.findIndex((statement) => statement.date === end);
|
|
258
|
-
return index < 3 ? null : aggregateQuarterlyStatements(sorted.slice(index - 3, index + 1), "TTM");
|
|
270
|
+
return index < 3 ? null : aggregateQuarterlyStatements(sorted.slice(index - 3, index + 1), "TTM", { quarterly: sorted, annual: annualStatements });
|
|
259
271
|
}
|
|
260
272
|
|
|
261
|
-
export function computeTTM(quarterlyStatements: FinancialStatement[]) {
|
|
262
|
-
|
|
273
|
+
export function computeTTM(quarterlyStatements: FinancialStatement[], annualStatements: readonly FinancialStatement[] = []) {
|
|
274
|
+
const sorted = [...quarterlyStatements].sort((a, b) => a.date.localeCompare(b.date));
|
|
275
|
+
return aggregateQuarterlyStatements(sorted.slice(-4), "TTM", { quarterly: sorted, annual: annualStatements });
|
|
263
276
|
}
|
|
264
277
|
|
|
265
|
-
function computePreviousTtm(quarterlyStatements: FinancialStatement[]) {
|
|
266
|
-
|
|
278
|
+
function computePreviousTtm(quarterlyStatements: FinancialStatement[], annualStatements: readonly FinancialStatement[]) {
|
|
279
|
+
const sorted = [...quarterlyStatements].sort((a, b) => a.date.localeCompare(b.date));
|
|
280
|
+
return aggregateQuarterlyStatements(sorted.slice(-8, -4), "prevTTM", { quarterly: sorted, annual: annualStatements });
|
|
267
281
|
}
|
|
268
282
|
|
|
269
283
|
export function buildPreviousStatementMap(
|
|
@@ -295,7 +309,7 @@ export function buildPreviousStatementMap(
|
|
|
295
309
|
}
|
|
296
310
|
|
|
297
311
|
if (ttm) {
|
|
298
|
-
const previousTtm = computePreviousTtm(quarterlyStatements);
|
|
312
|
+
const previousTtm = computePreviousTtm(quarterlyStatements, annualStatements);
|
|
299
313
|
const latest = quarterlyStatements.at(-1);
|
|
300
314
|
const prior = quarterlyStatements.at(-5);
|
|
301
315
|
const days = latest && prior ? (Date.parse(latest.date) - Date.parse(prior.date)) / 86_400_000 : NaN;
|
|
@@ -123,6 +123,8 @@ export function canCompareFinancialRow(
|
|
|
123
123
|
): boolean {
|
|
124
124
|
if (!previous) return false;
|
|
125
125
|
const key = row.kind === "group" ? row.summaryKey : row.key;
|
|
126
|
+
// A line filled from the exchange is not compared with the statements source's: the two define revenue differently.
|
|
127
|
+
if (key && filledLine(current, key) !== filledLine(previous, key)) return false;
|
|
126
128
|
const sameShareBasis = current.shareBasis === previous.shareBasis;
|
|
127
129
|
if (key && SHARE_COUNT_FIELDS.has(key)) return sameShareBasis;
|
|
128
130
|
if (key && PER_SHARE_EARNINGS_FIELDS.has(key) && !sameShareBasis) return false;
|
|
@@ -131,6 +133,10 @@ export function canCompareFinancialRow(
|
|
|
131
133
|
return !!currentCurrency && currentCurrency === previousCurrency;
|
|
132
134
|
}
|
|
133
135
|
|
|
136
|
+
function filledLine(statement: FinancialStatement, key: keyof FinancialStatement): boolean {
|
|
137
|
+
return statement.filledFrom?.fields.some((field) => field === key) === true;
|
|
138
|
+
}
|
|
139
|
+
|
|
134
140
|
export function semanticGrowthValue(
|
|
135
141
|
growth: number | undefined,
|
|
136
142
|
direction: FinancialGrowthDirection,
|
|
@@ -513,7 +519,7 @@ export function selectFinancialStatements(
|
|
|
513
519
|
.filter((candidate) => !tabRows || tabRows.some((row) => hasFinancialRowValue(row, [candidate])))
|
|
514
520
|
.slice(-limit)
|
|
515
521
|
.reverse();
|
|
516
|
-
const trailing = period === "annual" && statement !== "balance" ? computeTTM(quarterlyStatements) : null;
|
|
522
|
+
const trailing = period === "annual" && statement !== "balance" ? computeTTM(quarterlyStatements, annualStatements) : null;
|
|
517
523
|
// Right after a fiscal year closes, the last four quarters are that year:
|
|
518
524
|
// the reported year is shown, not a second column of the same period.
|
|
519
525
|
const ttm = trailing && !coversLatestYear(trailing, rawStatements[0]) ? trailing : null;
|
|
@@ -606,3 +612,32 @@ export function buildFinancialTableModel(
|
|
|
606
612
|
|
|
607
613
|
return { period, subTab, statements, rows, unit };
|
|
608
614
|
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* A statement table's columns for stalePeriodNote, each with whether the
|
|
618
|
+
* statement's lead line (its first: revenue, total assets, free cash flow)
|
|
619
|
+
* has a figure in it, so a newer column with only some figures (an EPS
|
|
620
|
+
* alone) is not read as the latest period.
|
|
621
|
+
*/
|
|
622
|
+
export function financialStatementPeriods(
|
|
623
|
+
statements: readonly FinancialTableStatement[],
|
|
624
|
+
subTab: Pick<FinancialSubTab, "rows">,
|
|
625
|
+
): Array<{ date: string; lead: boolean }> {
|
|
626
|
+
const lead = subTab.rows[0];
|
|
627
|
+
return statements.map((statement) => ({ date: statement.date, lead: !!lead && hasFinancialRowValue(lead, [statement]) }));
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/** The statement lines a table has a row for (filledPeriodsNote), group totals included. */
|
|
631
|
+
export function financialSubTabFields(subTab: Pick<FinancialSubTab, "rows">): Set<string> {
|
|
632
|
+
const fields = new Set<string>();
|
|
633
|
+
const visit = (rows: readonly FinancialRowDef[]) => {
|
|
634
|
+
for (const row of rows) {
|
|
635
|
+
if (isFinancialGroup(row)) {
|
|
636
|
+
if (row.summaryKey) fields.add(row.summaryKey);
|
|
637
|
+
visit(row.children);
|
|
638
|
+
} else if (row.key) fields.add(row.key);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
visit(subTab.rows);
|
|
642
|
+
return fields;
|
|
643
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
|
+
import { apiClient } from "../../../../api-client";
|
|
3
|
+
import { createPluginCache } from "../../../../data/plugin-cache";
|
|
4
|
+
import { useAsyncResource } from "../../../../public/react";
|
|
5
|
+
import type { TickerFinancials } from "../../../../types/financials";
|
|
6
|
+
import { fetchOfferingFilings, offeringNote, offeringsAfter, type OfferingFiling } from "../../../../utils/cash-runway";
|
|
7
|
+
import { latestFinancialPeriod } from "../../../../utils/latest-financial-period";
|
|
8
|
+
import { nonUsSecListingVenue } from "../../../../utils/sec";
|
|
9
|
+
import { cachedCloudResource, loadCloudResource } from "../../shared/cloud-resource";
|
|
10
|
+
|
|
11
|
+
/** A prospectus is filed days before the cash lands; an hour-old list is recent enough for the note. */
|
|
12
|
+
export const offeringFilingsCache = createPluginCache<OfferingFiling[]>({
|
|
13
|
+
kind: "offering-filings", source: "gloom-cloud", schemaVersion: 1,
|
|
14
|
+
policy: { staleMs: 60 * 60_000, expireMs: 7 * 24 * 60 * 60_000 },
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/** The newest balance sheet the statements carry: the latest quarter's, or the latest year's without quarters. */
|
|
18
|
+
export function latestBalanceSheetDate(financials: Pick<TickerFinancials, "annualStatements" | "quarterlyStatements"> | null | undefined): string | null {
|
|
19
|
+
const latest = latestFinancialPeriod([...financials?.quarterlyStatements ?? [], ...financials?.annualStatements ?? []], (row) => row.date);
|
|
20
|
+
return latest?.date ?? null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Offering prospectuses for a US company; a listing abroad files none of these. */
|
|
24
|
+
function offeringSymbol(symbol: string | null | undefined, exchange: string | undefined): string | null {
|
|
25
|
+
const key = symbol?.trim().toUpperCase();
|
|
26
|
+
return key && !nonUsSecListingVenue(key, exchange) ? key : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** The note that an offering filed after `periodEnd` is not in the cash yet, for a report. A failed read leaves it out. */
|
|
30
|
+
export async function loadOfferingNote(
|
|
31
|
+
client: Parameters<typeof fetchOfferingFilings>[0],
|
|
32
|
+
listing: { symbol: string; exchange?: string },
|
|
33
|
+
periodEnd: string | null,
|
|
34
|
+
signal?: AbortSignal,
|
|
35
|
+
): Promise<string | null> {
|
|
36
|
+
const key = offeringSymbol(listing.symbol, listing.exchange);
|
|
37
|
+
if (!key || !periodEnd) return null;
|
|
38
|
+
const { payload } = await loadCloudResource(offeringFilingsCache, key, () => fetchOfferingFilings(client, key, signal), { signal });
|
|
39
|
+
return offeringNote(offeringsAfter(payload, periodEnd), periodEnd);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The same note for a pane: read only while `enabled` (the views that show
|
|
44
|
+
* cash), from the cached list first. Nothing while it loads or when the read
|
|
45
|
+
* fails, as the note is context, not the data.
|
|
46
|
+
*/
|
|
47
|
+
export function useOfferingNote(symbol: string | null | undefined, exchange: string | undefined, periodEnd: string | null, enabled: boolean): string | null {
|
|
48
|
+
const key = enabled && periodEnd ? offeringSymbol(symbol, exchange) : null;
|
|
49
|
+
const loader = useCallback(async (force: boolean) => (
|
|
50
|
+
await loadCloudResource(offeringFilingsCache, key!, () => fetchOfferingFilings(apiClient, key!), { force })
|
|
51
|
+
).payload, [key]);
|
|
52
|
+
const cached = useMemo(() => key ? cachedCloudResource(offeringFilingsCache, key)?.payload ?? null : null, [key]);
|
|
53
|
+
const { data } = useAsyncResource(key ? loader : null, { initialData: () => cached });
|
|
54
|
+
const filings = data ?? cached;
|
|
55
|
+
return key && periodEnd && filings ? offeringNote(offeringsAfter(filings, periodEnd), periodEnd) : null;
|
|
56
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createValuationCurrencyContext } from "../../../../time-series/valuation-currency";
|
|
2
|
-
import type { FinancialStatement, PricePoint, TickerFinancials } from "../../../../types/financials";
|
|
2
|
+
import type { CompanyProfile, FinancialStatement, PricePoint, TickerFinancials } from "../../../../types/financials";
|
|
3
3
|
import { formatNumber, pickUnit } from "../../../../utils/format";
|
|
4
4
|
import { pricePointIntegrity } from "../../../../utils/price-history-integrity";
|
|
5
5
|
import { formatPerShareNumber } from "../../../../utils/reported-money";
|
|
6
6
|
import { hasStatementGap } from "../../../../utils/statement-gaps";
|
|
7
|
+
import { cashAndShortTermInvestments, excludesCashRunway, formatRunwayMonths, SHORT_RUNWAY_HISTORY, monthlyOperatingBurn, QUARTER_MONTHS, reportsShortTermTotal, runwayMonths, YEAR_MONTHS } from "../../../../utils/cash-runway";
|
|
7
8
|
import {
|
|
8
9
|
buildPreviousStatementMap,
|
|
9
10
|
trailingFourQuarters,
|
|
@@ -21,21 +22,23 @@ import {
|
|
|
21
22
|
* Why a ratio or one of its inputs has no number: a line the statements do
|
|
22
23
|
* not carry for the period, a ratio whose denominator makes it meaningless
|
|
23
24
|
* (a loss under P/E, negative equity under ROE), no close at the period end,
|
|
24
|
-
* a close still loading,
|
|
25
|
-
* for a trailing flow
|
|
25
|
+
* a close still loading, a quarter with fewer than four quarters to sum
|
|
26
|
+
* for a trailing flow, or operations that brought cash in, where a runway
|
|
27
|
+
* has no burn to divide by.
|
|
26
28
|
*/
|
|
27
|
-
export type RatioGap = "not-reported" | "short-history" | "not-meaningful" | "no-price" | "loading";
|
|
29
|
+
export type RatioGap = "not-reported" | "short-history" | "no-burn" | "not-meaningful" | "no-price" | "loading";
|
|
28
30
|
export type RatioAmount = number | RatioGap;
|
|
29
31
|
|
|
30
32
|
export const RATIO_GAP_TEXT: Record<RatioGap, string> = {
|
|
31
33
|
"not-reported": "not reported",
|
|
32
|
-
"short-history":
|
|
34
|
+
"short-history": SHORT_RUNWAY_HISTORY,
|
|
35
|
+
"no-burn": "no burn",
|
|
33
36
|
"not-meaningful": "N/M",
|
|
34
37
|
"no-price": "no price",
|
|
35
38
|
loading: "--",
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
export type RatioFormat = "percent" | "multiple" | "days";
|
|
41
|
+
export type RatioFormat = "percent" | "multiple" | "days" | "months";
|
|
39
42
|
export type RatioInputFormat = "money" | "perShare" | "days";
|
|
40
43
|
|
|
41
44
|
/** One column of a ratio tab: a period's statement and what its ratios also need. */
|
|
@@ -53,6 +56,8 @@ export interface RatioPeriod {
|
|
|
53
56
|
trailing?: FinancialTableStatement | null;
|
|
54
57
|
/** The close at the period end in the statement's currency. */
|
|
55
58
|
price: RatioAmount;
|
|
59
|
+
/** The filer reports cash and short-term investments as a total in some period on file (utils/cash-runway). */
|
|
60
|
+
shortTermTotalOnFile?: boolean;
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
interface RatioInputDef {
|
|
@@ -79,6 +84,8 @@ export interface RatioDef {
|
|
|
79
84
|
format: RatioFormat;
|
|
80
85
|
/** The sign carries meaning (a loss, a negative return), so the value takes the sign colour. */
|
|
81
86
|
signed?: boolean;
|
|
87
|
+
/** Read over one quarter, so the annual view, whose columns are years, leaves it out. */
|
|
88
|
+
quarterlyOnly?: boolean;
|
|
82
89
|
inputs: RatioInputDef[];
|
|
83
90
|
/** From the inputs after annualization. */
|
|
84
91
|
compute: (values: number[], period: RatioPeriod) => RatioAmount;
|
|
@@ -277,6 +284,26 @@ const DPO: RatioDef = {
|
|
|
277
284
|
compute: ([balance, daily]) => over(balance!, daily!),
|
|
278
285
|
};
|
|
279
286
|
|
|
287
|
+
/** Cash used by operations per month: a quarter's operating cash flow over 3 months, a year's over 12. */
|
|
288
|
+
const monthlyBurn = (months: number) => ({ statement }: RatioPeriod): RatioAmount => (
|
|
289
|
+
monthlyOperatingBurn(finite(statement.operatingCashFlow), months) ?? "not-reported"
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
/** Cash alone for a filer that reports no total with short-term investments, never for one missing it in a period. */
|
|
293
|
+
const runwayCash = ({ statement, shortTermTotalOnFile }: RatioPeriod): RatioAmount => (
|
|
294
|
+
cashAndShortTermInvestments(statement, shortTermTotalOnFile)?.amount ?? "not-reported"
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
/** Months of cash and short-term investments at a monthly operating burn (utils/cash-runway, as `ticker` reads it). */
|
|
298
|
+
const runway = (id: string, label: string, burn: RatioInputDef, quarterlyOnly = false): RatioDef => ({
|
|
299
|
+
id,
|
|
300
|
+
label,
|
|
301
|
+
format: "months",
|
|
302
|
+
...(quarterlyOnly ? { quarterlyOnly } : {}),
|
|
303
|
+
inputs: [{ label: "Cash + ST Inv", format: "money", value: runwayCash }, burn],
|
|
304
|
+
compute: ([cash, perMonth]) => runwayMonths(cash!, perMonth!),
|
|
305
|
+
});
|
|
306
|
+
|
|
280
307
|
const dayCount = (label: string, def: RatioDef, operator?: RatioInputDef["operator"]): RatioInputDef => ({
|
|
281
308
|
label, operator, format: "days", value: (period) => evaluateRatio(def, period).value,
|
|
282
309
|
});
|
|
@@ -440,6 +467,11 @@ export const RATIO_TABS: RatioTabDef[] = [
|
|
|
440
467
|
],
|
|
441
468
|
compute: ([cash, liabilities]) => over(cash!, liabilities!),
|
|
442
469
|
},
|
|
470
|
+
// Both burns, as a quarter swings for a company paid in lumps; the trailing one reads the year in annual columns.
|
|
471
|
+
runway("runway-quarter", "Runway, Qtr Burn (mo)",
|
|
472
|
+
{ label: "Op Burn/Mo", operator: "÷", format: "money", value: monthlyBurn(QUARTER_MONTHS) }, true),
|
|
473
|
+
runway("runway-ttm", "Runway, TTM Burn (mo)",
|
|
474
|
+
{ label: "Op Burn/Mo", operator: "÷", format: "money", trailing: true, value: monthlyBurn(YEAR_MONTHS) }),
|
|
443
475
|
],
|
|
444
476
|
},
|
|
445
477
|
{
|
|
@@ -527,7 +559,7 @@ export const RATIO_TAB_KEYS = new Set(RATIO_TABS.map((tab) => tab.key));
|
|
|
527
559
|
* report explains more than a missing close, and a close still loading may
|
|
528
560
|
* yet arrive.
|
|
529
561
|
*/
|
|
530
|
-
const GAP_ORDER: RatioGap[] = ["not-reported", "short-history", "not-meaningful", "no-price", "loading"];
|
|
562
|
+
const GAP_ORDER: RatioGap[] = ["not-reported", "short-history", "no-burn", "not-meaningful", "no-price", "loading"];
|
|
531
563
|
|
|
532
564
|
function inputAmount(input: RatioInputDef, period: RatioPeriod): RatioAmount {
|
|
533
565
|
if (!input.trailing || !period.quarterly) return input.value(period);
|
|
@@ -556,6 +588,7 @@ function ratioInputLabel(input: RatioInputDef, quarterly: boolean): string {
|
|
|
556
588
|
export function formatRatioValue(format: RatioFormat, amount: RatioAmount): string {
|
|
557
589
|
if (isGap(amount)) return RATIO_GAP_TEXT[amount];
|
|
558
590
|
if (format === "percent") return `${formatNumber(amount * 100, 1)}%`;
|
|
591
|
+
if (format === "months") return formatRunwayMonths(amount, "");
|
|
559
592
|
if (format === "days") return formatNumber(amount, 1);
|
|
560
593
|
return `${formatNumber(amount, Math.abs(amount) < 10 ? 2 : 1)}x`;
|
|
561
594
|
}
|
|
@@ -657,7 +690,7 @@ function trailingYear(
|
|
|
657
690
|
Math.abs(Date.parse(candidate.date) - end) <= SAME_PERIOD_END_DAYS * 86_400_000
|
|
658
691
|
&& (!candidate.currency || !statement.currency || candidate.currency === statement.currency)
|
|
659
692
|
));
|
|
660
|
-
return year ?? trailingFourQuarters(quarterlyStatements, statement.date);
|
|
693
|
+
return year ?? trailingFourQuarters(quarterlyStatements, statement.date, annualStatements);
|
|
661
694
|
}
|
|
662
695
|
|
|
663
696
|
export function ratioPeriods(
|
|
@@ -668,6 +701,7 @@ export function ratioPeriods(
|
|
|
668
701
|
/** Every statement on file, not only the columns shown, for quarterly columns' trailing years. */
|
|
669
702
|
onFile: { annual: readonly FinancialStatement[]; quarterly: readonly FinancialStatement[] } = { annual: [], quarterly: [] },
|
|
670
703
|
): RatioPeriod[] {
|
|
704
|
+
const shortTermTotalOnFile = reportsShortTermTotal([...onFile.annual, ...onFile.quarterly, ...statements]);
|
|
671
705
|
return statements.map((statement) => {
|
|
672
706
|
const quarterly = period === "quarterly" && statement.date !== "TTM";
|
|
673
707
|
return {
|
|
@@ -676,6 +710,7 @@ export function ratioPeriods(
|
|
|
676
710
|
quarterly,
|
|
677
711
|
...(quarterly ? { trailing: trailingYear(statement, onFile.annual, onFile.quarterly) } : {}),
|
|
678
712
|
price: price(statement),
|
|
713
|
+
shortTermTotalOnFile,
|
|
679
714
|
};
|
|
680
715
|
});
|
|
681
716
|
}
|
|
@@ -700,6 +735,8 @@ export type RatioTableRow =
|
|
|
700
735
|
|
|
701
736
|
export interface RatioTableModel {
|
|
702
737
|
tab: RatioTabDef;
|
|
738
|
+
/** The tab's ratios the period shows: a quarterly-only one is left out of years. */
|
|
739
|
+
ratios: RatioDef[];
|
|
703
740
|
periods: RatioPeriod[];
|
|
704
741
|
/** Each ratio's cell per period, by ratio id. */
|
|
705
742
|
cells: Map<string, RatioCell[]>;
|
|
@@ -708,14 +745,26 @@ export interface RatioTableModel {
|
|
|
708
745
|
|
|
709
746
|
const UNIT_WORDS: Record<string, string> = { K: "k", M: "mn", B: "bn", T: "tn" };
|
|
710
747
|
|
|
748
|
+
/** The ratios a tab shows for quarterly or annual columns. */
|
|
749
|
+
export function visibleRatios(tab: RatioTabDef, quarterly: boolean): RatioDef[] {
|
|
750
|
+
return quarterly ? tab.ratios : tab.ratios.filter((def) => !def.quarterlyOnly);
|
|
751
|
+
}
|
|
752
|
+
|
|
711
753
|
export function buildRatioTableModel(
|
|
712
754
|
tab: RatioTabDef,
|
|
713
755
|
periods: RatioPeriod[],
|
|
714
756
|
expandedRatioIds: ReadonlySet<string> | "all",
|
|
757
|
+
profile?: CompanyProfile,
|
|
715
758
|
): RatioTableModel {
|
|
716
759
|
const quarterly = periods.some((period) => period.quarterly);
|
|
717
|
-
const
|
|
718
|
-
const
|
|
760
|
+
const totalOnFile = periods.some((period) => period.shortTermTotalOnFile);
|
|
761
|
+
const ratios = visibleRatios(tab, quarterly)
|
|
762
|
+
.filter((def) => def.format !== "months" || !excludesCashRunway(profile))
|
|
763
|
+
.map((def) => def.format === "months" && !totalOnFile
|
|
764
|
+
? { ...def, inputs: def.inputs.map((input, index) => index === 0 ? { ...input, label: "Cash" } : input) }
|
|
765
|
+
: def);
|
|
766
|
+
const cells = new Map(ratios.map((def) => [def.id, periods.map((period) => evaluateRatio(def, period))]));
|
|
767
|
+
const inputs = ratios.flatMap((def) => def.inputs.map((input, index) => {
|
|
719
768
|
const values = cells.get(def.id)!.map((cell) => cell.inputs[index]).filter((value) => typeof value === "number");
|
|
720
769
|
const { suffix, divisor } = input.format === "money" ? pickUnit(values) : { suffix: "", divisor: 1 };
|
|
721
770
|
const unit = UNIT_WORDS[suffix] ?? suffix;
|
|
@@ -733,12 +782,12 @@ export function buildRatioTableModel(
|
|
|
733
782
|
// Each money input names its unit: a ratio tab has few of them, and a unit
|
|
734
783
|
// stated once in the query bar is the first thing a narrow pane cuts.
|
|
735
784
|
const rows: RatioTableRow[] = [];
|
|
736
|
-
for (const def of
|
|
785
|
+
for (const def of ratios) {
|
|
737
786
|
const expanded = expandedRatioIds === "all" || expandedRatioIds.has(def.id);
|
|
738
787
|
rows.push({ kind: "ratio", id: def.id, def, label: def.label, expanded });
|
|
739
788
|
if (expanded) rows.push(...inputs.filter((row) => row.def === def));
|
|
740
789
|
}
|
|
741
|
-
return { tab, periods, cells, rows };
|
|
790
|
+
return { tab, ratios, periods, cells, rows };
|
|
742
791
|
}
|
|
743
792
|
|
|
744
793
|
export const findRatioTab = (key: string) => RATIO_TABS.find((tab) => tab.key === key);
|
|
@@ -777,5 +826,5 @@ export function ratioTableForFinancials(
|
|
|
777
826
|
const close = history ? periodEndClose(history, ratioPeriodEnd(statement)) : undefined;
|
|
778
827
|
return (close === undefined ? null : currencies.priceInStatementUnits(statement, close)) ?? "no-price";
|
|
779
828
|
};
|
|
780
|
-
return buildRatioTableModel(tab, ratioPeriods(statements, ratioOpenings(period, annual, quarterly), period, price, { annual, quarterly }), "all");
|
|
829
|
+
return buildRatioTableModel(tab, ratioPeriods(statements, ratioOpenings(period, annual, quarterly), period, price, { annual, quarterly }), "all", financials.profile);
|
|
781
830
|
}
|