gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DataServiceUnreachableError, isNetworkFailure } from "../utils/network-failure";
|
|
2
|
+
|
|
1
3
|
// Registered, so a miss raised by another copy of this module (a plugin that
|
|
2
4
|
// resolved `gloomberb/market-data` from the source tree) is still recognized.
|
|
3
5
|
const PROVIDER_MISS_BRAND = Symbol.for("gloomberb.provider-miss");
|
|
@@ -44,6 +46,14 @@ export function createProviderMiss(message?: string, reason?: unknown, options?:
|
|
|
44
46
|
return new ProviderMissError(message, reason, options);
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
/** A source has the listing's bars but not up to the present: it answered, just behind. */
|
|
50
|
+
export class StaleHistoryError extends ProviderMissError {
|
|
51
|
+
constructor(message: string) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "StaleHistoryError";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
47
57
|
function isProviderMiss(error: unknown): error is ProviderMissError {
|
|
48
58
|
return error instanceof ProviderMissError
|
|
49
59
|
|| (!!error && typeof error === "object" && PROVIDER_MISS_BRAND in error);
|
|
@@ -129,12 +139,16 @@ class NoProviderError extends Error {
|
|
|
129
139
|
/**
|
|
130
140
|
* The router's final error when no provider answered. A reason a provider gave
|
|
131
141
|
* replaces the generic wording, and so does the service's answer that no
|
|
132
|
-
* listing exists for `symbol` ("Not a ticker")
|
|
133
|
-
*
|
|
142
|
+
* listing exists for `symbol` ("Not a ticker"), and a request that never
|
|
143
|
+
* reached the data service, which says that rather than that no source has the
|
|
144
|
+
* symbol; a timeout or any other failure keeps the generic message.
|
|
134
145
|
*/
|
|
135
146
|
export function noProviderError(message: string, note: ProviderMissNote | undefined, symbol?: string): Error {
|
|
136
147
|
if (note?.reason) return createProviderMiss(note.reason, note.reason);
|
|
137
148
|
if (note?.notFound === true && symbol) return createProviderMiss(notATickerMessage(symbol), undefined, { notFound: true });
|
|
149
|
+
if (isNetworkFailure(note?.failure)) {
|
|
150
|
+
return note!.failure instanceof DataServiceUnreachableError ? note!.failure : new DataServiceUnreachableError(note!.failure);
|
|
151
|
+
}
|
|
138
152
|
return new NoProviderError(message, note?.failure);
|
|
139
153
|
}
|
|
140
154
|
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
sortCachedRecords,
|
|
17
17
|
} from "./cache";
|
|
18
18
|
import { noProviderError, type ProviderMissNote } from "../provider-errors";
|
|
19
|
+
import { servedFromSavedCopy } from "../../data/saved-copies";
|
|
19
20
|
import { withBrokerTimeout } from "./brokers";
|
|
20
21
|
import {
|
|
21
22
|
hasMeaningfulProfile,
|
|
@@ -166,7 +167,8 @@ export class ProviderRouterFinancialRoutes {
|
|
|
166
167
|
|
|
167
168
|
if (cached.value) {
|
|
168
169
|
const brokerResult = await withBrokerTimeout(this.deps.primaryRoutes.fetchBrokerFinancials(ticker, exchange, context));
|
|
169
|
-
const
|
|
170
|
+
const refresh: ProviderMissNote = {};
|
|
171
|
+
const providerResult = await this.deps.primaryRoutes.fetchProviderFinancials(ticker, exchange, context, refresh);
|
|
170
172
|
const merged = mergeFinancials(
|
|
171
173
|
brokerResult?.value ?? cached.brokerRecord?.value ?? null,
|
|
172
174
|
context?.statementHistory === "extended"
|
|
@@ -176,7 +178,14 @@ export class ProviderRouterFinancialRoutes {
|
|
|
176
178
|
if (isOptionTicker && !merged?.quote) {
|
|
177
179
|
return quoteOnlyFinancials(merged ?? cached.value);
|
|
178
180
|
}
|
|
179
|
-
|
|
181
|
+
const answer = merged ?? cached.value;
|
|
182
|
+
// The refresh failed and the saved copy answers: marked with when its
|
|
183
|
+
// oldest part was saved, and its quote too unless a broker's live one
|
|
184
|
+
// replaced it, since the quote is what a report's closing line dates.
|
|
185
|
+
const saved = cached.providerRecords?.map((record) => record.fetchedAt) ?? [];
|
|
186
|
+
return !providerResult && refresh.failure !== undefined && cached.providerValue && saved.length > 0
|
|
187
|
+
? savedFinancials(answer, Math.min(...saved), !brokerResult?.value?.quote)
|
|
188
|
+
: answer;
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
const brokerResult = await withBrokerTimeout(this.deps.primaryRoutes.fetchBrokerFinancials(ticker, exchange, context));
|
|
@@ -229,7 +238,10 @@ export class ProviderRouterFinancialRoutes {
|
|
|
229
238
|
if (providerQuote) {
|
|
230
239
|
return providerQuote.value;
|
|
231
240
|
}
|
|
232
|
-
if (cached)
|
|
241
|
+
if (cached) {
|
|
242
|
+
// The refresh failed rather than finding nothing newer: the saved copy answers, and says so.
|
|
243
|
+
return misses.failure !== undefined ? servedFromSavedCopy(cached.value, cached.fetchedAt) : cached.value;
|
|
244
|
+
}
|
|
233
245
|
// No source has a current quote: the last price one answered with, flagged
|
|
234
246
|
// stale and dated by its own time, rather than none.
|
|
235
247
|
if (misses.lastKnownQuote) return misses.lastKnownQuote;
|
|
@@ -363,3 +375,9 @@ export class ProviderRouterFinancialRoutes {
|
|
|
363
375
|
return this.readCachedMergedFinancialsSelection(ticker, exchange, context, allowExpired, options).value;
|
|
364
376
|
}
|
|
365
377
|
}
|
|
378
|
+
|
|
379
|
+
/** Financials as served from their saved copy, with their quote when it is the saved one. */
|
|
380
|
+
function savedFinancials(value: TickerFinancials, savedAt: number, savedQuote: boolean): TickerFinancials {
|
|
381
|
+
const served = servedFromSavedCopy(value, savedAt);
|
|
382
|
+
return savedQuote && served.quote ? { ...served, quote: servedFromSavedCopy(served.quote, savedAt) } : served;
|
|
383
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CachedResourceRecord, ResourceStore } from "../../data/resource-store";
|
|
2
|
-
import type { AnalystResearchData, CorporateActionsData, FinancialStatement, Fundamentals, Quote, TickerFinancials } from "../../types/financials";
|
|
2
|
+
import type { AnalystResearchData, CompanyProfile, CorporateActionsData, FinancialStatement, Fundamentals, Quote, TickerFinancials } from "../../types/financials";
|
|
3
3
|
import { hasLikelyQuoteUnitMismatch } from "../../utils/currency-units";
|
|
4
4
|
import { coalesceFinancialPeriodAliases, mergeFinancialStatementRows } from "../../utils/financial-statements";
|
|
5
5
|
import { normalizePriceHistory, normalizeTickerFinancialsPriceHistory } from "../../utils/price-history";
|
|
@@ -51,6 +51,19 @@ function isFundFinancials(financials: Pick<TickerFinancials, "quote" | "quoteMet
|
|
|
51
51
|
return ["etf", "exchangetradedfund", "mutualfund", "fund"].includes(researchInstrumentType(financials) ?? "");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* What a fund's profile keeps: its description, and where a quoted one is
|
|
56
|
+
* from with the fund's own page beside it. A provider's website for a fund is
|
|
57
|
+
* its manager's, not the fund's.
|
|
58
|
+
*/
|
|
59
|
+
function fundProfile(profile: CompanyProfile): CompanyProfile {
|
|
60
|
+
const source = profile.descriptionSource;
|
|
61
|
+
return {
|
|
62
|
+
description: profile.description,
|
|
63
|
+
...(source ? { descriptionSource: source, ...(profile.website ? { website: profile.website } : {}) } : {}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
function excludeNonCompanyFinancials(financials: TickerFinancials): TickerFinancials {
|
|
55
68
|
const type = researchInstrumentType(financials);
|
|
56
69
|
if (!type || !["etf", "exchangetradedfund", "mutualfund", "fund", "index", "currency", "forex", "fx", "future", "futures", "cryptocurrency", "crypto", "digitalcurrency"].includes(type)) return financials;
|
|
@@ -71,7 +84,7 @@ function excludeNonCompanyFinancials(financials: TickerFinancials): TickerFinanc
|
|
|
71
84
|
fetchedAt: statistics.fetchedAt,
|
|
72
85
|
stale: statistics.stale,
|
|
73
86
|
} : undefined,
|
|
74
|
-
profile: fund && financials.profile?.description ?
|
|
87
|
+
profile: fund && financials.profile?.description ? fundProfile(financials.profile) : undefined,
|
|
75
88
|
nextEarnings: undefined,
|
|
76
89
|
annualStatements: [],
|
|
77
90
|
quarterlyStatements: [],
|
|
@@ -25,8 +25,9 @@ import { isRoundTheClockCoin } from "../../utils/crypto-pair";
|
|
|
25
25
|
import { zonedDateKey } from "../../utils/zoned-date-time";
|
|
26
26
|
import { resolvePriceHistoryCurrencyUnit } from "../../utils/currency-units";
|
|
27
27
|
import { calendarHistoryFetchState, calendarHistoryLastBarDate, dropLeadingPlaceholderBars, getPricePointTimestamp, hasUsablePriceHistory, preservePriceHistoryGaps, isPriceHistoryStaleForCurrentWindow, normalizePriceHistory, priceHistoryIntervalMs, type CalendarHistoryFetchState } from "../../utils/price-history";
|
|
28
|
-
import { noProviderError, noteProviderAnswer, noteProviderMiss, shouldLogProviderError, type ProviderMissNote } from "../provider-errors";
|
|
28
|
+
import { noProviderError, noteProviderAnswer, noteProviderMiss, shouldLogProviderError, StaleHistoryError, type ProviderMissNote } from "../provider-errors";
|
|
29
29
|
import { HistoryCoverageError } from "../history-coverage";
|
|
30
|
+
import { servedFromSavedCopy } from "../../data/saved-copies";
|
|
30
31
|
import {
|
|
31
32
|
buildVariantKey,
|
|
32
33
|
compactDate,
|
|
@@ -44,7 +45,9 @@ type PriceHistoryCachePolicyKey = Extract<
|
|
|
44
45
|
>;
|
|
45
46
|
// Bumped instead of adding markers: every older record is a miss and refetches.
|
|
46
47
|
// Refetch source/session metadata under the current public backend contract.
|
|
47
|
-
|
|
48
|
+
// 8: copies saved while Gloom Cloud could serve bars on two split bases (NRDY
|
|
49
|
+
// after its 1-for-15 reverse split of 19 Aug 2026) are not shown again.
|
|
50
|
+
const PRICE_HISTORY_CACHE_VERSION = 8;
|
|
48
51
|
interface HistoryRequestDescriptor {
|
|
49
52
|
target: { symbol: string; exchange: string };
|
|
50
53
|
identity: RouterRequestIdentity;
|
|
@@ -111,7 +114,10 @@ function candidateForRequest(request: HistoryRequestDescriptor, sourceKey: strin
|
|
|
111
114
|
function recordHistoryError(attempts: HistoryAttempts | undefined, request: HistoryRequestDescriptor, sourceKey: string, error: unknown): void {
|
|
112
115
|
if (!attempts) return;
|
|
113
116
|
noteProviderMiss(attempts.misses, error);
|
|
114
|
-
if (error instanceof
|
|
117
|
+
if (error instanceof StaleHistoryError) {
|
|
118
|
+
// It has the bars, only not up to the present: behind, as a stale copy it served would be.
|
|
119
|
+
recordHistoryOutcome(attempts, sourceKey, "stale");
|
|
120
|
+
} else if (error instanceof InvalidHistoryResultError) {
|
|
115
121
|
recordHistoryOutcome(attempts, sourceKey, "malformed");
|
|
116
122
|
} else if (isHistoryRetentionError(error)) {
|
|
117
123
|
recordHistoryOutcome(attempts, sourceKey, "retention");
|
|
@@ -579,7 +585,21 @@ export class ProviderRouterHistoryRoutes {
|
|
|
579
585
|
});
|
|
580
586
|
}
|
|
581
587
|
|
|
588
|
+
/** The answer, named by the source that served it, so a caller can say which one did. */
|
|
582
589
|
private async executeHistoryRequest(request: HistoryRequestDescriptor): Promise<PriceHistoryResult> {
|
|
590
|
+
const answer = await this.answerHistoryRequest(request);
|
|
591
|
+
const sourceName = answer.sourceKey ? this.sourceName(answer.sourceKey, request.context) : undefined;
|
|
592
|
+
return sourceName ? { ...answer, sourceName } : answer;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
private sourceName(sourceKey: string, context?: MarketDataRequestContext): string | undefined {
|
|
596
|
+
const provider = this.deps.providersInPriorityOrder().find((candidate) => this.deps.providerSourceKey(candidate) === sourceKey);
|
|
597
|
+
if (provider) return provider.name;
|
|
598
|
+
return this.deps.getBrokerCandidatesForContext(context, false)
|
|
599
|
+
.find((candidate) => this.deps.brokerSourceKey(candidate) === sourceKey)?.broker.name;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
private async answerHistoryRequest(request: HistoryRequestDescriptor): Promise<PriceHistoryResult> {
|
|
583
603
|
const recovery = this.validateRecovery(request);
|
|
584
604
|
const { first: brokerCandidates, last: regularSessionBrokers } = brokersForSession(
|
|
585
605
|
recovery ? [] : this.deps.getBrokerCandidatesForContext(request.context, false), request.context);
|
|
@@ -717,9 +737,9 @@ export class ProviderRouterHistoryRoutes {
|
|
|
717
737
|
// from a current one: a thin listing's complete copy is not behind.
|
|
718
738
|
const fallbackValue = request.isCachedValueStale(fallbackRecord.value, fallbackRecord.fetchedAt)
|
|
719
739
|
? { ...fallbackRecord.value, savedCopyBehind: true as const } : fallbackRecord.value;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
740
|
+
const answer = request.requestedRange ? clip(withReportedGaps(fallbackValue)) : withReportedGaps(fallbackValue);
|
|
741
|
+
// A refetch that failed, rather than one that found nothing newer, leaves the saved copy answering.
|
|
742
|
+
return attempts.misses.failure !== undefined ? servedFromSavedCopy(answer, fallbackRecord.fetchedAt) : answer;
|
|
723
743
|
}
|
|
724
744
|
if (coverageError) throw coverageError;
|
|
725
745
|
if (attempts.coverageError) throw attempts.coverageError;
|
|
@@ -735,8 +755,10 @@ export class ProviderRouterHistoryRoutes {
|
|
|
735
755
|
const behind = coin && [...attempts.outcomes.values()].some((outcome) => outcome.outcome === "stale");
|
|
736
756
|
if (behind) throw new Error(`Latest history for ${target.symbol} is behind`);
|
|
737
757
|
// A reason the service gave ("ADX listings have daily bars only.") says why; one that has no
|
|
738
|
-
// listing for the symbol says it is not a ticker; otherwise no source answered.
|
|
739
|
-
|
|
758
|
+
// listing for the symbol says it is not a ticker; otherwise no source answered. A coin trades
|
|
759
|
+
// around the clock and its sources are there: they could not answer just now.
|
|
760
|
+
throw noProviderError(coin ? `No source could load history for ${request.target.symbol} just now` : request.missingProviderError,
|
|
761
|
+
attempts.misses, request.target.symbol);
|
|
740
762
|
}
|
|
741
763
|
return withReportedGaps(providerResult?.value ?? { points: [], resolution: historyResolutionForInterval(request.interval) });
|
|
742
764
|
}
|
|
@@ -26,6 +26,7 @@ import { mergeQuoteMetadata, quoteMetadataFromQuote, quoteMetadataMatchesTarget
|
|
|
26
26
|
import type { NewsArticle, NewsQuery } from "../../news/types";
|
|
27
27
|
import type { BrokerContractRef, InstrumentSearchResult } from "../../types/instrument";
|
|
28
28
|
import type { TickerChanges } from "../../types/ticker-changes";
|
|
29
|
+
import type { IssuerListings } from "../../types/issuer-listings";
|
|
29
30
|
import type { TimeRange } from "../../time-series/range";
|
|
30
31
|
import type { ChartResolutionSupport, ManualChartResolution } from "../../time-series/resolution";
|
|
31
32
|
import { debugLog } from "../../utils/debug-log";
|
|
@@ -317,6 +318,21 @@ export class AssetDataRouter implements DataProvider {
|
|
|
317
318
|
return null;
|
|
318
319
|
}
|
|
319
320
|
|
|
321
|
+
/** The first source that holds the company's listings; one that fails is passed over. */
|
|
322
|
+
async getIssuerListings(symbol: string, exchange?: string, options?: { signal?: AbortSignal }): Promise<IssuerListings | null> {
|
|
323
|
+
for (const provider of this.providersInPriorityOrder()) {
|
|
324
|
+
if (!provider.getIssuerListings) continue;
|
|
325
|
+
try {
|
|
326
|
+
const listings = await provider.getIssuerListings(symbol, exchange, options);
|
|
327
|
+
if (listings) return listings;
|
|
328
|
+
} catch (error) {
|
|
329
|
+
if (options?.signal?.aborted) return null;
|
|
330
|
+
logFailure("sources.provider-router.index", "Issuer listings failed")(error);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
|
|
320
336
|
async getEarningsCalendar(symbols: string[], context?: MarketDataRequestContext) {
|
|
321
337
|
return this.supplementalRoutes.getEarningsCalendar(symbols, context);
|
|
322
338
|
}
|
|
@@ -163,7 +163,7 @@ export class ProviderRouterPrimaryRoutes {
|
|
|
163
163
|
const entityKey = this.options.getEntityKey(ticker, context?.instrument);
|
|
164
164
|
const variantKey = this.options.getTickerVariantCandidates(exchange)[0] ?? "";
|
|
165
165
|
for (const candidate of this.options.getBrokerCandidatesForContext(context, false)) {
|
|
166
|
-
if (!candidate.broker.getQuote) continue;
|
|
166
|
+
if (!candidate.broker.getQuote || candidate.broker.ticketQuotesOnly) continue;
|
|
167
167
|
try {
|
|
168
168
|
const result = await candidate.broker.getQuote(
|
|
169
169
|
ticker,
|
|
@@ -14,6 +14,8 @@ import { hasAmbiguousTickerContracts, resolveInstrumentForPane } from "../../cor
|
|
|
14
14
|
import { getDockedPaneIds } from "../../layout/pane-manager";
|
|
15
15
|
import { debugLog } from "../../utils/debug-log";
|
|
16
16
|
import { measurePerf, measurePerfAsync } from "../../utils/perf-marks";
|
|
17
|
+
import { mergeSavedSuffixedListings } from "../../portfolio/suffixed-listings";
|
|
18
|
+
import { saveConfigImmediately } from "../config-save-scheduler";
|
|
17
19
|
|
|
18
20
|
export const DEFAULT_WATCHLIST_TICKERS: Array<Pick<TickerMetadata, "ticker" | "exchange" | "currency" | "name">> = [
|
|
19
21
|
{ ticker: "AAPL", exchange: "NASDAQ", currency: "USD", name: "Apple Inc." },
|
|
@@ -253,6 +255,27 @@ export async function initializeAppState({
|
|
|
253
255
|
let tickers = await measurePerfAsync("startup.load-tickers", () => tickerRepository.loadAllTickers());
|
|
254
256
|
startupLog.info("tickers loaded", { count: tickers.length });
|
|
255
257
|
|
|
258
|
+
// A collection's rows under a vendor's suffixed key (GARAN.IS) merge into their listing's row (GARAN:BIST).
|
|
259
|
+
// The moved targets are written before the rows, so a stop in between strands none on an emptied key.
|
|
260
|
+
try {
|
|
261
|
+
const merged = await mergeSavedSuffixedListings(tickers, config, {
|
|
262
|
+
config: saveConfigImmediately,
|
|
263
|
+
tickers: async (rows) => {
|
|
264
|
+
for (const row of rows) await tickerRepository.saveTicker(row);
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
if (merged) {
|
|
268
|
+
tickers = merged.tickers;
|
|
269
|
+
startupLog.info("suffixed listing rows merged", { keptCustom: merged.keptCustom });
|
|
270
|
+
if (merged.config !== config) {
|
|
271
|
+
config = merged.config;
|
|
272
|
+
dispatch({ type: "SET_CONFIG", config });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
startupLog.warn("suffixed listing merge failed", { message: error instanceof Error ? error.message : String(error) });
|
|
277
|
+
}
|
|
278
|
+
|
|
256
279
|
// Seed default watchlist tickers on first run
|
|
257
280
|
if (tickers.length === 0) {
|
|
258
281
|
const defaultWatchlistId = config.watchlists[0]?.id ?? "watchlist";
|
|
@@ -84,6 +84,17 @@ function tickerKey(symbol: string): string {
|
|
|
84
84
|
return listingKeys.get(symbol) ?? symbol;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Points a badge's symbol at the ticker its lookup settled on. A lookup that
|
|
89
|
+
* settles on a key other than the badge's own ($BRK-B on BRK.B, $TTF on TTF=F)
|
|
90
|
+
* must say so here: the next pass reads the badge's ticker under this key, and
|
|
91
|
+
* one that finds nothing asks again, gets the same answer and never stops.
|
|
92
|
+
*/
|
|
93
|
+
function pointBadgeAt(symbol: string, key: string): void {
|
|
94
|
+
if (key === symbol) listingKeys.delete(symbol);
|
|
95
|
+
else listingKeys.set(symbol, key);
|
|
96
|
+
}
|
|
97
|
+
|
|
87
98
|
/** The saved ticker a badge's symbol stands for: its own, or the listing its tag resolved to. */
|
|
88
99
|
function badgeTicker(tickers: ReadonlyMap<string, TickerRecord>, symbol: string): TickerRecord | null {
|
|
89
100
|
return tickers.get(tickerKey(symbol)) ?? null;
|
|
@@ -158,7 +169,11 @@ async function loadInlineQuotes(requests: Map<string, QuoteRequest>): Promise<vo
|
|
|
158
169
|
// asks the provider directly.
|
|
159
170
|
await Promise.all(batch.map(async ([symbol, { instrument, context }]) => {
|
|
160
171
|
const provider = context.registry?.marketData;
|
|
161
|
-
if (!provider)
|
|
172
|
+
if (!provider) {
|
|
173
|
+
// Nobody to ask is an answer too: unrecorded, the next pass would ask again at once.
|
|
174
|
+
inlineTickerQuoteFailures.record(symbol, "error");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
162
177
|
try {
|
|
163
178
|
const quote = await provider.getQuote(
|
|
164
179
|
instrument.symbol,
|
|
@@ -279,6 +294,8 @@ export function useInlineTickers(
|
|
|
279
294
|
const textsKey = texts.join("\u0000");
|
|
280
295
|
const symbols = useMemo(() => normalizeSymbols(texts), [textsKey]);
|
|
281
296
|
const symbolsKey = symbols.join("|");
|
|
297
|
+
// A lookup can point a symbol at a saved ticker's key without changing any ticker.
|
|
298
|
+
const badgeKeys = symbols.map(tickerKey).join("|");
|
|
282
299
|
const financialsEffectTarget = liveQuotes ? financials : null;
|
|
283
300
|
const latestRef = useRef<InlineTickerContext>({ tickers, financials, dispatch, registry });
|
|
284
301
|
|
|
@@ -297,7 +314,7 @@ export function useInlineTickers(
|
|
|
297
314
|
const instrument = ticker ? instrumentFromTicker(ticker, tickerKey(symbol)) : null;
|
|
298
315
|
return instrument ? [instrument] : [];
|
|
299
316
|
});
|
|
300
|
-
}, [liveQuotes, symbolsKey, tickers]);
|
|
317
|
+
}, [badgeKeys, liveQuotes, symbolsKey, tickers]);
|
|
301
318
|
const streamingTargets = useMemo(() => {
|
|
302
319
|
if (!settled) return [];
|
|
303
320
|
return instruments.map((instrument) => ({
|
|
@@ -362,7 +379,9 @@ export function useInlineTickers(
|
|
|
362
379
|
}
|
|
363
380
|
|
|
364
381
|
if (!currentTicker) {
|
|
365
|
-
|
|
382
|
+
// With no registry there is nothing to ask: a lookup would settle at
|
|
383
|
+
// once with nothing learnt, wake this effect and start again.
|
|
384
|
+
if (!registry || inlineTickerResolutionFailures.read(symbol, now)) continue;
|
|
366
385
|
let resolution = resolutionInFlight.get(symbol);
|
|
367
386
|
if (!resolution) {
|
|
368
387
|
resolution = (async () => {
|
|
@@ -382,7 +401,7 @@ export function useInlineTickers(
|
|
|
382
401
|
inlineTickerResolutionFailures.record(symbol, "unknown");
|
|
383
402
|
return;
|
|
384
403
|
}
|
|
385
|
-
|
|
404
|
+
pointBadgeAt(symbol, target.ticker.metadata.ticker);
|
|
386
405
|
current.dispatch({ type: "UPDATE_TICKER", ticker: target.ticker });
|
|
387
406
|
if (target.created) {
|
|
388
407
|
activeRegistry.events.emit("ticker:added", { symbol: target.symbol, ticker: target.ticker });
|
|
@@ -402,9 +421,15 @@ export function useInlineTickers(
|
|
|
402
421
|
return;
|
|
403
422
|
}
|
|
404
423
|
|
|
405
|
-
if (resolved.kind === "local")
|
|
424
|
+
if (resolved.kind === "local") {
|
|
425
|
+
// A saved ticker the symbol is another spelling of, already in state.
|
|
426
|
+
pointBadgeAt(symbol, resolved.ticker.metadata.ticker);
|
|
427
|
+
inlineTickerResolutionFailures.clear(symbol);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
406
430
|
|
|
407
431
|
const { ticker, created } = await upsertTickerFromSearchResult(activeRegistry.tickerRepository, resolved.result);
|
|
432
|
+
pointBadgeAt(symbol, ticker.metadata.ticker);
|
|
408
433
|
current.dispatch({ type: "UPDATE_TICKER", ticker });
|
|
409
434
|
if (created) {
|
|
410
435
|
activeRegistry.events.emit("ticker:added", { symbol: ticker.metadata.ticker, ticker });
|
package/src/sync/controller.ts
CHANGED
|
@@ -94,7 +94,7 @@ export class CloudSyncController {
|
|
|
94
94
|
* The content signature of the cloud's copy, with the revision and the
|
|
95
95
|
* write it belongs to. Each 15 s poll pulls the same copy again until a
|
|
96
96
|
* device writes; working its signature out every time was a third of an
|
|
97
|
-
* idle sync on a large workspace
|
|
97
|
+
* idle sync on a large workspace.
|
|
98
98
|
*/
|
|
99
99
|
private cloudSignature: { transportId: string; revision: number; clientId: string; createdAt: string; signature: string } | null = null;
|
|
100
100
|
private baseline: Record<string, unknown> | null = null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { scheduleConfigSave } from "../state/config-save-scheduler";
|
|
1
|
+
import { saveConfigImmediately, scheduleConfigSave } from "../state/config-save-scheduler";
|
|
2
2
|
import { normalizeStoredBaseCurrency } from "../utils/base-currency";
|
|
3
3
|
import { debugLog } from "../utils/debug-log";
|
|
4
4
|
import { fnv1aHex, stableStringify } from "../utils/hash";
|
|
@@ -9,6 +9,7 @@ import type { BrokerAccount } from "../types/trading";
|
|
|
9
9
|
import { hydrateTickerMetadata } from "../tickers/metadata";
|
|
10
10
|
import type { SyncContributor } from "./types";
|
|
11
11
|
import { convertCurrency } from "../utils/format";
|
|
12
|
+
import { fxRateCurrencies } from "../utils/currency-units";
|
|
12
13
|
import { getSharedMarketDataCoordinator, resolveEntryValue } from "../market-data/coordinator";
|
|
13
14
|
import {
|
|
14
15
|
computeDatedBeta,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
import { isFiniteNumber, isRecord, recordOrNull } from "../utils/guards";
|
|
35
36
|
import { getBrokerInstance } from "../utils/broker-instances";
|
|
36
37
|
import { withoutMissingWatchlists } from "../portfolio/mutations";
|
|
38
|
+
import { mergeSuffixedListings, moveTargetWeights } from "../portfolio/suffixed-listings";
|
|
37
39
|
import { positionContractMultiplier } from "../portfolio/position-metrics";
|
|
38
40
|
import {
|
|
39
41
|
clearLeftoverBrokerHoldings,
|
|
@@ -124,6 +126,7 @@ function sanitizePortfolio(portfolio: Portfolio): Portfolio {
|
|
|
124
126
|
name: portfolio.name,
|
|
125
127
|
description: portfolio.description,
|
|
126
128
|
currency: portfolio.currency,
|
|
129
|
+
...(portfolio.fixedCurrency ? { fixedCurrency: true } : {}),
|
|
127
130
|
brokerId: portfolio.brokerId,
|
|
128
131
|
lastSyncedAt: portfolio.lastSyncedAt,
|
|
129
132
|
// Cash and targets are the user's own entries: a pulled portfolio without
|
|
@@ -379,6 +382,8 @@ function sanitizeTickerMetadata(metadata: TickerMetadata, financials?: TickerFin
|
|
|
379
382
|
positions: metadata.positions.map(sanitizePosition),
|
|
380
383
|
custom: (sanitizeUnknown(metadata.custom) as Record<string, unknown>) ?? {},
|
|
381
384
|
tags: [...metadata.tags],
|
|
385
|
+
// What a listing's row took from a suffixed key's row, so a device that merges it later never counts a lot twice.
|
|
386
|
+
...metadata.mergedLots ? { mergedLots: metadata.mergedLots } : {},
|
|
382
387
|
quote: sanitizeQuote(financials),
|
|
383
388
|
};
|
|
384
389
|
}
|
|
@@ -468,8 +473,8 @@ function recentPriceHistory(history: PricePoint[], days: number): PricePoint[] {
|
|
|
468
473
|
* Work derived from a bar history, kept with the history. Every sync values
|
|
469
474
|
* every portfolio and quotes every filed ticker (each 15 s poll, and after
|
|
470
475
|
* each workspace change), and redoing that work from each holding's bars
|
|
471
|
-
* blocked the view for a quarter of a second on a few hundred holdings
|
|
472
|
-
*
|
|
476
|
+
* blocked the view for a quarter of a second on a few hundred holdings.
|
|
477
|
+
* Bars change when a history loads again, which replaces the
|
|
473
478
|
* array; a last bar extended or revised in place, or one appended, is caught
|
|
474
479
|
* by its length, time and close.
|
|
475
480
|
*/
|
|
@@ -597,18 +602,15 @@ async function loadHoldingExchangeRates(
|
|
|
597
602
|
const rates = new Map([["USD", 1]]);
|
|
598
603
|
const coordinator = getSharedMarketDataCoordinator();
|
|
599
604
|
if (!coordinator) return rates;
|
|
600
|
-
const
|
|
601
|
-
const track = (currency: string | undefined) => {
|
|
602
|
-
const normalized = currency?.trim().toUpperCase();
|
|
603
|
-
if (normalized && normalized !== "USD") currencies.add(normalized);
|
|
604
|
-
};
|
|
605
|
-
track(config.baseCurrency);
|
|
605
|
+
const held: Array<string | undefined> = [config.baseCurrency];
|
|
606
606
|
for (const ticker of tickers.values()) {
|
|
607
607
|
if (ticker.metadata.positions.length === 0) continue;
|
|
608
|
-
|
|
609
|
-
for (const position of ticker.metadata.positions)
|
|
608
|
+
held.push(financials.get(ticker.metadata.ticker)?.quote?.currency);
|
|
609
|
+
for (const position of ticker.metadata.positions) held.push(position.currency);
|
|
610
610
|
}
|
|
611
|
-
|
|
611
|
+
// With a minor unit's major currency, as the panes load them (GBX and ILA have no rate of their own).
|
|
612
|
+
const currencies = fxRateCurrencies(held).filter((currency) => currency !== "USD");
|
|
613
|
+
await Promise.all(currencies.map(async (currency) => {
|
|
612
614
|
// A failed FX load must not hold back the rest of the push.
|
|
613
615
|
await coordinator.loadFxRate(currency).catch(() => {});
|
|
614
616
|
const rate = resolveEntryValue(coordinator.getFxEntry(currency));
|
|
@@ -1435,8 +1437,12 @@ export const coreCollectionsSyncContributor: SyncContributor = {
|
|
|
1435
1437
|
nextTickers.set(next.metadata.ticker, next);
|
|
1436
1438
|
changed.push(next);
|
|
1437
1439
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
+
const suffixed = mergePulledSuffixedListings(nextTickers, changed, state.config);
|
|
1441
|
+
if (changed.length === 0 && !suffixed.config) return;
|
|
1442
|
+
if (suffixed.config) dispatch({ type: "SET_CONFIG", config: suffixed.config });
|
|
1443
|
+
if (changed.length > 0) dispatch({ type: "SET_TICKERS", tickers: nextTickers });
|
|
1444
|
+
// The moved targets first, so a stop before the rows strands none on an emptied key.
|
|
1445
|
+
if (suffixed.config) await saveConfigImmediately(suffixed.config);
|
|
1440
1446
|
// Written one at a time, so an edit or a broker sync can replace a row
|
|
1441
1447
|
// before its turn. That copy is newer and its writer saves it; this one
|
|
1442
1448
|
// written over it would come back at launch as an edit and be pushed.
|
|
@@ -1447,6 +1453,32 @@ export const coreCollectionsSyncContributor: SyncContributor = {
|
|
|
1447
1453
|
},
|
|
1448
1454
|
};
|
|
1449
1455
|
|
|
1456
|
+
/**
|
|
1457
|
+
* An older build still files lots under a vendor's suffixed key (GARAN.IS)
|
|
1458
|
+
* and pushes them: pulled, they merge into the listing's row here as at
|
|
1459
|
+
* launch (`mergeSuffixedListings`), each lot once, so they never count in
|
|
1460
|
+
* both rows or go back out under the old key. The merged rows replace their
|
|
1461
|
+
* entries in `tickers` and `changed`; the config comes back with targets
|
|
1462
|
+
* moved, or null when none moved.
|
|
1463
|
+
*/
|
|
1464
|
+
function mergePulledSuffixedListings(
|
|
1465
|
+
tickers: Map<string, TickerRecord>,
|
|
1466
|
+
changed: TickerRecord[],
|
|
1467
|
+
config: AppConfig,
|
|
1468
|
+
): { config: AppConfig | null } {
|
|
1469
|
+
const merged = mergeSuffixedListings([...tickers.values()]);
|
|
1470
|
+
if (!merged) return { config: null };
|
|
1471
|
+
for (const row of merged.saves) {
|
|
1472
|
+
tickers.set(row.metadata.ticker, row);
|
|
1473
|
+
const at = changed.findIndex((record) => record.metadata.ticker === row.metadata.ticker);
|
|
1474
|
+
if (at >= 0) changed[at] = row;
|
|
1475
|
+
else changed.push(row);
|
|
1476
|
+
}
|
|
1477
|
+
for (const kept of merged.keptCustom) log.info("sync.suffixed-listing.custom-kept", kept);
|
|
1478
|
+
const next = moveTargetWeights(config, merged.moved);
|
|
1479
|
+
return { config: next === config ? null : next };
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1450
1482
|
export function createCoreSyncContributors(): SyncContributor[] {
|
|
1451
1483
|
return [coreConfigSyncContributor, coreCollectionsSyncContributor];
|
|
1452
1484
|
}
|
|
@@ -184,7 +184,8 @@ export function useTeamCollectionsSync(host: Omit<TeamCollectionsHost, "dispatch
|
|
|
184
184
|
const item = await apiClient.putTeamCollectionItem(collection.teamId, collection.id, {
|
|
185
185
|
symbol: entry.symbol,
|
|
186
186
|
exchange: ticker?.metadata.exchange ?? null,
|
|
187
|
-
|
|
187
|
+
// A holding's purchase date and the rate its cost was bought at go with its count.
|
|
188
|
+
...(collection.kind === "portfolio" ? { quantity: entry.quantity, ...entry.terms } : {}),
|
|
188
189
|
});
|
|
189
190
|
items.set(item.symbol, item);
|
|
190
191
|
} catch (error) {
|