gloomberb 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +32 -1
- package/src/account/auth-model.ts +7 -3
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +11 -6
- package/src/api-client/catalysts.ts +2 -1
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +98 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +182 -16
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +18 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +224 -26
- package/src/api-client/research-activity.ts +3 -10
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +96 -2
- package/src/app/keybindings/index.ts +3 -0
- package/src/app/keybindings/labels.ts +18 -1
- package/src/app/keybindings/resolve.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/broker-import.ts +43 -26
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +9 -2
- package/src/cli/commands/keybindings.ts +25 -2
- package/src/cli/commands/market.ts +1177 -278
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-chain.ts +59 -3
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +222 -61
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +82 -46
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +194 -48
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +21 -3
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +38 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +113 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +226 -50
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +123 -27
- package/src/cli/listing-arg.ts +316 -46
- package/src/cli/name-entries.ts +30 -18
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +193 -30
- package/src/cli/pane-functions/function-help.ts +76 -30
- package/src/cli/pane-functions/headless.ts +59 -12
- package/src/cli/pane-functions/index.ts +28 -19
- package/src/cli/pane-functions/market-session.ts +15 -5
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +10 -6
- package/src/cli/pane-functions/resolver.ts +64 -11
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +45 -4
- package/src/cli/report-tables.ts +75 -19
- package/src/cli/restore-plugins.ts +42 -15
- package/src/cli/result.ts +164 -23
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +198 -68
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +395 -20
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +7 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +314 -13
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +20 -4
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +17 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/panel/prompt-binding.ts +0 -8
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/alert.ts +1 -1
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +12 -6
- package/src/components/layout/header.tsx +33 -46
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +38 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-frame.tsx +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +10 -2
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +6 -4
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +123 -0
- package/src/docs/snapshot.json +422 -112
- package/src/i18n/es.ts +30 -13
- package/src/i18n/ja.ts +30 -13
- package/src/i18n/ko.ts +30 -13
- package/src/i18n/zh-cn.ts +30 -13
- package/src/i18n/zh-tw.ts +30 -13
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/coordinator/financials.ts +10 -2
- package/src/market-data/coordinator/index.ts +3 -1
- package/src/market-data/coordinator/quotes.ts +4 -2
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +81 -11
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/status.ts +16 -4
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/options-alternatives.ts +60 -0
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +25 -3
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +7 -2
- package/src/market-data/selectors.ts +3 -0
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/notifications/notification-log.ts +6 -4
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +34 -20
- package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
- package/src/plugins/builtin/alerts/cli.ts +533 -85
- package/src/plugins/builtin/alerts/command.ts +12 -10
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +119 -0
- package/src/plugins/builtin/alerts/format.ts +10 -3
- package/src/plugins/builtin/alerts/headless.ts +107 -41
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +92 -0
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +107 -30
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +61 -0
- package/src/plugins/builtin/alerts/metric-data.ts +70 -0
- package/src/plugins/builtin/alerts/metric-model.ts +175 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +130 -49
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +76 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +38 -12
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/alerts/types.ts +3 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +6 -3
- package/src/plugins/builtin/backtest/headless.ts +13 -8
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +24 -14
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +18 -3
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +66 -24
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +19 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +111 -24
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +51 -5
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +4 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
- package/src/plugins/builtin/chart-composer/headless.ts +266 -37
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +144 -30
- package/src/plugins/builtin/chart-composer/presets.ts +50 -15
- package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +31 -28
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +44 -31
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/command-suggestions.ts +92 -0
- package/src/plugins/builtin/chat/content/composer.tsx +13 -6
- package/src/plugins/builtin/chat/content/footer.tsx +6 -3
- package/src/plugins/builtin/chat/content/index.tsx +51 -22
- package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
- package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
- package/src/plugins/builtin/chat/index.tsx +23 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
- package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
- package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/plugin.tsx +1 -1
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +79 -23
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +5 -3
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +3 -2
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +18 -11
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +144 -27
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/figures.ts +72 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +144 -27
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +34 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +87 -28
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +104 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/charts.tsx +2 -2
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +20 -1
- package/src/plugins/builtin/exposure/pane.tsx +10 -5
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +12 -10
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +3 -3
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +20 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
- package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
- package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/headless.ts +7 -4
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +10 -4
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +51 -13
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +29 -8
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/breadth-pane.tsx +81 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +24 -10
- package/src/plugins/builtin/members/index.tsx +9 -9
- package/src/plugins/builtin/members/model.ts +23 -4
- package/src/plugins/builtin/members/pane.tsx +31 -14
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/analytics.ts +26 -2
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +5 -2
- package/src/plugins/builtin/options/strike-window.ts +2 -1
- package/src/plugins/builtin/options/table.ts +1 -7
- package/src/plugins/builtin/options/view.tsx +30 -13
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-positioning/client.ts +19 -0
- package/src/plugins/builtin/options-positioning/headless.ts +54 -14
- package/src/plugins/builtin/options-positioning/index.tsx +3 -3
- package/src/plugins/builtin/options-positioning/model.ts +47 -8
- package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +36 -15
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +14 -9
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +168 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +49 -26
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +7 -4
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +4 -1
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +80 -13
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/index.ts +24 -1
- package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
- package/src/plugins/builtin/scanner/live-feed.ts +168 -0
- package/src/plugins/builtin/scanner/live-headless.ts +114 -0
- package/src/plugins/builtin/scanner/live-model.ts +351 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
- package/src/plugins/builtin/scanner/live-track.ts +186 -0
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/macro-releases.ts +65 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +21 -0
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
- package/src/plugins/builtin/shared/volatility/pricing.ts +7 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +11 -6
- package/src/plugins/builtin/themes/model.ts +15 -5
- package/src/plugins/builtin/themes/pane.tsx +27 -8
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +14 -4
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +7 -4
- package/src/plugins/builtin/vol-surface/headless.ts +71 -13
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +26 -9
- package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/volatility/pane.tsx +2 -2
- package/src/plugins/builtin/volatility/series.ts +26 -0
- package/src/plugins/builtin/world-indices/footer.ts +1 -1
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +15 -9
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +15 -13
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +15 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +5 -55
- package/src/renderers/browser/main.tsx +30 -60
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/styles.css +76 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +36 -2
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/app-name.ts +17 -0
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +1 -1
- package/src/renderers/opentui/toast-host.tsx +71 -43
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +16 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/batches.ts +10 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +58 -15
- package/src/sources/provider-router/index.ts +146 -10
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +67 -17
- package/src/sync/core-contributors.ts +46 -14
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +11 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/company-name.ts +59 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-venues.ts +23 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +111 -33
- package/src/tickers/search/ranking.ts +64 -5
- package/src/tickers/search/types.ts +5 -0
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +315 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/field-catalog.ts +1 -3
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +173 -10
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/hooks.ts +1 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/price-units.ts +72 -2
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +161 -0
- package/src/time-series/resolve.ts +185 -1587
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +242 -0
- package/src/time-series/spec.ts +13 -7
- package/src/time-series/studies.ts +377 -82
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/transforms.ts +1 -0
- package/src/time-series/types.ts +34 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +23 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +145 -8
- package/src/types/headless.ts +117 -9
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +66 -9
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +180 -0
- package/src/updater/index.ts +10 -5
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +89 -5
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +86 -0
- package/src/utils/option-expiry.ts +186 -7
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +23 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
- package/src/renderers/browser/first-screen.ts +0 -193
package/src/cli/result.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CliGlobalOptions } from "./options";
|
|
2
2
|
import {
|
|
3
|
+
cliPlainEnabled,
|
|
3
4
|
cliStyles,
|
|
4
5
|
cliTerminalWidth,
|
|
5
6
|
renderStats,
|
|
@@ -13,11 +14,14 @@ import {
|
|
|
13
14
|
} from "../utils/cli-output";
|
|
14
15
|
import { serializeCsv } from "../utils/csv";
|
|
15
16
|
import { formatUtcTime, isEpochMilliseconds, isZonedIsoDateTime } from "../utils/utc-time";
|
|
16
|
-
import { formatFreshnessLine, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
|
+
import { formatFreshnessLine, withSavedCopy, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
18
|
import { withSearchHints, type FredSeriesCheck } from "./not-a-ticker";
|
|
18
19
|
import { renderReportCsv, renderReportNdjson, withCsvFooter, type CliReportTables } from "./report-tables";
|
|
19
20
|
import {
|
|
21
|
+
EXPORT_DATING_COLUMNS,
|
|
20
22
|
EXPORT_IDENTITY_COLUMNS,
|
|
23
|
+
exportDatingCells,
|
|
24
|
+
exportDatingFields,
|
|
21
25
|
exportIdentityCells,
|
|
22
26
|
exportIdentityFields,
|
|
23
27
|
exportSource,
|
|
@@ -98,6 +102,11 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
98
102
|
* `metadata.rows` in JSON.
|
|
99
103
|
*/
|
|
100
104
|
dateKey?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The row key that splits the rows into series of their own, each windowed
|
|
107
|
+
* apart: with `symbol`, `--tail 5` keeps every symbol's newest five rows.
|
|
108
|
+
*/
|
|
109
|
+
seriesKey?: string;
|
|
101
110
|
/** How many rows to show when neither `--limit` nor `--tail` is given; every row when absent. */
|
|
102
111
|
defaultLimit?: number;
|
|
103
112
|
/**
|
|
@@ -114,6 +123,24 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
114
123
|
exportIdentity?: ExportIdentity | ((row: Row) => ExportIdentity);
|
|
115
124
|
/** What CSV says after the source lines as `# note:` lines: what the rows do not show, such as where a series begins. */
|
|
116
125
|
exportNotes?: readonly string[];
|
|
126
|
+
/**
|
|
127
|
+
* The rows are statistics dated by a period and a release (`econ`, `fred`):
|
|
128
|
+
* CSV and NDJSON rows also end with `period`, `released` and `retrieved`
|
|
129
|
+
* (`EXPORT_DATING_COLUMNS`) after the five fixed columns, from the `period`
|
|
130
|
+
* and `released` of each row's `exportIdentity`, and `as_of` is the release.
|
|
131
|
+
* A column the rows already have by name keeps its own values. Needs a
|
|
132
|
+
* cited source, as the fixed columns do.
|
|
133
|
+
*/
|
|
134
|
+
exportDated?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Why a row's figures are empty (`Not a ticker: ZZZZQQ.`, `Chg%: no previous
|
|
137
|
+
* close`), for the `status` column CSV writes after the row's own columns and
|
|
138
|
+
* the `status` field of an NDJSON row; empty for a whole row. The column is
|
|
139
|
+
* there whenever this is, with rows or without, so the header never depends
|
|
140
|
+
* on what loaded. A figure that is no number (NaN) is written empty and,
|
|
141
|
+
* without a reason here, named as `<header>: not available`.
|
|
142
|
+
*/
|
|
143
|
+
exportStatus?: (row: Row) => string | null | undefined;
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
interface CliResultJsonEnvelope<T> extends Omit<CliResult<T>, "freshness" | "exportFreshness" | "failure"> {
|
|
@@ -149,11 +176,28 @@ function rowWindowOptions(options: CliGlobalOptions, renderOptions: Pick<CliResu
|
|
|
149
176
|
function windowed<Row>(
|
|
150
177
|
rows: readonly Row[],
|
|
151
178
|
options: CliGlobalOptions,
|
|
152
|
-
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit">,
|
|
179
|
+
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit" | "seriesKey">,
|
|
153
180
|
): RowWindow<Row> {
|
|
154
|
-
const { dateKey } = renderOptions;
|
|
181
|
+
const { dateKey, seriesKey } = renderOptions;
|
|
155
182
|
const dateOf = dateKey ? (row: Row) => (isPlainObject(row) ? row[dateKey] : undefined) : undefined;
|
|
156
|
-
|
|
183
|
+
const windowOptions = rowWindowOptions(options, renderOptions);
|
|
184
|
+
if (!seriesKey) return windowRows(rows, windowOptions, dateOf);
|
|
185
|
+
const series = new Map<unknown, Row[]>();
|
|
186
|
+
for (const row of rows) {
|
|
187
|
+
const key = isPlainObject(row) ? row[seriesKey] : undefined;
|
|
188
|
+
const group = series.get(key);
|
|
189
|
+
if (group) group.push(row);
|
|
190
|
+
else series.set(key, [row]);
|
|
191
|
+
}
|
|
192
|
+
const windows = [...series.values()].map((group) => windowRows(group, windowOptions, dateOf));
|
|
193
|
+
const count = windowOptions.tail ?? windowOptions.limit;
|
|
194
|
+
return {
|
|
195
|
+
rows: windows.flatMap((window) => window.rows),
|
|
196
|
+
total: rows.length,
|
|
197
|
+
kept: windows.find((window) => window.kept)?.kept ?? null,
|
|
198
|
+
note: windows.some((window) => window.note)
|
|
199
|
+
? `showing the oldest ${count} ${count === 1 ? "row" : "rows"} of each ${seriesKey}; --tail ${count} for the latest` : null,
|
|
200
|
+
};
|
|
157
201
|
}
|
|
158
202
|
|
|
159
203
|
function asRows<T, Row>(data: T, rows?: (data: T) => Row[]): Row[] {
|
|
@@ -206,7 +250,7 @@ function formatTextValue(
|
|
|
206
250
|
depth = 0,
|
|
207
251
|
width: number | null = null,
|
|
208
252
|
): string {
|
|
209
|
-
const missing = context === "record" ? cliStyles.muted("-") : "";
|
|
253
|
+
const missing = context === "record" ? cliPlainEnabled() ? "—" : cliStyles.muted("-") : "";
|
|
210
254
|
if (value == null || value === "") return missing;
|
|
211
255
|
// Times print in UTC with the zone named, never in the host's zone; JSON and CSV keep the raw value.
|
|
212
256
|
if (value instanceof Date) return formatUtcTime(value);
|
|
@@ -291,23 +335,80 @@ function serializeColumns<Row>(columns?: CliResultColumn<Row>[]) {
|
|
|
291
335
|
}));
|
|
292
336
|
}
|
|
293
337
|
|
|
338
|
+
/** A number a spreadsheet cannot read: NaN or an infinity, which exports write empty, never as the word. */
|
|
339
|
+
function isNonFiniteNumber(value: unknown): boolean {
|
|
340
|
+
return typeof value === "number" && !Number.isFinite(value);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* What a row's status cell says: the command's reason, else the figures
|
|
345
|
+
* written empty for being no number. Empty when nothing is missing.
|
|
346
|
+
*/
|
|
347
|
+
function exportStatusText(reason: string | null | undefined, blanked: readonly string[]): string {
|
|
348
|
+
const own = reason?.trim();
|
|
349
|
+
if (own) return own;
|
|
350
|
+
return blanked.length > 0 ? `${blanked.join(", ")}: not available` : "";
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** `status`, or `value_status` beside a column of the table's own named Status. */
|
|
354
|
+
function statusHeader(headers: readonly string[]): string {
|
|
355
|
+
return headers.some((header) => header.trim().toLowerCase() === "status") ? "value_status" : "status";
|
|
356
|
+
}
|
|
357
|
+
|
|
294
358
|
function renderCsv<Row extends Record<string, unknown>>(
|
|
295
359
|
rows: Row[],
|
|
296
360
|
columns?: CliResultColumn<Row>[],
|
|
297
361
|
identity?: (row: Row) => string[],
|
|
362
|
+
status?: (row: Row) => string | null | undefined,
|
|
363
|
+
dating?: (row: Row) => string[],
|
|
298
364
|
): string {
|
|
299
365
|
const resolvedColumns = columns && columns.length > 0
|
|
300
366
|
? columns
|
|
301
367
|
: inferColumns(rows as Record<string, unknown>[]) as CliResultColumn<Row>[];
|
|
368
|
+
const headers = resolvedColumns.map((column) => column.header);
|
|
369
|
+
// A dated export's own `released` column keeps its values; the others close the row.
|
|
370
|
+
const datingAdded = dating
|
|
371
|
+
? EXPORT_DATING_COLUMNS.flatMap((column, index) => headers.includes(column) ? [] : [index]) : [];
|
|
302
372
|
return serializeCsv([
|
|
303
|
-
[
|
|
304
|
-
|
|
305
|
-
...
|
|
306
|
-
...identity
|
|
307
|
-
|
|
373
|
+
[
|
|
374
|
+
...headers,
|
|
375
|
+
...status ? [statusHeader(headers)] : [],
|
|
376
|
+
...identity ? EXPORT_IDENTITY_COLUMNS : [],
|
|
377
|
+
...datingAdded.map((index) => EXPORT_DATING_COLUMNS[index]!),
|
|
378
|
+
],
|
|
379
|
+
...rows.map((row) => {
|
|
380
|
+
const values = resolvedColumns.map((column) => (column.value ? column.value(row) : row[column.key]));
|
|
381
|
+
const blanked = resolvedColumns.flatMap((column, index) => isNonFiniteNumber(values[index]) ? [column.header] : []);
|
|
382
|
+
const datingCells = dating?.(row) ?? [];
|
|
383
|
+
return [
|
|
384
|
+
...values.map((value) => isNonFiniteNumber(value) ? "" : value),
|
|
385
|
+
...status ? [exportStatusText(status(row), blanked)] : [],
|
|
386
|
+
...identity?.(row) ?? [],
|
|
387
|
+
...datingAdded.map((index) => datingCells[index] ?? ""),
|
|
388
|
+
];
|
|
389
|
+
}),
|
|
308
390
|
]);
|
|
309
391
|
}
|
|
310
392
|
|
|
393
|
+
/**
|
|
394
|
+
* The key an NDJSON row says why its figures are empty under: `status`, or
|
|
395
|
+
* `value_status` beside a field of the row's own that the export writes under
|
|
396
|
+
* that name (an order's status), as CSV's header does.
|
|
397
|
+
*/
|
|
398
|
+
function ndjsonStatusKey(rows: readonly unknown[], columns?: readonly CliResultColumn<never>[]): string {
|
|
399
|
+
const own = columns && columns.length > 0
|
|
400
|
+
? columns.some((column) => column.key === "status")
|
|
401
|
+
: rows.some((row) => isPlainObject(row) && "status" in row);
|
|
402
|
+
return own ? "value_status" : "status";
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** An NDJSON row: a figure that is no number is null, and the row says why its figures are empty when the command does. */
|
|
406
|
+
function ndjsonRow<Row extends Record<string, unknown>>(row: Row, status: ((row: Row) => string | null | undefined) | undefined, statusKey: string): Record<string, unknown> {
|
|
407
|
+
const blanked = Object.entries(row).flatMap(([key, value]) => isNonFiniteNumber(value) ? [key] : []);
|
|
408
|
+
const own = blanked.length > 0 ? { ...row, ...Object.fromEntries(blanked.map((key) => [key, null])) } : row;
|
|
409
|
+
return status ? { ...own, [statusKey]: exportStatusText(status(row), blanked) || null } : own;
|
|
410
|
+
}
|
|
411
|
+
|
|
311
412
|
function stringField(row: Record<string, unknown>, key: string): string | null {
|
|
312
413
|
const value = row?.[key];
|
|
313
414
|
return typeof value === "string" && value.trim() ? value : null;
|
|
@@ -348,10 +449,11 @@ function renderTextTable<Row extends Record<string, unknown>>(
|
|
|
348
449
|
): string {
|
|
349
450
|
const resolvedColumns = textColumns(rows, columns);
|
|
350
451
|
const cells = rows.map((row) => resolvedColumns.map((column) => formatTextCell(column, row, "table")));
|
|
351
|
-
// A column no row fills is noise in a table; exports keep it
|
|
452
|
+
// A column no row fills is noise in a table; exports keep it, and so does plain output, whose
|
|
453
|
+
// tables keep one shape from query to query with "—" in the empty cells.
|
|
352
454
|
const filled = resolvedColumns
|
|
353
455
|
.map((column, index) => ({ column, index }))
|
|
354
|
-
.filter(({ column, index }) => column.width != null || cells.some((row) => row[index] !== ""));
|
|
456
|
+
.filter(({ column, index }) => cliPlainEnabled() || column.width != null || cells.some((row) => row[index] !== ""));
|
|
355
457
|
const shown = filled.length > 0 ? filled : resolvedColumns.map((column, index) => ({ column, index }));
|
|
356
458
|
return renderTable(
|
|
357
459
|
shown.map(({ column }) => ({
|
|
@@ -395,9 +497,13 @@ function overflowsTerminal<Row extends Record<string, unknown>>(rows: Row[]): bo
|
|
|
395
497
|
return width > terminalWidth;
|
|
396
498
|
}
|
|
397
499
|
|
|
398
|
-
/**
|
|
399
|
-
|
|
400
|
-
|
|
500
|
+
/**
|
|
501
|
+
* The closing source, as-of and status line of a text result, for output
|
|
502
|
+
* printed without `printResult`; `shown` is the data the line is drawn from,
|
|
503
|
+
* which says whether it came from a saved copy.
|
|
504
|
+
*/
|
|
505
|
+
export function cliFreshnessFooter(freshness: ReportFreshness, shown?: unknown): string {
|
|
506
|
+
return cliStyles.muted(wrapToTerminal(formatFreshnessLine(withSavedCopy(freshness, shown))));
|
|
401
507
|
}
|
|
402
508
|
|
|
403
509
|
export function serializeCliResult<T, Row extends Record<string, unknown> = Record<string, unknown>>(
|
|
@@ -405,8 +511,10 @@ export function serializeCliResult<T, Row extends Record<string, unknown> = Reco
|
|
|
405
511
|
options: CliGlobalOptions,
|
|
406
512
|
renderOptions: CliResultRenderOptions<T, Row> = {},
|
|
407
513
|
): string {
|
|
408
|
-
const { freshness, exportFreshness, failure, ...rest } = result;
|
|
409
|
-
|
|
514
|
+
const { freshness: reported, exportFreshness, failure, ...rest } = result;
|
|
515
|
+
// Rows shown from a saved copy, its refresh having failed, say so in place of live or delayed.
|
|
516
|
+
const freshness = reported && withSavedCopy(reported, result.data);
|
|
517
|
+
const cited = freshness ?? (exportFreshness && withSavedCopy(exportFreshness, result.data));
|
|
410
518
|
if (options.format === "json") {
|
|
411
519
|
const columns = serializeColumns(renderOptions.columns);
|
|
412
520
|
const window = Array.isArray(result.data) ? windowed(result.data as unknown[], options, renderOptions) : null;
|
|
@@ -443,15 +551,32 @@ function serializeCliRows<T, Row extends Record<string, unknown>>(
|
|
|
443
551
|
}
|
|
444
552
|
const window = windowed(asRows(result.data, renderOptions.rows), options, renderOptions);
|
|
445
553
|
const rows = window.rows;
|
|
554
|
+
const status = renderOptions.exportStatus;
|
|
446
555
|
if (options.format === "ndjson") {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
556
|
+
const statusKey = ndjsonStatusKey(rows, renderOptions.columns as readonly CliResultColumn<never>[] | undefined);
|
|
557
|
+
return rows.map((row) => {
|
|
558
|
+
if (!isPlainObject(row)) return JSON.stringify(row);
|
|
559
|
+
const fields = ndjsonRow(row as Row, status, statusKey);
|
|
560
|
+
if (!cited) return JSON.stringify(fields);
|
|
561
|
+
const identity = rowIdentity(row as Row, renderOptions.exportIdentity);
|
|
562
|
+
// A dated export's own fields (a row's `released`) keep their values.
|
|
563
|
+
const dating = renderOptions.exportDated
|
|
564
|
+
? Object.fromEntries(Object.entries(exportDatingFields(cited, identity)).filter(([key]) => !(key in fields))) : {};
|
|
565
|
+
return JSON.stringify({ ...fields, ...exportIdentityFields(cited, identity), ...dating });
|
|
566
|
+
}).join("\n");
|
|
450
567
|
}
|
|
451
568
|
if (options.format === "csv") {
|
|
452
|
-
|
|
453
|
-
const
|
|
454
|
-
return withCsvFooter(
|
|
569
|
+
// The rows a window cut say so after them, as text and JSON do: a script has no other way to know.
|
|
570
|
+
const cutNote = window.note ? [`note: ${window.note}`] : [];
|
|
571
|
+
if (!cited) return withCsvFooter(renderCsv(rows as Row[], renderOptions.columns, undefined, status), cutNote);
|
|
572
|
+
const csv = renderCsv(
|
|
573
|
+
rows as Row[],
|
|
574
|
+
renderOptions.columns,
|
|
575
|
+
(row) => exportIdentityCells(cited, rowIdentity(row, renderOptions.exportIdentity)),
|
|
576
|
+
status,
|
|
577
|
+
renderOptions.exportDated ? (row) => exportDatingCells(cited, rowIdentity(row, renderOptions.exportIdentity)) : undefined,
|
|
578
|
+
);
|
|
579
|
+
return withCsvFooter(csv, [...exportSourceLines(cited), ...cutNote, ...(renderOptions.exportNotes ?? []).map((note) => `note: ${note}`)]);
|
|
455
580
|
}
|
|
456
581
|
if (renderOptions.text) {
|
|
457
582
|
return renderOptions.text(result.data);
|
|
@@ -519,6 +644,22 @@ export function printCliResult<T, Row extends Record<string, unknown> = Record<s
|
|
|
519
644
|
console.error(`${cliStyles.warning("warning:")} ${hinted(warning)}`);
|
|
520
645
|
}
|
|
521
646
|
}
|
|
647
|
+
// CSV says what its rows do not in closing `# note:` lines; NDJSON has no place for one among its rows,
|
|
648
|
+
// so the same notes go to stderr, where the warnings are.
|
|
649
|
+
if (options.format === "ndjson" && !options.quiet) {
|
|
650
|
+
for (const note of exportNdjsonNotes(result, options, renderOptions)) console.error(`note: ${note}`);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/** What a `--limit`, or the default a command caps its rows at, left out of a list, then the command's own notes: what CSV closes with as `# note:` lines. */
|
|
655
|
+
function exportNdjsonNotes<T, Row extends Record<string, unknown>>(
|
|
656
|
+
result: CliResult<T>,
|
|
657
|
+
options: CliGlobalOptions,
|
|
658
|
+
renderOptions: CliResultRenderOptions<T, Row>,
|
|
659
|
+
): string[] {
|
|
660
|
+
if (renderOptions.tables || renderOptions.text) return [];
|
|
661
|
+
const cut = windowed(asRows(result.data, renderOptions.rows), options, renderOptions).note;
|
|
662
|
+
return [...cut ? [cut] : [], ...renderOptions.exportNotes ?? []];
|
|
522
663
|
}
|
|
523
664
|
|
|
524
665
|
export function serializeCliError(error: CliErrorObject, options: CliGlobalOptions): string {
|
package/src/cli/series-search.ts
CHANGED
|
@@ -27,7 +27,7 @@ function fredSeriesIdOf(expression: string): string | null {
|
|
|
27
27
|
return /^FRED:([A-Z0-9]+)$/i.exec(expression)?.[1]?.toUpperCase() ?? null;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/** The FRED series the plugins' catalog charts, as `
|
|
30
|
+
/** The FRED series the plugins' catalog charts, as `gloom fred` takes them: DFEDTARU, ECBDFR. */
|
|
31
31
|
export function catalogFredSeriesIds(plugins: readonly SeriesSource[]): Set<string> {
|
|
32
32
|
return new Set(plugins.flatMap((plugin) => plugin.series ?? [])
|
|
33
33
|
.flatMap((definition) => definition.expression ? [fredSeriesIdOf(definition.expression)] : [])
|
|
@@ -96,14 +96,14 @@ export function renderSeriesMatches(
|
|
|
96
96
|
const shown = matches.slice(0, limit);
|
|
97
97
|
const count = shown.length < matches.length ? `${shown.length} of ${matches.length}` : String(matches.length);
|
|
98
98
|
const quoted = `"${query.replace(/"/g, "")}"`;
|
|
99
|
-
// A FRED series named by its id is also one `
|
|
99
|
+
// A FRED series named by its id is also one `gloom fred` prints.
|
|
100
100
|
const asked = query.trim().toUpperCase().replace(/^FRED:/, "");
|
|
101
101
|
const fred = matches.find((match) => match.exact && fredSeriesIdOf(match.expression) === asked);
|
|
102
102
|
const hint = fred
|
|
103
|
-
? `Print it with
|
|
103
|
+
? `Print it with gloom fred ${asked}; chart it with gloom fn G ${fred.expression}.`
|
|
104
104
|
: shown.length < matches.length
|
|
105
|
-
? `Chart one with
|
|
106
|
-
: "Chart one with
|
|
105
|
+
? `Chart one with gloom fn G <chart>; gloom ${rest === "catalog" ? `catalog ${quoted}` : `shot CAT ${quoted}`} lists all ${matches.length}.`
|
|
106
|
+
: "Chart one with gloom fn G <chart>.";
|
|
107
107
|
return [
|
|
108
108
|
`${renderSection(`Series for "${query}"`)} ${cliStyles.muted(`(${count})`)}`,
|
|
109
109
|
renderTable(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { apiClient } from "../api-client";
|
|
2
2
|
import type { BankFiguresPayload } from "../api-client/bank-figures";
|
|
3
3
|
import type { FinancialStatement } from "../types/financials";
|
|
4
|
+
import { fetchOfferingFilings, type OfferingFiling } from "../utils/cash-runway";
|
|
4
5
|
import { logFailure } from "../utils/log-failure";
|
|
5
6
|
import { nonUsSecListingVenue } from "../utils/sec";
|
|
6
7
|
|
|
@@ -42,6 +43,8 @@ export interface StatementReportSources {
|
|
|
42
43
|
/** The company's 10-K, 10-Q, 8-K, 20-F and 40-F filings, newest first. */
|
|
43
44
|
statementFilings(symbol: string): Promise<PeriodicFiling[]>;
|
|
44
45
|
bankFigures(symbol: string): Promise<BankFiguresPayload>;
|
|
46
|
+
/** The company's latest offering prospectuses (424B5, 424B4), newest first. */
|
|
47
|
+
offeringFilings?(symbol: string): Promise<OfferingFiling[]>;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
export const cloudStatementReportSources: StatementReportSources = {
|
|
@@ -62,8 +65,24 @@ export const cloudStatementReportSources: StatementReportSources = {
|
|
|
62
65
|
});
|
|
63
66
|
},
|
|
64
67
|
bankFigures: (symbol) => apiClient.getCloudBankFigures(symbol),
|
|
68
|
+
offeringFilings: (symbol) => fetchOfferingFilings(apiClient, symbol),
|
|
65
69
|
};
|
|
66
70
|
|
|
71
|
+
/**
|
|
72
|
+
* A US listing's latest offering prospectuses, for the note that its cash
|
|
73
|
+
* predates one; nothing (and no request) for any other listing, or when
|
|
74
|
+
* `wanted` is false. A failed read leaves the note out.
|
|
75
|
+
*/
|
|
76
|
+
export async function loadOfferingFilings(
|
|
77
|
+
sources: StatementReportSources | undefined,
|
|
78
|
+
listing: { symbol: string; exchange?: string },
|
|
79
|
+
wanted: boolean,
|
|
80
|
+
): Promise<OfferingFiling[]> {
|
|
81
|
+
if (!wanted || !sources?.offeringFilings || nonUsSecListingVenue(listing.symbol, listing.exchange)) return [];
|
|
82
|
+
return sources.offeringFilings(listing.symbol)
|
|
83
|
+
.catch(logFailure("cli.statement-filings", "Reading the offering filings failed", [] as OfferingFiling[]));
|
|
84
|
+
}
|
|
85
|
+
|
|
67
86
|
/** The filing a statement row's period was read from: its form when the filing list names it, and its filed date. */
|
|
68
87
|
export interface StatementFiling {
|
|
69
88
|
/** 10-Q, 10-K, 20-F or 40-F; null when the filing is not among those listed. */
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { saveConfig } from "../data/config/store";
|
|
2
|
+
import { mergeSavedSuffixedListings } from "../portfolio/suffixed-listings";
|
|
3
|
+
import type { CliCommandContext } from "../types/plugin";
|
|
4
|
+
import { debugLog } from "../utils/debug-log";
|
|
5
|
+
import { logFailure } from "../utils/log-failure";
|
|
6
|
+
import { withConfigData, withMarketData } from "./scoped-context";
|
|
7
|
+
import type { ConfigContext, MarketContext } from "./types";
|
|
8
|
+
|
|
9
|
+
const log = debugLog.createLogger("cli.suffixed-listings");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The profile with the rows a collection holds under a vendor's suffixed key
|
|
13
|
+
* (GARAN.IS) merged into their listing's row (`mergeSuffixedListings`), as
|
|
14
|
+
* the app does at launch, for a command about to change a portfolio or
|
|
15
|
+
* watchlist: what it reads is then what it saves over. A dry run writes
|
|
16
|
+
* nothing and reads the profile as it is. A merge that fails leaves the rows
|
|
17
|
+
* as they were.
|
|
18
|
+
*/
|
|
19
|
+
async function mergedForWrite<TContext extends ConfigContext>(ctx: Pick<CliCommandContext, "cliOptions">, context: TContext): Promise<TContext> {
|
|
20
|
+
if (ctx.cliOptions.dryRun) return context;
|
|
21
|
+
try {
|
|
22
|
+
const merged = await mergeSavedSuffixedListings(await context.store.loadAllTickers(), context.config, {
|
|
23
|
+
config: saveConfig,
|
|
24
|
+
tickers: (rows) => context.store.saveTickers(rows),
|
|
25
|
+
});
|
|
26
|
+
// In place: a market context's provider reads the config through this object.
|
|
27
|
+
if (merged) context.config = merged.config;
|
|
28
|
+
for (const kept of merged?.keptCustom ?? []) log.info("custom fields kept on the suffixed row", kept);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
logFailure("cli.suffixed-listings", "Merging suffixed listing rows failed")(error);
|
|
31
|
+
}
|
|
32
|
+
return context;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** `withConfigData` for a command that changes a portfolio or watchlist (`mergedForWrite`). Commands that only read use `withConfigData`. */
|
|
36
|
+
export function withCollectionConfigData<TResult>(
|
|
37
|
+
ctx: Pick<CliCommandContext, "initConfigData" | "cliOptions">,
|
|
38
|
+
operation: (context: ConfigContext) => TResult | Promise<TResult>,
|
|
39
|
+
): Promise<TResult> {
|
|
40
|
+
return withConfigData(async () => mergedForWrite(ctx, await ctx.initConfigData()), operation);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** `withMarketData` for a command that changes a portfolio or watchlist (`mergedForWrite`). */
|
|
44
|
+
export function withCollectionMarketData<TResult>(
|
|
45
|
+
ctx: Pick<CliCommandContext, "initMarketData" | "cliOptions">,
|
|
46
|
+
operation: (context: MarketContext) => TResult | Promise<TResult>,
|
|
47
|
+
): Promise<TResult> {
|
|
48
|
+
return withMarketData(async () => mergedForWrite(ctx, await ctx.initMarketData()), operation);
|
|
49
|
+
}
|
package/src/cli/symbol-args.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { isFigure, isNumberCell, protectFigureCommas, restoreFigureCommas } from "./symbol-cells";
|
|
2
|
+
import { readTerminalListingCode, unknownBloombergMarket } from "../tickers/terminal-codes";
|
|
3
|
+
|
|
1
4
|
/** The quote marks a pasted list wraps its entries in: "AAPL", 'MSFT', “NVDA”. */
|
|
2
5
|
const QUOTE_MARKS = "\"'`\u2018\u2019\u201C\u201D";
|
|
3
6
|
const QUOTE_EDGES = new RegExp(`^[${QUOTE_MARKS}]+|[${QUOTE_MARKS}]+$`, "g");
|
|
@@ -12,18 +15,37 @@ const LIST_SEPARATOR = /[,;\t\r\n]/;
|
|
|
12
15
|
* in it is split on those, so an entry may be a company's name (`WHR,
|
|
13
16
|
* Whirlpool Corporation, BRK.B`) or several symbols with spaces between them
|
|
14
17
|
* (`brk.b bf-b` on a pasted line); one without them is split on spaces (`JNK
|
|
15
|
-
* EMB BRK.B`)
|
|
18
|
+
* EMB BRK.B`), or with `phrases` kept whole (`splitSymbolArgLines`). Which an
|
|
19
|
+
* entry with a space is takes a search: a command that
|
|
16
20
|
* resolves its symbols reads them with `readNameEntries`, and a parser that
|
|
17
|
-
* looks nothing up takes `splitSymbolWords`.
|
|
21
|
+
* looks nothing up takes `splitSymbolWords`. A comma inside a figure
|
|
22
|
+
* (`2.582,52`, `1,899.21`) is no separator: the figure stays one entry. One
|
|
23
|
+
* between plain digits is a decimal comma only on a line with another
|
|
24
|
+
* separator (`ED 2,5`); alone it splits codes (`9988,5`, `700,388`).
|
|
18
25
|
*/
|
|
19
|
-
export function splitSymbolArgs(args: readonly string[]): string[] {
|
|
20
|
-
return args
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
export function splitSymbolArgs(args: readonly string[], options: { phrases?: boolean } = {}): string[] {
|
|
27
|
+
return args.flatMap((arg) => splitSymbolArgLines(arg, options).flat());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `splitSymbolArgs` of one argument, its entries kept by the line they are
|
|
32
|
+
* on, so a figure can be told to sit beside the symbol on its line. With
|
|
33
|
+
* `phrases`, an argument with spaces and no list separator is one entry, as
|
|
34
|
+
* an entry between commas is: a company's name (`"Beyond Meat"`) or symbols
|
|
35
|
+
* typed on one line (`"GME AMC"`), which `readNameEntries` tells apart.
|
|
36
|
+
*/
|
|
37
|
+
export function splitSymbolArgLines(arg: string, { phrases = false }: { phrases?: boolean } = {}): string[][] {
|
|
38
|
+
const lines = arg.replace(/^\uFEFF/, "").split(/\r\n?|\n/).map((line) => protectFigureCommas(line));
|
|
39
|
+
const separated = lines.length > 1 || lines.some((line) => LIST_SEPARATOR.test(line));
|
|
40
|
+
// A terminal's code (`VOD LN`, `JPM US Equity`), or words written as one (`AAPL GP`), is one entry.
|
|
41
|
+
return lines.map((line) => (separated ? line.split(/[,;\t]/) : phrases || isTerminalCodeLine(line) ? [line] : line.split(/\s+/))
|
|
42
|
+
.map((entry) => restoreFigureCommas(entry).trim().replace(QUOTE_EDGES, "").trim().replace(/\s+/g, " "))
|
|
43
|
+
.filter(Boolean));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isTerminalCodeLine(line: string): boolean {
|
|
47
|
+
const text = line.trim().replace(QUOTE_EDGES, "").trim();
|
|
48
|
+
return /\s/.test(text) && (readTerminalListingCode(text) != null || unknownBloombergMarket(text) != null);
|
|
27
49
|
}
|
|
28
50
|
|
|
29
51
|
/**
|
|
@@ -31,15 +53,28 @@ export function splitSymbolArgs(args: readonly string[]): string[] {
|
|
|
31
53
|
* spaces and no list separator into it: `quote "10 year yield"`, `quote
|
|
32
54
|
* "Apple Inc"` or a pasted line `quote "AAPL MSFT"`. Which of those it is
|
|
33
55
|
* takes a lookup (`readPhraseArgument`); `splitSymbolArgs` would split it
|
|
34
|
-
* into words, each a symbol (10, YEAR, YIELD).
|
|
35
|
-
*
|
|
56
|
+
* into words, each a symbol (10, YEAR, YIELD). A figure in it is part of
|
|
57
|
+
* the phrase (`"10.5 year yield"`, `"fed funds rate 5.25%"`). Null for
|
|
58
|
+
* anything else: several arguments, one word, a list with commas, or a
|
|
59
|
+
* pasted row of symbols each followed by its prices (`ED 2.582,52`, `AAPL
|
|
60
|
+
* 150.00 MSFT 300.00`), which is read as a list is.
|
|
36
61
|
*/
|
|
37
62
|
export function quotedPhrase(args: readonly string[]): string | null {
|
|
38
63
|
if (args.length !== 1) return null;
|
|
39
64
|
const text = args[0]!.replace(/^\uFEFF/, "");
|
|
40
|
-
if (LIST_SEPARATOR.test(text)) return null;
|
|
65
|
+
if (LIST_SEPARATOR.test(protectFigureCommas(text))) return null;
|
|
41
66
|
const phrase = text.trim().replace(QUOTE_EDGES, "").trim().replace(/\s+/g, " ");
|
|
42
|
-
return phrase.includes(" ") ? phrase : null;
|
|
67
|
+
return phrase.includes(" ") && !isPricedRow(phrase.split(" ")) ? phrase : null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Words that are a sheet's row rather than a phrase: a number (`2.582,52`)
|
|
72
|
+
* among them, and each word that is no figure followed by one (`ED
|
|
73
|
+
* 2.582,52`), so no two words of a name or a phrase sit side by side.
|
|
74
|
+
*/
|
|
75
|
+
function isPricedRow(words: readonly string[]): boolean {
|
|
76
|
+
if (!words.some(isNumberCell) || isFigure(words[0]!)) return false;
|
|
77
|
+
return words.every((word, index) => isFigure(word) || (index + 1 < words.length && isFigure(words[index + 1]!)));
|
|
43
78
|
}
|
|
44
79
|
|
|
45
80
|
/**
|
|
@@ -50,7 +85,7 @@ export function quotedPhrase(args: readonly string[]): string | null {
|
|
|
50
85
|
*/
|
|
51
86
|
export function splitSymbolWords(args: readonly string[]): string[] {
|
|
52
87
|
return splitSymbolArgs(args)
|
|
53
|
-
.flatMap((entry) => entry.split(" "))
|
|
88
|
+
.flatMap((entry) => isTerminalCodeLine(entry) ? [entry] : entry.split(" "))
|
|
54
89
|
.map((word) => word.replace(QUOTE_EDGES, ""))
|
|
55
90
|
.filter(Boolean);
|
|
56
91
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one cell of a pasted list or a typed argument is before anything is
|
|
3
|
+
* looked up: a symbol, a figure (a price, a weight, a share count) or junk
|
|
4
|
+
* a sheet leaves where a value is missing (`N/A`, `--`, `$$$`). Every list
|
|
5
|
+
* reader and every lookup of a list's symbols decide it here, so a price
|
|
6
|
+
* from a European sheet (`2.582,52`) is never searched for as a ticker.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** A sign before a figure: plus, hyphen-minus or the minus sign. */
|
|
10
|
+
const SIGN = "[+\\-\u2212]";
|
|
11
|
+
/** The currency marks a sheet writes beside an amount. */
|
|
12
|
+
const CURRENCY = "[$\u20ac\u00a3\u00a5\u20b9\u20a9\u20bd\u20ba\u20aa\u0e3f\u20ab\u00a2]";
|
|
13
|
+
/** Thousands written with an apostrophe (1'234.50) or a no-break or thin space (1 234,50). */
|
|
14
|
+
const GROUP_MARK = "['\u2019\u00a0\u202f\u2009]";
|
|
15
|
+
const FIGURE_BODY = [
|
|
16
|
+
// 1,899.21 and 1,899: commas between thousands.
|
|
17
|
+
"\\d{1,3}(?:,\\d{3})+(?:\\.\\d+)?",
|
|
18
|
+
// 2.582,52, 1.899 and 1.234.567: dots between thousands, a decimal comma.
|
|
19
|
+
"\\d{1,3}(?:\\.\\d{3})+(?:,\\d+)?",
|
|
20
|
+
`\\d{1,3}(?:${GROUP_MARK}\\d{3})+(?:[.,]\\d+)?`,
|
|
21
|
+
// 2,5 and 12,345, and 1234,56: a decimal comma.
|
|
22
|
+
"\\d{1,3},\\d+",
|
|
23
|
+
"\\d+,\\d{1,2}",
|
|
24
|
+
"\\d*\\.\\d+",
|
|
25
|
+
"\\d+",
|
|
26
|
+
].join("|");
|
|
27
|
+
const FIGURE = new RegExp(
|
|
28
|
+
`^(?:${SIGN}?${CURRENCY}?${SIGN}?(?:${FIGURE_BODY})(?:%|\u2030|${CURRENCY})?|\\(${CURRENCY}?(?:${FIGURE_BODY})%?\\))$`,
|
|
29
|
+
"u",
|
|
30
|
+
);
|
|
31
|
+
/** A run of digits and the marks between them, where a comma may be a decimal comma rather than a list's separator. */
|
|
32
|
+
const FIGURE_RUN = new RegExp(`(?<![\\p{L}\\p{N}.])(?:${SIGN}|${CURRENCY})*\\d[\\d.,'\u2019\u00a0\u202f\u2009]*(?:%|\u2030|${CURRENCY})?`, "gu");
|
|
33
|
+
/** Placeholders a sheet writes for a missing value, and its error values: N/A, n.a., #N/A, #VALUE!. */
|
|
34
|
+
const PLACEHOLDER = /^(?:#?n\/a|n\.a\.?|#(?:value!|ref!|div\/0!|name\?|num!|null!|spill!|calc!|getting_data))$/i;
|
|
35
|
+
/** Stands in for a comma inside a figure while a line is split on its separators. */
|
|
36
|
+
const FIGURE_COMMA = "\u0000";
|
|
37
|
+
/** Plain digits split by commas (`7203,10`, `5,700`): a decimal comma, or the line's separator between two codes. */
|
|
38
|
+
const PLAIN_COMMA_RUN = /^\d+(?:,\d+)+$/;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A figure as a sheet or a keyboard writes it, a bare whole number (7203)
|
|
42
|
+
* included: `2.582,52`, `1,899.21`, `-3.2%`, `€1.234,56`, `(1,234.56)`.
|
|
43
|
+
*/
|
|
44
|
+
export function isFigure(cell: string): boolean {
|
|
45
|
+
return FIGURE.test(cell.trim());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A figure that is never a symbol: one with a decimal or thousands mark, a
|
|
50
|
+
* sign, a percent or a currency mark (`1.899`, `2,5`, `+4`, `12%`, `$12`). A
|
|
51
|
+
* bare whole number is not one, as `7203` and `0700` are tickers on their own.
|
|
52
|
+
*/
|
|
53
|
+
export function isNumberCell(cell: string): boolean {
|
|
54
|
+
const text = cell.trim();
|
|
55
|
+
return FIGURE.test(text) && !/^\d+$/.test(text);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** A cell that names nothing: no letter or digit (`$$$`, `--`, `-`, `…`), or a placeholder for a missing value (`N/A`, `#N/A`). */
|
|
59
|
+
export function isJunkCell(cell: string): boolean {
|
|
60
|
+
const text = cell.trim();
|
|
61
|
+
return !/[\p{L}\p{N}]/u.test(text) || PLACEHOLDER.test(text);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Why a cell is not a symbol, as a lookup refuses it without asking anything; null for one that may be. */
|
|
65
|
+
function notASymbolReason(cell: string): string | null {
|
|
66
|
+
if (isJunkCell(cell)) return "not a symbol";
|
|
67
|
+
if (isNumberCell(cell)) return "a number, not a symbol";
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** An entry of a list that cannot be a symbol, refused before any lookup and never looked up again. */
|
|
72
|
+
export class NotASymbolError extends Error {
|
|
73
|
+
constructor(readonly input: string, readonly reason: string) {
|
|
74
|
+
super(`${input.trim()} is ${reason}.`);
|
|
75
|
+
this.name = "NotASymbolError";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** `NotASymbolError` for a cell that is not a symbol, else null. */
|
|
80
|
+
export function notASymbolError(cell: string): NotASymbolError | null {
|
|
81
|
+
const reason = notASymbolReason(cell);
|
|
82
|
+
return reason ? new NotASymbolError(cell, reason) : null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Whether a comma between plain digits on a line is a decimal comma (`ED
|
|
87
|
+
* 2,5`, `CNX;1899,21`): the line has another separator, a tab, a semicolon or
|
|
88
|
+
* spaces between its cells. Otherwise the comma is the line's only separator
|
|
89
|
+
* and splits the digits into cells, as a sheet of codes exports them
|
|
90
|
+
* (`0700,25`, `7203,10`). Quoted cells and separators at the ends are not
|
|
91
|
+
* counted.
|
|
92
|
+
*/
|
|
93
|
+
export function hasDecimalCommas(line: string): boolean {
|
|
94
|
+
const bare = line.replace(/"(?:[^"]|"")*"/g, "\"\"").replace(/^[\s,;]+|[\s,;]+$/g, "");
|
|
95
|
+
return /[\t;]/.test(bare) || /[^\s,;]\s+[^\s,;]/.test(bare);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The text with each comma inside a figure swapped for a stand-in, so
|
|
100
|
+
* splitting on commas leaves the figure whole; `restoreFigureCommas` puts
|
|
101
|
+
* them back. A figure only a number can be (`2.582,52`, `1,899.21`, `2,5%`)
|
|
102
|
+
* keeps its comma. One of plain digits (`7203,10`) keeps it only where its
|
|
103
|
+
* comma is a decimal comma: `decimalCommas`, else `hasDecimalCommas` of each
|
|
104
|
+
* line. A run that is no figure keeps its commas as separators.
|
|
105
|
+
*/
|
|
106
|
+
export function protectFigureCommas(text: string, decimalCommas?: boolean): string {
|
|
107
|
+
if (decimalCommas == null) {
|
|
108
|
+
return text.split(/(\r\n?|\n)/).map((part, index) => index % 2 === 1 ? part : protectFigureCommas(part, hasDecimalCommas(part))).join("");
|
|
109
|
+
}
|
|
110
|
+
return text.replace(FIGURE_RUN, (run) => {
|
|
111
|
+
const body = run.replace(/[.,'\u2019]+$/, "");
|
|
112
|
+
const tail = run.slice(body.length);
|
|
113
|
+
const figure = body.includes(",") && isFigure(body) && (decimalCommas || !PLAIN_COMMA_RUN.test(body));
|
|
114
|
+
return figure ? `${body.replaceAll(",", FIGURE_COMMA)}${tail}` : run;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function restoreFigureCommas(text: string): string {
|
|
119
|
+
return text.replaceAll(FIGURE_COMMA, ",");
|
|
120
|
+
}
|