gloomberb 0.18.4 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/patches/electrobun@1.18.1.patch +169 -5
- package/src/account/auth-model.ts +7 -3
- package/src/api-client/auth.ts +9 -4
- package/src/api-client/catalysts.ts +2 -1
- package/src/api-client/cot.ts +6 -2
- package/src/api-client/credit-documents.ts +6 -0
- package/src/api-client/data.ts +31 -6
- package/src/api-client/equity-screener.ts +24 -0
- package/src/api-client/fund-facts.ts +45 -4
- package/src/api-client/index.ts +171 -11
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/market-movers.ts +7 -0
- package/src/api-client/members.ts +13 -1
- package/src/api-client/perps.ts +43 -0
- package/src/api-client/request.ts +222 -41
- package/src/api-client/research-activity.ts +6 -12
- package/src/api-client/types.ts +74 -0
- 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 -5
- package/src/app/runtime/broker-import.ts +42 -27
- package/src/app/runtime/plugin-bindings.ts +73 -56
- package/src/architecture/core-builtin-allowlist.json +1 -1
- package/src/architecture/pane-tabs-allowlist.json +3 -0
- package/src/architecture/ttl-caches-allowlist.json +19 -0
- package/src/brokers/sync-broker-instance.ts +2 -8
- package/src/capabilities/chart-series.ts +1 -1
- package/src/cli/commands/crypto-hints.ts +40 -24
- package/src/cli/commands/fred-series.ts +5 -0
- package/src/cli/commands/keybindings.ts +23 -0
- package/src/cli/commands/market.ts +138 -46
- package/src/cli/commands/options-chain.ts +107 -10
- package/src/cli/commands/options-leaps.ts +9 -3
- package/src/cli/commands/overview.ts +176 -39
- package/src/cli/commands/search.ts +39 -3
- package/src/cli/commands/themes.ts +11 -2
- package/src/cli/commands/ticker.ts +57 -35
- package/src/cli/company-name-hint.ts +41 -0
- package/src/cli/earnings-calendar.ts +1 -1
- package/src/cli/errors.ts +10 -2
- package/src/cli/export-source.ts +29 -1
- package/src/cli/glossary.ts +73 -1
- package/src/cli/history-rows.ts +87 -16
- package/src/cli/index.ts +2 -0
- package/src/cli/known-gaps.ts +5 -2
- package/src/cli/listing-arg.ts +195 -56
- package/src/cli/output-file.ts +68 -0
- package/src/cli/pane-functions/capabilities.ts +3 -0
- package/src/cli/pane-functions/catalog.ts +80 -7
- package/src/cli/pane-functions/dom.ts +13 -3
- package/src/cli/pane-functions/freshness.ts +111 -16
- package/src/cli/pane-functions/function-help.ts +23 -13
- package/src/cli/pane-functions/headless.ts +56 -12
- package/src/cli/pane-functions/index.ts +58 -16
- package/src/cli/pane-functions/market-session.ts +81 -9
- package/src/cli/pane-functions/options.ts +19 -1
- package/src/cli/pane-functions/report.ts +5 -1
- package/src/cli/pane-functions/resolver.ts +35 -8
- package/src/cli/pane-functions/screenshot-assessment.ts +6 -4
- package/src/cli/pane-functions/screenshot-types.ts +5 -0
- package/src/cli/quote-answer.ts +30 -13
- package/src/cli/report-tables.ts +18 -7
- package/src/cli/restore-plugins.ts +13 -1
- package/src/cli/result.ts +57 -5
- package/src/cli/ticker-resolution.ts +3 -2
- package/src/components/chart/composite/composite-chart.tsx +26 -4
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +6 -0
- package/src/components/chart/composite/legend.tsx +45 -7
- package/src/components/chart/composite/levels.ts +2 -0
- package/src/components/chart/composite/panel-gestures.ts +33 -0
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +61 -5
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +24 -13
- package/src/components/chart/composite/scene.ts +46 -7
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- package/src/components/chart/composite/series-cues.ts +14 -0
- package/src/components/chart/composite/text-renderer.ts +9 -2
- package/src/components/chart/composite/tool-catalog.ts +36 -0
- package/src/components/chart/composite/tools.ts +203 -44
- package/src/components/chart/composite/types.ts +4 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +11 -4
- package/src/components/command-bar/assist/inventory.ts +2 -1
- package/src/components/command-bar/commands/direct/index.ts +28 -13
- package/src/components/command-bar/pane-templates/items.ts +3 -2
- package/src/components/command-bar/panel/prompt-binding.ts +0 -8
- package/src/components/command-bar/workflow/alert.ts +1 -1
- package/src/components/command-bar/workflow/collection-actions.ts +3 -3
- package/src/components/layout/header.tsx +26 -40
- package/src/components/layout/pane/footer/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +27 -0
- package/src/components/onboarding/onboarding-frame.tsx +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +4 -1
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +14 -9
- package/src/components/onboarding/wizard-broker-sync.ts +0 -1
- package/src/components/onboarding/wizard-positions.ts +3 -3
- package/src/components/ticker/list-table-view.tsx +4 -1
- package/src/components/ui/choice-dialog.tsx +23 -18
- package/src/components/ui/choice-groups.ts +18 -0
- package/src/components/ui/data-table/opentui/index.tsx +9 -7
- package/src/components/ui/data-table/opentui/model.ts +26 -1
- package/src/components/ui/data-table/types.ts +2 -0
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/list-view.tsx +8 -4
- package/src/components/ui/query-bar-keys.tsx +2 -0
- package/src/components/ui/query-bar.tsx +1 -0
- package/src/components/ui/select-button.tsx +5 -1
- package/src/components/ui/select-field.tsx +1 -0
- package/src/components/ui/table-layout.ts +8 -5
- package/src/core/app-runtime.ts +2 -0
- package/src/core/app-services.ts +2 -2
- package/src/core/state/app/layout.ts +2 -0
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- package/src/data/config/chart-settings.ts +1 -1
- package/src/data/json-ticker-repository.ts +17 -8
- package/src/data/saved-copies.ts +55 -16
- package/src/data/ticker-repository.ts +16 -9
- package/src/data/ticker-writes.ts +81 -0
- package/src/data/ttl-cache.ts +165 -0
- package/src/docs/snapshot.json +427 -216
- package/src/i18n/es.ts +19 -3
- package/src/i18n/ja.ts +19 -3
- package/src/i18n/ko.ts +19 -3
- package/src/i18n/zh-cn.ts +19 -3
- package/src/i18n/zh-tw.ts +19 -3
- 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 +2 -2
- package/src/market-data/fund-facts.ts +50 -0
- package/src/market-data/market/change-basis.ts +48 -7
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/format.ts +25 -0
- package/src/market-data/market/freshness.ts +2 -1
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/status.ts +16 -4
- package/src/market-data/options-alternatives.ts +141 -4
- package/src/market-data/quotes/contributions.ts +20 -2
- package/src/market-data/quotes/resolution.ts +3 -0
- package/src/market-data/selectors.ts +3 -0
- package/src/news/aggregator.ts +113 -9
- package/src/news/cloud-session.ts +21 -0
- package/src/news/hooks.ts +1 -0
- package/src/news/news-model.ts +1 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/notification-log.ts +6 -4
- package/src/plugins/builtin/alerts/alert-engine.ts +25 -2
- package/src/plugins/builtin/alerts/alert-log.ts +33 -0
- package/src/plugins/builtin/alerts/calendar-events.ts +57 -6
- package/src/plugins/builtin/alerts/cli-forms.ts +216 -0
- package/src/plugins/builtin/alerts/cli.ts +380 -82
- package/src/plugins/builtin/alerts/command.ts +31 -0
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- package/src/plugins/builtin/alerts/events-pane.tsx +19 -4
- package/src/plugins/builtin/alerts/fired-log.ts +113 -8
- package/src/plugins/builtin/alerts/format.ts +80 -4
- package/src/plugins/builtin/alerts/headless.ts +30 -7
- package/src/plugins/builtin/alerts/history-rows.ts +7 -3
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +135 -22
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +134 -0
- package/src/plugins/builtin/alerts/metric-data.ts +111 -0
- package/src/plugins/builtin/alerts/metric-model.ts +324 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +90 -39
- package/src/plugins/builtin/alerts/quotes.ts +6 -0
- package/src/plugins/builtin/alerts/storage.ts +37 -10
- package/src/plugins/builtin/alerts/types.ts +7 -0
- package/src/plugins/builtin/analytics/index.tsx +2 -1
- package/src/plugins/builtin/analytics/risk-client.ts +16 -5
- package/src/plugins/builtin/analytics/risk-fx.ts +70 -15
- package/src/plugins/builtin/analytics/risk-headless.ts +27 -0
- package/src/plugins/builtin/analytics/risk-model.ts +55 -9
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
- package/src/plugins/builtin/attention/index.tsx +2 -1
- package/src/plugins/builtin/attention/listing.ts +14 -0
- package/src/plugins/builtin/backtest/headless.ts +10 -5
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -3
- package/src/plugins/builtin/broker-manager/index.tsx +10 -5
- package/src/plugins/builtin/broker-manager/model.ts +6 -1
- package/src/plugins/builtin/broker-trading/controller.ts +22 -12
- package/src/plugins/builtin/broker-trading/index.tsx +13 -1
- package/src/plugins/builtin/broker-trading/order-feed.ts +9 -4
- package/src/plugins/builtin/broker-trading/pane.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +12 -4
- package/src/plugins/builtin/buildout/format.ts +38 -0
- package/src/plugins/builtin/buildout/model/normalizers.ts +36 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +4 -1
- package/src/plugins/builtin/buildout/table-model.ts +23 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +7 -3
- package/src/plugins/builtin/catalysts/model.ts +2 -1
- package/src/plugins/builtin/changelog/index.tsx +9 -6
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +6 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +1 -1
- package/src/plugins/builtin/chart-composer/cli-options.ts +9 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +12 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -2
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +7 -5
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +21 -4
- package/src/plugins/builtin/chart-composer/headless.ts +19 -3
- package/src/plugins/builtin/chart-composer/index.tsx +1 -1
- package/src/plugins/builtin/chart-composer/pane.tsx +53 -9
- 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/session-history.ts +18 -9
- package/src/plugins/builtin/chart-composer/settings.ts +27 -0
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +40 -26
- package/src/plugins/builtin/chat/content/command-suggestions.ts +93 -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 +50 -21
- 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 +271 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +8 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
- package/src/plugins/builtin/clinical-trials/model.ts +0 -9
- package/src/plugins/builtin/clinical-trials/pane.tsx +15 -22
- package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +8 -6
- package/src/plugins/builtin/cloud/askg/manifest.ts +2 -0
- package/src/plugins/builtin/cloud/plugin.tsx +1 -1
- package/src/plugins/builtin/company-attention/building.tsx +5 -1
- package/src/plugins/builtin/company-attention/client.ts +8 -9
- package/src/plugins/builtin/company-attention/evidence.ts +4 -1
- package/src/plugins/builtin/company-attention/moves.tsx +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +9 -2
- package/src/plugins/builtin/company-attention/signals.tsx +5 -1
- package/src/plugins/builtin/correlation/headless.ts +13 -5
- package/src/plugins/builtin/correlation/history.ts +22 -0
- package/src/plugins/builtin/cot/client.ts +22 -18
- package/src/plugins/builtin/cot/headless.ts +15 -10
- package/src/plugins/builtin/cot/model.ts +14 -1
- package/src/plugins/builtin/cot/pane.tsx +22 -14
- package/src/plugins/builtin/credit-boards/client.ts +6 -10
- package/src/plugins/builtin/credit-conditions/headless.ts +8 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +5 -1
- package/src/plugins/builtin/credit-conditions/model.ts +4 -0
- package/src/plugins/builtin/credit-conditions/series.ts +3 -1
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -2
- package/src/plugins/builtin/credit-documents/export.ts +173 -0
- package/src/plugins/builtin/credit-documents/headless.ts +7 -7
- package/src/plugins/builtin/credit-documents/model.ts +104 -14
- package/src/plugins/builtin/credit-documents/pane.tsx +12 -5
- package/src/plugins/builtin/custom-view/sources.ts +2 -0
- package/src/plugins/builtin/dividend-yield/client.ts +131 -23
- package/src/plugins/builtin/dividend-yield/headless.ts +44 -16
- package/src/plugins/builtin/dividend-yield/model.ts +8 -5
- package/src/plugins/builtin/dividend-yield/pane.tsx +38 -13
- package/src/plugins/builtin/dividend-yield/ranking.ts +37 -14
- package/src/plugins/builtin/dividend-yield/types.ts +20 -2
- package/src/plugins/builtin/dividend-yield/view.ts +30 -2
- package/src/plugins/builtin/docs/targets.ts +5 -1
- package/src/plugins/builtin/earnings/board-model.ts +16 -15
- package/src/plugins/builtin/earnings/board.tsx +62 -71
- package/src/plugins/builtin/earnings/headless.ts +40 -4
- package/src/plugins/builtin/earnings/scope.ts +31 -43
- package/src/plugins/builtin/earnings-calls/calendar.tsx +2 -2
- package/src/plugins/builtin/earnings-calls/format.ts +31 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +7 -2
- package/src/plugins/builtin/earnings-calls/model.ts +6 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +5 -4
- package/src/plugins/builtin/econ/calendar-model.ts +14 -9
- package/src/plugins/builtin/econ/figures.ts +72 -0
- package/src/plugins/builtin/econ/index.tsx +33 -3
- package/src/plugins/builtin/econ/types.ts +4 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +6 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +85 -35
- package/src/plugins/builtin/econ-statistics/stats.ts +37 -9
- package/src/plugins/builtin/econ-statistics/view.ts +3 -0
- package/src/plugins/builtin/equity-screener/categories.ts +179 -0
- package/src/plugins/builtin/equity-screener/client.ts +4 -2
- package/src/plugins/builtin/equity-screener/headless.ts +144 -13
- package/src/plugins/builtin/equity-screener/ideas.ts +49 -0
- package/src/plugins/builtin/equity-screener/model.ts +99 -10
- package/src/plugins/builtin/equity-screener/pane.tsx +70 -15
- package/src/plugins/builtin/exposure/charts.tsx +2 -2
- package/src/plugins/builtin/exposure/model.ts +13 -1
- package/src/plugins/builtin/exposure/pane.tsx +4 -4
- package/src/plugins/builtin/fixed-income/pane.tsx +2 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +2 -1
- package/src/plugins/builtin/futures/table.tsx +2 -2
- package/src/plugins/builtin/futures/use-board-terms.ts +42 -28
- package/src/plugins/builtin/futures/use-front-returns.ts +45 -28
- package/src/plugins/builtin/fx-matrix/client.ts +11 -3
- package/src/plugins/builtin/fx-matrix/headless.ts +6 -3
- package/src/plugins/builtin/fx-matrix/index.tsx +16 -4
- package/src/plugins/builtin/fx-matrix/live-legs.ts +54 -3
- package/src/plugins/builtin/gpu/headless.ts +8 -2
- package/src/plugins/builtin/help/function-index.ts +4 -1
- package/src/plugins/builtin/help/index.tsx +1 -0
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- package/src/plugins/builtin/help/shortcut-model.ts +1 -1
- package/src/plugins/builtin/holders/fund-holders.ts +51 -0
- package/src/plugins/builtin/holders/headless.ts +18 -1
- package/src/plugins/builtin/iv-history/client.ts +52 -11
- package/src/plugins/builtin/iv-history/format.ts +36 -23
- package/src/plugins/builtin/iv-history/headless.ts +36 -18
- package/src/plugins/builtin/iv-history/index.tsx +2 -2
- package/src/plugins/builtin/iv-history/model.ts +163 -27
- package/src/plugins/builtin/iv-history/pane.tsx +10 -6
- package/src/plugins/builtin/iv-history/screen-pane.tsx +22 -15
- package/src/plugins/builtin/iv-history/universe.ts +5 -1
- package/src/plugins/builtin/jobs/client.ts +25 -29
- package/src/plugins/builtin/kelly-sizer/model.ts +12 -8
- package/src/plugins/builtin/kelly-sizer/pane.tsx +9 -9
- package/src/plugins/builtin/kelly-sizer/sections.tsx +19 -10
- package/src/plugins/builtin/kelly-sizer/types.ts +10 -4
- package/src/plugins/builtin/macro-day/pane.tsx +7 -5
- package/src/plugins/builtin/macro-day/release-table.ts +2 -2
- package/src/plugins/builtin/market-heatmap/data.ts +8 -33
- package/src/plugins/builtin/market-movers/client.ts +25 -7
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- package/src/plugins/builtin/market-movers/headless.ts +32 -12
- package/src/plugins/builtin/market-movers/index.tsx +26 -14
- package/src/plugins/builtin/market-movers/min-float.ts +74 -0
- package/src/plugins/builtin/market-movers/model.ts +4 -1
- package/src/plugins/builtin/market-movers/screener.ts +14 -0
- package/src/plugins/builtin/market-movers/session-body.tsx +13 -8
- package/src/plugins/builtin/market-movers/session-table.ts +4 -3
- package/src/plugins/builtin/market-movers/table.ts +17 -5
- package/src/plugins/builtin/members/breadth-pane.tsx +82 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +20 -7
- 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 +25 -15
- package/src/plugins/builtin/news/index.tsx +1 -0
- package/src/plugins/builtin/news/wire/categories.ts +19 -3
- package/src/plugins/builtin/news/wire/industry-pane.tsx +1 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +31 -5
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +6 -1
- package/src/plugins/builtin/news/wire/news/table.tsx +2 -2
- package/src/plugins/builtin/openfda/client.ts +14 -2
- package/src/plugins/builtin/openfda/index.tsx +3 -2
- package/src/plugins/builtin/openfda/model.ts +9 -0
- package/src/plugins/builtin/openfda/pane.tsx +42 -6
- package/src/plugins/builtin/options/analytics.ts +54 -6
- package/src/plugins/builtin/options/enrichment.ts +17 -5
- 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 +6 -9
- package/src/plugins/builtin/options/types.ts +2 -0
- package/src/plugins/builtin/options/view.tsx +42 -12
- package/src/plugins/builtin/options-positioning/client.ts +30 -0
- package/src/plugins/builtin/options-positioning/headless.ts +74 -21
- package/src/plugins/builtin/options-positioning/index.tsx +4 -4
- package/src/plugins/builtin/options-positioning/model.ts +122 -14
- package/src/plugins/builtin/options-positioning/pane.tsx +87 -42
- package/src/plugins/builtin/options-scenario/client.ts +116 -47
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +142 -10
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +206 -55
- package/src/plugins/builtin/options-scenario/csp-screen.ts +63 -23
- package/src/plugins/builtin/options-scenario/csp.ts +8 -2
- package/src/plugins/builtin/options-scenario/index.tsx +9 -7
- package/src/plugins/builtin/options-scenario/strategy-screen.ts +532 -0
- package/src/plugins/builtin/pe-band/model.ts +12 -49
- package/src/plugins/builtin/perps/cascade-tabs.tsx +161 -0
- package/src/plugins/builtin/perps/cascade.ts +236 -0
- package/src/plugins/builtin/perps/client.ts +56 -2
- package/src/plugins/builtin/perps/freshness.ts +12 -10
- package/src/plugins/builtin/perps/headless.ts +65 -9
- package/src/plugins/builtin/perps/index.tsx +7 -5
- package/src/plugins/builtin/perps/live-rows.ts +10 -3
- package/src/plugins/builtin/perps/model.ts +18 -4
- package/src/plugins/builtin/perps/pane.tsx +32 -31
- package/src/plugins/builtin/perps/status-line.ts +25 -0
- package/src/plugins/builtin/plugin-module.ts +5 -1
- package/src/plugins/builtin/portfolio-list/cached-account.ts +3 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +2 -8
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +4 -4
- package/src/plugins/builtin/portfolio-list/cli/render.ts +12 -7
- package/src/plugins/builtin/portfolio-list/headless.ts +1 -1
- package/src/plugins/builtin/portfolio-list/pane/futures-front.ts +40 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +4 -1
- package/src/plugins/builtin/portfolio-list/pane/streaming.ts +5 -2
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +3 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +3 -1
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
- package/src/plugins/builtin/portfolio-list/table.tsx +11 -3
- package/src/plugins/builtin/primary-dealers/client.ts +13 -38
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- package/src/plugins/builtin/realized-vol/index.tsx +2 -2
- package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
- package/src/plugins/builtin/relative-rotation/client.ts +18 -4
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +2 -1
- package/src/plugins/builtin/relative-rotation/model.ts +16 -40
- package/src/plugins/builtin/relative-rotation/pane.tsx +3 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +3 -2
- package/src/plugins/builtin/research/event-model.ts +10 -8
- package/src/plugins/builtin/research/headless.ts +1 -1
- package/src/plugins/builtin/research/relative-valuation-headless.ts +5 -1
- package/src/plugins/builtin/research/relative-valuation-model.ts +31 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +11 -9
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -3
- package/src/plugins/builtin/reverse-dcf/model.ts +61 -6
- package/src/plugins/builtin/reverse-dcf/pane.tsx +7 -4
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/flow-model.ts +50 -4
- package/src/plugins/builtin/scanner/flow-pane.tsx +367 -65
- package/src/plugins/builtin/scanner/flow-session.ts +146 -0
- package/src/plugins/builtin/scanner/headless.ts +204 -35
- package/src/plugins/builtin/scanner/index.ts +40 -6
- 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 +138 -0
- package/src/plugins/builtin/scanner/live-model.ts +362 -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 +3 -2
- package/src/plugins/builtin/seasonality/headless.ts +10 -1
- package/src/plugins/builtin/sec/fund-facts-view.tsx +5 -2
- package/src/plugins/builtin/sec/fund-facts.ts +116 -34
- package/src/plugins/builtin/sec/headless.ts +2 -1
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +3 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +4 -3
- package/src/plugins/builtin/shared/earnings-calendar.ts +6 -2
- package/src/plugins/builtin/shared/earnings-report.ts +2 -2
- package/src/plugins/builtin/shared/job-posting.ts +1 -0
- package/src/plugins/builtin/shared/macro-releases.ts +65 -0
- package/src/plugins/builtin/shared/members-menu.tsx +3 -2
- package/src/plugins/builtin/shared/pro-lock-note.ts +12 -12
- package/src/plugins/builtin/shared/report-freshness.ts +3 -2
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/ticker-choice.tsx +2 -1
- package/src/plugins/builtin/shared/ticker-company.ts +77 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +10 -3
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -8
- package/src/plugins/builtin/shared/volatility/pricing.ts +26 -1
- package/src/plugins/builtin/shared/wall-view-lifecycle.ts +3 -1
- package/src/plugins/builtin/themes/headless.ts +6 -4
- package/src/plugins/builtin/themes/model.ts +17 -8
- package/src/plugins/builtin/themes/pane.tsx +7 -7
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +43 -18
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +3 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +62 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +83 -46
- package/src/plugins/builtin/ticker-detail/headless.ts +31 -16
- package/src/plugins/builtin/ticker-detail/overview/model.ts +1 -1
- package/src/plugins/builtin/ticker-detail/pane.tsx +3 -2
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +6 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/settings.ts +1 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -19
- package/src/plugins/builtin/treasury-daily/client.ts +41 -5
- package/src/plugins/builtin/treasury-daily/headless.ts +2 -2
- package/src/plugins/builtin/treasury-daily/index.tsx +1 -1
- package/src/plugins/builtin/treasury-daily/model.ts +50 -3
- package/src/plugins/builtin/treasury-daily/pane.tsx +81 -2
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +9 -17
- package/src/plugins/builtin/vol-surface/headless.ts +63 -14
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +22 -7
- package/src/plugins/builtin/vol-surface/pane.tsx +48 -9
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -2
- package/src/plugins/builtin/volatility/pane.tsx +4 -4
- 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/headless.ts +3 -3
- package/src/plugins/catalog-browser.ts +13 -8
- package/src/plugins/catalog-manifest.ts +2 -1
- package/src/plugins/marketplace/model.ts +18 -5
- package/src/portfolio/column-values.ts +5 -5
- package/src/portfolio/futures-positions.ts +6 -3
- package/src/portfolio/position-quantity.ts +15 -9
- package/src/public/__snapshots__/public-api.test.ts.snap +1 -0
- package/src/remote/resources.ts +2 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +2 -55
- package/src/renderers/browser/main.tsx +7 -57
- package/src/renderers/dom/data-table/row.tsx +26 -0
- package/src/renderers/dom/desktop/list-view.tsx +13 -10
- package/src/renderers/dom/desktop/query-bar.tsx +4 -2
- package/src/renderers/dom/desktop/select-field.tsx +4 -2
- package/src/renderers/dom/host/chart-surface.tsx +21 -0
- package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +29 -7
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +7 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -0
- 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 +173 -5
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +52 -0
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/index.ts +25 -1
- package/src/renderers/electrobun/shared/app-name.ts +30 -0
- package/src/renderers/electrobun/shared/protocol.ts +10 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +6 -0
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
- package/src/renderers/electrobun/view/main.tsx +24 -1
- package/src/renderers/electrobun/view/news-source.ts +3 -1
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +14 -7
- package/src/renderers/electrobun/view/view-ids.ts +85 -0
- package/src/renderers/opentui/start.tsx +5 -0
- package/src/renderers/opentui/toast-host.tsx +71 -43
- package/src/series/registry.ts +1 -0
- package/src/series/types.ts +6 -0
- package/src/series/validate.ts +1 -0
- package/src/sources/gloomberb-cloud/index.ts +1 -0
- package/src/sources/gloomberb-cloud/news.ts +47 -7
- package/src/sources/gloomberb-cloud/normalizers.ts +2 -0
- package/src/sources/provider-router/batches.ts +10 -2
- package/src/sources/provider-router/financial-routes.ts +3 -3
- package/src/sources/provider-router/financials.ts +15 -3
- package/src/sources/provider-router/history.ts +28 -7
- package/src/sources/provider-router/index.ts +149 -10
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/ticker-cleanup.ts +50 -0
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +70 -19
- package/src/sync/core-contributors.ts +90 -31
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/telemetry/stall-reports-dom.ts +38 -0
- package/src/telemetry/stall-reports-node.ts +75 -0
- package/src/telemetry/stall-reports.ts +214 -0
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/preload.ts +14 -0
- package/src/theme/colors.ts +8 -0
- package/src/theme/themes.ts +10 -0
- package/src/tickers/company-name.ts +103 -3
- package/src/tickers/listing-venues.ts +38 -3
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/index.ts +36 -7
- package/src/tickers/search/ranking.ts +10 -1
- package/src/tickers/search/types.ts +5 -0
- package/src/tickers/terminal-codes.ts +19 -0
- package/src/time-series/alignment.ts +1 -1
- package/src/time-series/base-series.ts +13 -5
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +18 -4
- package/src/time-series/field-catalog.ts +2 -4
- package/src/time-series/filed-trailing-eps.ts +197 -0
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +198 -7
- package/src/time-series/hooks.ts +1 -0
- package/src/time-series/ice-credit.ts +3 -0
- package/src/time-series/price-comparison.ts +30 -2
- package/src/time-series/price-units.ts +72 -2
- package/src/time-series/resolve-context.ts +7 -1
- package/src/time-series/resolve.ts +116 -15
- package/src/time-series/series-presentation.ts +40 -6
- package/src/time-series/session-bar.ts +11 -0
- package/src/time-series/spec.ts +5 -3
- package/src/time-series/studies.ts +278 -74
- package/src/time-series/total-return.ts +160 -0
- package/src/time-series/transforms.ts +3 -3
- package/src/time-series/types.ts +27 -1
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/data-provider.ts +9 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/financials.ts +73 -2
- package/src/types/headless.ts +61 -5
- package/src/types/instrument.ts +3 -0
- package/src/types/news-source.ts +1 -0
- package/src/types/plugin.ts +10 -1
- package/src/ui/host.tsx +3 -0
- package/src/updater/command-names.ts +12 -7
- package/src/updater/failure.ts +4 -1
- package/src/utils/cli-output.ts +42 -1
- package/src/utils/crypto-pair.ts +44 -0
- package/src/utils/financial-statements.ts +6 -1
- package/src/utils/forward-dividend.ts +2 -0
- package/src/utils/fundamentals.ts +24 -3
- package/src/utils/fx-market-hours.ts +26 -3
- package/src/utils/main-thread-stall.ts +35 -2
- package/src/utils/market-capitalization.ts +24 -1
- package/src/utils/network-failure.ts +9 -6
- package/src/utils/option-expiry.ts +48 -1
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-history.ts +12 -1
- package/src/utils/shell-word.ts +8 -0
- package/src/utils/trailing-dividend.ts +53 -4
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +0 -17
- package/src/renderers/browser/first-screen.ts +0 -193
package/src/i18n/es.ts
CHANGED
|
@@ -1115,6 +1115,19 @@ export const es: Record<string, string> = {
|
|
|
1115
1115
|
"{symbol}'s figures are not collected yet; the next read stores them.": "Aún no se han recopilado las cifras de {symbol}; la próxima lectura las guardará.",
|
|
1116
1116
|
"{symbol} files with the SEC as a trust or pool, not as an open-end fund, and its sponsor's site is not one Gloom reads.": "{symbol} está registrado ante la SEC como fideicomiso o pool, no como fondo abierto, y Gloom no lee el sitio de su patrocinador.",
|
|
1117
1117
|
"No figures for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets list none for it yet.": "No hay cifras para {symbol}: Gloom no lee el sitio de su patrocinador y los conjuntos de datos de folletos y N-PORT de la SEC aún no incluyen ninguna.",
|
|
1118
|
+
"est. {range}": "est. {range}",
|
|
1119
|
+
"Shares outstanding": "Acciones en circulación",
|
|
1120
|
+
"1M flows": "Flujos 1M",
|
|
1121
|
+
"Structure": "Estructura",
|
|
1122
|
+
"Closed-end fund": "Fondo cerrado",
|
|
1123
|
+
"BDC": "BDC",
|
|
1124
|
+
"est.": "est.",
|
|
1125
|
+
"{count} shares": "{count} acciones",
|
|
1126
|
+
"No figures for {symbol}: it files with the SEC as a closed-end fund or BDC, but neither the filings Gloom reads nor its sponsor's site state any for it yet.": "No hay cifras para {symbol}: está registrado ante la SEC como fondo cerrado o BDC, pero ni las presentaciones que lee Gloom ni el sitio de su patrocinador indican ninguna todavía.",
|
|
1127
|
+
"No NAV for {symbol}: {publisher} publishes figures for it, but no NAV.": "No hay valor liquidativo para {symbol}: {publisher} publica cifras del fondo, pero no su valor liquidativo.",
|
|
1128
|
+
"No NAV for {symbol}: its SEC filings state net assets but no NAV per share, and its sponsor's NAV is not one Gloom reads.": "No hay valor liquidativo para {symbol}: sus presentaciones ante la SEC indican el patrimonio neto pero no el valor liquidativo por acción, y Gloom no lee el de su patrocinador.",
|
|
1129
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and a trust files no NAV with the SEC's fund data sets.": "No hay valor liquidativo para {symbol}: Gloom no lee el sitio de su patrocinador, y un fideicomiso no presenta valor liquidativo en los conjuntos de datos de fondos de la SEC.",
|
|
1130
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets state no NAV.": "No hay valor liquidativo para {symbol}: Gloom no lee el sitio de su patrocinador, y los conjuntos de datos de folletos y N-PORT de la SEC no indican ninguno.",
|
|
1118
1131
|
"No figures for {symbol}: it lists as a fund, but the SEC's lists do not name it yet and its sponsor's site is not one Gloom reads.": "No hay cifras para {symbol}: cotiza como fondo, pero las listas de la SEC aún no lo incluyen y Gloom no lee el sitio de su patrocinador.",
|
|
1119
1132
|
"No fund facts for {symbol}: it is not on the SEC's lists of US-listed funds.": "No hay datos del fondo para {symbol}: no figura en las listas de fondos cotizados en EE. UU. de la SEC.",
|
|
1120
1133
|
"No fund facts for {symbol} yet.": "Aún no hay datos del fondo para {symbol}.",
|
|
@@ -1345,7 +1358,7 @@ export const es: Record<string, string> = {
|
|
|
1345
1358
|
"Free: 12h delayed. Pro: real-time.": "Gratis: 12 h de retraso. Pro: tiempo real.",
|
|
1346
1359
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1347
1360
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1348
|
-
"
|
|
1361
|
+
"GLOOM SETUP": "CONFIGURACIÓN DE GLOOM",
|
|
1349
1362
|
"Gloom Cloud is connected": "Gloom Cloud está conectado",
|
|
1350
1363
|
"How do you want to start?": "¿Cómo quieres empezar?",
|
|
1351
1364
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "Se importaron {count} posiciones de {broker}. Tu espacio de trabajo está listo para explorar.",
|
|
@@ -1478,8 +1491,11 @@ export const es: Record<string, string> = {
|
|
|
1478
1491
|
"Answers cite filings, calls and news.": "Las respuestas citan informes, llamadas y noticias.",
|
|
1479
1492
|
"{ticker} is open. {shortcut}, then AP, adds more.": "{ticker} está abierto. {shortcut} y luego AP añade más.",
|
|
1480
1493
|
"Later: {shortcut}, then AP.": "Más tarde: {shortcut} y luego AP.",
|
|
1481
|
-
"Enter: next field, then add
|
|
1482
|
-
"
|
|
1494
|
+
"Enter: next field, then add": "Enter: siguiente campo, luego añade",
|
|
1495
|
+
"Add one ticker to continue": "Añade un ticker para continuar",
|
|
1496
|
+
"Add one ticker to continue.": "Añade un ticker para continuar.",
|
|
1497
|
+
"Esc, then Enter: continue": "Esc y luego Enter: continuar",
|
|
1498
|
+
"Enter to add a ticker": "Enter para añadir un ticker",
|
|
1483
1499
|
" already added": " ya añadido",
|
|
1484
1500
|
"Credentials stay on this device.": "Las credenciales se quedan en este dispositivo.",
|
|
1485
1501
|
"Ask Gloom": "Ask Gloom",
|
package/src/i18n/ja.ts
CHANGED
|
@@ -1129,6 +1129,19 @@ export const ja: Record<string, string> = {
|
|
|
1129
1129
|
"{symbol}'s figures are not collected yet; the next read stores them.": "{symbol} の数値はまだ収集していません。次回の読み込みで保存されます。",
|
|
1130
1130
|
"{symbol} files with the SEC as a trust or pool, not as an open-end fund, and its sponsor's site is not one Gloom reads.": "{symbol} はオープンエンド型ファンドではなく、信託またはプールとして SEC に届け出ており、Gloom はそのスポンサーのサイトを読み込んでいません。",
|
|
1131
1131
|
"No figures for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets list none for it yet.": "{symbol} の数値はありません。Gloom はスポンサーのサイトを読み込んでおらず、SEC の目論見書データセットと N-PORT データセットにもまだ掲載がありません。",
|
|
1132
|
+
"est. {range}": "推定 {range}",
|
|
1133
|
+
"Shares outstanding": "発行済口数",
|
|
1134
|
+
"1M flows": "1か月の資金流出入",
|
|
1135
|
+
"Structure": "形態",
|
|
1136
|
+
"Closed-end fund": "クローズドエンド型ファンド",
|
|
1137
|
+
"BDC": "BDC",
|
|
1138
|
+
"est.": "推定",
|
|
1139
|
+
"{count} shares": "{count} 口",
|
|
1140
|
+
"No figures for {symbol}: it files with the SEC as a closed-end fund or BDC, but neither the filings Gloom reads nor its sponsor's site state any for it yet.": "{symbol} の数値はありません。SEC にクローズドエンド型ファンドまたは BDC として届け出ていますが、Gloom が読み込む提出書類にもスポンサーのサイトにもまだ掲載がありません。",
|
|
1141
|
+
"No NAV for {symbol}: {publisher} publishes figures for it, but no NAV.": "{symbol} の基準価額はありません。{publisher} は数値を公表していますが、基準価額は公表していません。",
|
|
1142
|
+
"No NAV for {symbol}: its SEC filings state net assets but no NAV per share, and its sponsor's NAV is not one Gloom reads.": "{symbol} の基準価額はありません。SEC への提出書類には純資産が記載されていますが 1 株あたり基準価額はなく、Gloom はスポンサーの基準価額を読み込んでいません。",
|
|
1143
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and a trust files no NAV with the SEC's fund data sets.": "{symbol} の基準価額はありません。Gloom はスポンサーのサイトを読み込んでおらず、信託は SEC のファンドデータセットに基準価額を届け出ていません。",
|
|
1144
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets state no NAV.": "{symbol} の基準価額はありません。Gloom はスポンサーのサイトを読み込んでおらず、SEC の目論見書データセットと N-PORT データセットにも基準価額は記載されていません。",
|
|
1132
1145
|
"No figures for {symbol}: it lists as a fund, but the SEC's lists do not name it yet and its sponsor's site is not one Gloom reads.": "{symbol} の数値はありません。ファンドとして上場していますが、SEC のリストにはまだ掲載されておらず、Gloom はスポンサーのサイトを読み込んでいません。",
|
|
1133
1146
|
"No fund facts for {symbol}: it is not on the SEC's lists of US-listed funds.": "{symbol} のファンド概要はありません: SEC の米国上場ファンドの一覧に含まれていません。",
|
|
1134
1147
|
"No fund facts for {symbol} yet.": "{symbol} のファンド概要はまだありません。",
|
|
@@ -1333,7 +1346,7 @@ export const ja: Record<string, string> = {
|
|
|
1333
1346
|
"Free: 12h delayed. Pro: real-time.": "無料:12時間遅延。Pro:リアルタイム。",
|
|
1334
1347
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1335
1348
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1336
|
-
"
|
|
1349
|
+
"GLOOM SETUP": "GLOOM セットアップ",
|
|
1337
1350
|
"Gloom Cloud is connected": "Gloom Cloudに接続しました",
|
|
1338
1351
|
"How do you want to start?": "どの方法で始めますか?",
|
|
1339
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "{broker}から{count}件のポジションをインポートしました。ワークスペースの準備が整いました。",
|
|
@@ -1474,8 +1487,11 @@ export const ja: Record<string, string> = {
|
|
|
1474
1487
|
"Answers cite filings, calls and news.": "回答は開示、決算説明会、ニュースを引用します。",
|
|
1475
1488
|
"{ticker} is open. {shortcut}, then AP, adds more.": "{ticker} を開きました。{shortcut} のあと AP で追加できます。",
|
|
1476
1489
|
"Later: {shortcut}, then AP.": "後で: {shortcut} のあと AP。",
|
|
1477
|
-
"Enter: next field, then add
|
|
1478
|
-
"
|
|
1490
|
+
"Enter: next field, then add": "Enter: 次の項目へ、最後に追加",
|
|
1491
|
+
"Add one ticker to continue": "ティッカーを1つ追加すると続行できます",
|
|
1492
|
+
"Add one ticker to continue.": "ティッカーを1つ追加すると続行できます。",
|
|
1493
|
+
"Esc, then Enter: continue": "Esc のあと Enter: 続行",
|
|
1494
|
+
"Enter to add a ticker": "Enter でティッカーを追加",
|
|
1479
1495
|
" already added": " 追加済み",
|
|
1480
1496
|
"Credentials stay on this device.": "認証情報はこの端末にのみ保存されます。",
|
|
1481
1497
|
"Ask Gloom": "Ask Gloom",
|
package/src/i18n/ko.ts
CHANGED
|
@@ -1127,6 +1127,19 @@ export const ko: Record<string, string> = {
|
|
|
1127
1127
|
"{symbol}'s figures are not collected yet; the next read stores them.": "{symbol}의 수치는 아직 수집되지 않았습니다. 다음 읽기에서 저장됩니다.",
|
|
1128
1128
|
"{symbol} files with the SEC as a trust or pool, not as an open-end fund, and its sponsor's site is not one Gloom reads.": "{symbol}은(는) SEC에 개방형 펀드가 아닌 신탁 또는 풀로 등록되어 있으며, Gloom은 스폰서의 사이트를 읽지 않습니다.",
|
|
1129
1129
|
"No figures for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets list none for it yet.": "{symbol}의 수치가 없습니다. Gloom은 스폰서의 사이트를 읽지 않으며, SEC의 투자설명서 및 N-PORT 데이터 세트에도 아직 없습니다.",
|
|
1130
|
+
"est. {range}": "추정 {range}",
|
|
1131
|
+
"Shares outstanding": "발행 주식 수",
|
|
1132
|
+
"1M flows": "1개월 자금 유출입",
|
|
1133
|
+
"Structure": "구조",
|
|
1134
|
+
"Closed-end fund": "폐쇄형 펀드",
|
|
1135
|
+
"BDC": "BDC",
|
|
1136
|
+
"est.": "추정",
|
|
1137
|
+
"{count} shares": "{count}주",
|
|
1138
|
+
"No figures for {symbol}: it files with the SEC as a closed-end fund or BDC, but neither the filings Gloom reads nor its sponsor's site state any for it yet.": "{symbol}의 수치가 없습니다. SEC에 폐쇄형 펀드 또는 BDC로 신고하지만, Gloom이 읽는 공시와 스폰서 사이트 어디에도 아직 수치가 없습니다.",
|
|
1139
|
+
"No NAV for {symbol}: {publisher} publishes figures for it, but no NAV.": "{symbol}의 순자산가치가 없습니다. {publisher}는 수치를 공시하지만 순자산가치는 공시하지 않습니다.",
|
|
1140
|
+
"No NAV for {symbol}: its SEC filings state net assets but no NAV per share, and its sponsor's NAV is not one Gloom reads.": "{symbol}의 순자산가치가 없습니다. SEC 공시에는 순자산은 있지만 주당 순자산가치는 없으며, Gloom은 스폰서의 순자산가치를 읽지 않습니다.",
|
|
1141
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and a trust files no NAV with the SEC's fund data sets.": "{symbol}의 순자산가치가 없습니다. Gloom은 스폰서의 사이트를 읽지 않으며, 신탁은 SEC 펀드 데이터 세트에 순자산가치를 신고하지 않습니다.",
|
|
1142
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets state no NAV.": "{symbol}의 순자산가치가 없습니다. Gloom은 스폰서의 사이트를 읽지 않으며, SEC의 투자설명서 및 N-PORT 데이터 세트에도 순자산가치가 없습니다.",
|
|
1130
1143
|
"No figures for {symbol}: it lists as a fund, but the SEC's lists do not name it yet and its sponsor's site is not one Gloom reads.": "{symbol}의 수치가 없습니다. 펀드로 상장되어 있지만 SEC 목록에는 아직 없으며, Gloom은 스폰서의 사이트를 읽지 않습니다.",
|
|
1131
1144
|
"No fund facts for {symbol}: it is not on the SEC's lists of US-listed funds.": "{symbol}의 펀드 정보가 없습니다: SEC의 미국 상장 펀드 목록에 없습니다.",
|
|
1132
1145
|
"No fund facts for {symbol} yet.": "{symbol}의 펀드 정보가 아직 없습니다.",
|
|
@@ -1331,7 +1344,7 @@ export const ko: Record<string, string> = {
|
|
|
1331
1344
|
"Free: 12h delayed. Pro: real-time.": "무료: 12시간 지연. Pro: 실시간.",
|
|
1332
1345
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1333
1346
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1334
|
-
"
|
|
1347
|
+
"GLOOM SETUP": "GLOOM 설정",
|
|
1335
1348
|
"Gloom Cloud is connected": "Gloom Cloud가 연결되었습니다",
|
|
1336
1349
|
"How do you want to start?": "어떻게 시작하시겠어요?",
|
|
1337
1350
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "{broker}에서 {count}개 보유 종목을 가져왔습니다. 이제 작업 공간을 둘러볼 수 있습니다.",
|
|
@@ -1472,8 +1485,11 @@ export const ko: Record<string, string> = {
|
|
|
1472
1485
|
"Answers cite filings, calls and news.": "답변은 공시, 실적 발표, 뉴스를 인용합니다.",
|
|
1473
1486
|
"{ticker} is open. {shortcut}, then AP, adds more.": "{ticker}이(가) 열렸습니다. {shortcut} 다음 AP로 더 추가하세요.",
|
|
1474
1487
|
"Later: {shortcut}, then AP.": "나중에: {shortcut} 다음 AP.",
|
|
1475
|
-
"Enter: next field, then add
|
|
1476
|
-
"
|
|
1488
|
+
"Enter: next field, then add": "Enter: 다음 필드, 마지막에 추가",
|
|
1489
|
+
"Add one ticker to continue": "티커를 하나 추가하면 계속할 수 있습니다",
|
|
1490
|
+
"Add one ticker to continue.": "티커를 하나 추가하면 계속할 수 있습니다.",
|
|
1491
|
+
"Esc, then Enter: continue": "Esc 후 Enter: 계속",
|
|
1492
|
+
"Enter to add a ticker": "Enter로 티커 추가",
|
|
1477
1493
|
" already added": " 이미 추가됨",
|
|
1478
1494
|
"Credentials stay on this device.": "자격 증명은 이 기기에만 저장됩니다.",
|
|
1479
1495
|
"Ask Gloom": "Ask Gloom",
|
package/src/i18n/zh-cn.ts
CHANGED
|
@@ -1129,6 +1129,19 @@ export const zhCN: Record<string, string> = {
|
|
|
1129
1129
|
"{symbol}'s figures are not collected yet; the next read stores them.": "尚未采集 {symbol} 的数据;下次读取时会保存。",
|
|
1130
1130
|
"{symbol} files with the SEC as a trust or pool, not as an open-end fund, and its sponsor's site is not one Gloom reads.": "{symbol} 在 SEC 登记为信托或资金池,而非开放式基金,且 Gloom 不读取其发起人的网站。",
|
|
1131
1131
|
"No figures for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets list none for it yet.": "暂无 {symbol} 的数据:Gloom 不读取其发起人的网站,SEC 的招募说明书和 N-PORT 数据集中也尚未列出。",
|
|
1132
|
+
"est. {range}": "估计 {range}",
|
|
1133
|
+
"Shares outstanding": "流通份额",
|
|
1134
|
+
"1M flows": "1个月资金流",
|
|
1135
|
+
"Structure": "结构",
|
|
1136
|
+
"Closed-end fund": "封闭式基金",
|
|
1137
|
+
"BDC": "BDC",
|
|
1138
|
+
"est.": "估计",
|
|
1139
|
+
"{count} shares": "{count} 份",
|
|
1140
|
+
"No figures for {symbol}: it files with the SEC as a closed-end fund or BDC, but neither the filings Gloom reads nor its sponsor's site state any for it yet.": "暂无 {symbol} 的数据:它以封闭式基金或 BDC 身份向 SEC 申报,但 Gloom 读取的申报文件和其发起人的网站均尚未列出任何数据。",
|
|
1141
|
+
"No NAV for {symbol}: {publisher} publishes figures for it, but no NAV.": "暂无 {symbol} 的资产净值:{publisher} 公布了其数据,但未公布资产净值。",
|
|
1142
|
+
"No NAV for {symbol}: its SEC filings state net assets but no NAV per share, and its sponsor's NAV is not one Gloom reads.": "暂无 {symbol} 的资产净值:其 SEC 申报文件列出了净资产,但未列出每股资产净值,Gloom 也不读取其发起人公布的资产净值。",
|
|
1143
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and a trust files no NAV with the SEC's fund data sets.": "暂无 {symbol} 的资产净值:Gloom 不读取其发起人的网站,信托也不在 SEC 的基金数据集中申报资产净值。",
|
|
1144
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets state no NAV.": "暂无 {symbol} 的资产净值:Gloom 不读取其发起人的网站,SEC 的招募说明书和 N-PORT 数据集中也没有资产净值。",
|
|
1132
1145
|
"No figures for {symbol}: it lists as a fund, but the SEC's lists do not name it yet and its sponsor's site is not one Gloom reads.": "暂无 {symbol} 的数据:它以基金身份上市,但 SEC 的名单尚未收录,且 Gloom 不读取其发起人的网站。",
|
|
1133
1146
|
"No fund facts for {symbol}: it is not on the SEC's lists of US-listed funds.": "{symbol} 没有基金概况:它不在 SEC 的美国上市基金名单中。",
|
|
1134
1147
|
"No fund facts for {symbol} yet.": "{symbol} 暂无基金概况。",
|
|
@@ -1333,7 +1346,7 @@ export const zhCN: Record<string, string> = {
|
|
|
1333
1346
|
"Free: 12h delayed. Pro: real-time.": "免费:延迟 12 小时。Pro:实时。",
|
|
1334
1347
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1335
1348
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1336
|
-
"
|
|
1349
|
+
"GLOOM SETUP": "GLOOM 设置",
|
|
1337
1350
|
"Gloom Cloud is connected": "Gloom Cloud 已连接",
|
|
1338
1351
|
"How do you want to start?": "你想如何开始?",
|
|
1339
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "已从 {broker} 导入 {count} 个持仓。你的工作区已准备好,可以开始探索。",
|
|
@@ -1474,8 +1487,11 @@ export const zhCN: Record<string, string> = {
|
|
|
1474
1487
|
"Answers cite filings, calls and news.": "回答引用公告、电话会议和新闻。",
|
|
1475
1488
|
"{ticker} is open. {shortcut}, then AP, adds more.": "{ticker} 已打开。{shortcut} 然后输入 AP 可添加更多。",
|
|
1476
1489
|
"Later: {shortcut}, then AP.": "之后:{shortcut},然后输入 AP。",
|
|
1477
|
-
"Enter: next field, then add
|
|
1478
|
-
"
|
|
1490
|
+
"Enter: next field, then add": "Enter:下一字段,最后添加",
|
|
1491
|
+
"Add one ticker to continue": "添加一个代码即可继续",
|
|
1492
|
+
"Add one ticker to continue.": "添加一个代码即可继续。",
|
|
1493
|
+
"Esc, then Enter: continue": "Esc,然后 Enter:继续",
|
|
1494
|
+
"Enter to add a ticker": "按 Enter 添加代码",
|
|
1479
1495
|
" already added": " 已添加",
|
|
1480
1496
|
"Credentials stay on this device.": "凭据仅保存在此设备上。",
|
|
1481
1497
|
"Ask Gloom": "Ask Gloom",
|
package/src/i18n/zh-tw.ts
CHANGED
|
@@ -1129,6 +1129,19 @@ export const zhTW: Record<string, string> = {
|
|
|
1129
1129
|
"{symbol}'s figures are not collected yet; the next read stores them.": "尚未蒐集 {symbol} 的數據;下次讀取時會儲存。",
|
|
1130
1130
|
"{symbol} files with the SEC as a trust or pool, not as an open-end fund, and its sponsor's site is not one Gloom reads.": "{symbol} 在 SEC 登記為信託或資金池,而非開放式基金,且 Gloom 不讀取其發起人的網站。",
|
|
1131
1131
|
"No figures for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets list none for it yet.": "暫無 {symbol} 的數據:Gloom 不讀取其發起人的網站,SEC 的公開說明書與 N-PORT 資料集中也尚未列出。",
|
|
1132
|
+
"est. {range}": "估計 {range}",
|
|
1133
|
+
"Shares outstanding": "流通單位數",
|
|
1134
|
+
"1M flows": "1個月資金流",
|
|
1135
|
+
"Structure": "結構",
|
|
1136
|
+
"Closed-end fund": "封閉式基金",
|
|
1137
|
+
"BDC": "BDC",
|
|
1138
|
+
"est.": "估計",
|
|
1139
|
+
"{count} shares": "{count} 單位",
|
|
1140
|
+
"No figures for {symbol}: it files with the SEC as a closed-end fund or BDC, but neither the filings Gloom reads nor its sponsor's site state any for it yet.": "暫無 {symbol} 的數據:它以封閉式基金或 BDC 身分向 SEC 申報,但 Gloom 讀取的申報文件與其發起人的網站均尚未列出任何數據。",
|
|
1141
|
+
"No NAV for {symbol}: {publisher} publishes figures for it, but no NAV.": "暫無 {symbol} 的資產淨值:{publisher} 公布了其數據,但未公布資產淨值。",
|
|
1142
|
+
"No NAV for {symbol}: its SEC filings state net assets but no NAV per share, and its sponsor's NAV is not one Gloom reads.": "暫無 {symbol} 的資產淨值:其 SEC 申報文件列出了淨資產,但未列出每股資產淨值,Gloom 也不讀取其發起人公布的資產淨值。",
|
|
1143
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and a trust files no NAV with the SEC's fund data sets.": "暫無 {symbol} 的資產淨值:Gloom 不讀取其發起人的網站,信託也不在 SEC 的基金資料集中申報資產淨值。",
|
|
1144
|
+
"No NAV for {symbol}: its sponsor's site is not one Gloom reads, and the SEC's prospectus and N-PORT data sets state no NAV.": "暫無 {symbol} 的資產淨值:Gloom 不讀取其發起人的網站,SEC 的公開說明書與 N-PORT 資料集中也沒有資產淨值。",
|
|
1132
1145
|
"No figures for {symbol}: it lists as a fund, but the SEC's lists do not name it yet and its sponsor's site is not one Gloom reads.": "暫無 {symbol} 的數據:它以基金身分上市,但 SEC 的名單尚未收錄,且 Gloom 不讀取其發起人的網站。",
|
|
1133
1146
|
"No fund facts for {symbol}: it is not on the SEC's lists of US-listed funds.": "{symbol} 沒有基金概況:它不在 SEC 的美國上市基金名單中。",
|
|
1134
1147
|
"No fund facts for {symbol} yet.": "{symbol} 暫無基金概況。",
|
|
@@ -1333,7 +1346,7 @@ export const zhTW: Record<string, string> = {
|
|
|
1333
1346
|
"Free: 12h delayed. Pro: real-time.": "免費:延遲 12 小時。Pro:即時。",
|
|
1334
1347
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1335
1348
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1336
|
-
"
|
|
1349
|
+
"GLOOM SETUP": "GLOOM 設定",
|
|
1337
1350
|
"Gloom Cloud is connected": "Gloom Cloud 已連線",
|
|
1338
1351
|
"How do you want to start?": "你想如何開始?",
|
|
1339
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "已從 {broker} 匯入 {count} 個部位。你的工作區已準備好,可以開始探索。",
|
|
@@ -1474,8 +1487,11 @@ export const zhTW: Record<string, string> = {
|
|
|
1474
1487
|
"Answers cite filings, calls and news.": "回答引用申報、法說會和新聞。",
|
|
1475
1488
|
"{ticker} is open. {shortcut}, then AP, adds more.": "{ticker} 已開啟。{shortcut} 然後輸入 AP 可新增更多。",
|
|
1476
1489
|
"Later: {shortcut}, then AP.": "之後:{shortcut},然後輸入 AP。",
|
|
1477
|
-
"Enter: next field, then add
|
|
1478
|
-
"
|
|
1490
|
+
"Enter: next field, then add": "Enter:下一欄位,最後新增",
|
|
1491
|
+
"Add one ticker to continue": "新增一個代號即可繼續",
|
|
1492
|
+
"Add one ticker to continue.": "新增一個代號即可繼續。",
|
|
1493
|
+
"Esc, then Enter: continue": "Esc,然後 Enter:繼續",
|
|
1494
|
+
"Enter to add a ticker": "按 Enter 新增代號",
|
|
1479
1495
|
" already added": " 已新增",
|
|
1480
1496
|
"Credentials stay on this device.": "憑證僅保存在此裝置上。",
|
|
1481
1497
|
"Ask Gloom": "Ask Gloom",
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
toMarketDataContext,
|
|
12
12
|
} from "../selectors";
|
|
13
13
|
import { traceMarketData } from "../trace";
|
|
14
|
+
import { savedCopyAt } from "../../data/saved-copies";
|
|
14
15
|
import { createBaselineChartRequest } from "./chart";
|
|
15
16
|
import {
|
|
16
17
|
EXPECTED_EMPTY,
|
|
@@ -94,8 +95,10 @@ function storeFinancialsSnapshot(
|
|
|
94
95
|
if (normalized.quote) {
|
|
95
96
|
const quoteKey = buildQuoteKey(instrument);
|
|
96
97
|
const currentQuoteEntry = stores.quoteStore.get(quoteKey);
|
|
97
|
-
// A tick streamed while the snapshot was in flight is newer than its quote.
|
|
98
|
-
|
|
98
|
+
// A tick streamed while the snapshot was in flight is newer than its quote. And a snapshot read
|
|
99
|
+
// from the cache carries the quote saved with it: no newer than a saved copy the quote's own
|
|
100
|
+
// failed refresh answered with, it is that copy, and the quote keeps saying so.
|
|
101
|
+
if (!heldQuoteSupersedes(currentQuoteEntry, normalized.quote) && !repeatsHeldSavedCopy(currentQuoteEntry, normalized.quote)) {
|
|
99
102
|
stores.quoteStore.set(
|
|
100
103
|
quoteKey,
|
|
101
104
|
readyEntry(currentQuoteEntry, normalized.quote, normalized.quote.providerId ?? source, attempts),
|
|
@@ -112,6 +115,11 @@ function storeFinancialsSnapshot(
|
|
|
112
115
|
return entry;
|
|
113
116
|
}
|
|
114
117
|
|
|
118
|
+
function repeatsHeldSavedCopy(current: QueryEntry<Quote>, incoming: Quote): boolean {
|
|
119
|
+
const held = current.data ?? current.lastGoodData;
|
|
120
|
+
return !!held && savedCopyAt(held) != null && savedCopyAt(incoming) == null && !(incoming.lastUpdated > held.lastUpdated);
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
/** Fresh data, or a failure too recent to ask about again unless forced. */
|
|
116
124
|
function canReuseSnapshotEntry(entry: QueryEntry<TickerFinancials>): boolean {
|
|
117
125
|
return hasFreshEntryData(entry, SNAPSHOT_CACHE_TTL_MS) || hasRecentFailedAttempt(entry, SNAPSHOT_FAILURE_RETRY_MS);
|
|
@@ -82,6 +82,7 @@ import {
|
|
|
82
82
|
type QuoteSubscriptionHandle,
|
|
83
83
|
type QuoteSubscriptionRequest,
|
|
84
84
|
} from "./quotes";
|
|
85
|
+
import { withSavedCopyMarkOf } from "../../data/saved-copies";
|
|
85
86
|
|
|
86
87
|
/** How long a streamed tick may reuse the quote fields read from the cache. */
|
|
87
88
|
const STREAM_QUOTE_BASELINE_TTL_MS = 60_000;
|
|
@@ -747,7 +748,8 @@ export class MarketDataCoordinator {
|
|
|
747
748
|
const resolvedQuote = quote.stale === true ? quote : this.resolveIncomingQuote(instrument, quote);
|
|
748
749
|
const startedAt = Date.now();
|
|
749
750
|
const receivedAt = resolvedQuote.stale === true ? resolvedQuote.receivedAt : startedAt;
|
|
750
|
-
|
|
751
|
+
// A tick merged onto a saved copy is the stream's answer, not the saved copy.
|
|
752
|
+
const storedQuote = withSavedCopyMarkOf(receivedAt == null ? resolvedQuote : { ...resolvedQuote, receivedAt }, quote);
|
|
751
753
|
const currentQuote = current.data ?? current.lastGoodData;
|
|
752
754
|
if (areStreamQuotesEquivalent(currentQuote, storedQuote)) {
|
|
753
755
|
const previousReceipt = currentQuote?.receivedAt;
|
|
@@ -7,6 +7,7 @@ import { QueryStore } from "../query-store";
|
|
|
7
7
|
import type { QueryEntry } from "../result-types";
|
|
8
8
|
import { buildQuoteKey, instrumentFromQuoteTarget, toMarketDataContext } from "../selectors";
|
|
9
9
|
import { measurePerf } from "../../utils/perf-marks";
|
|
10
|
+
import { withSavedCopyMarkOf } from "../../data/saved-copies";
|
|
10
11
|
import {
|
|
11
12
|
EXPECTED_EMPTY,
|
|
12
13
|
SNAPSHOT_CACHE_TTL_MS,
|
|
@@ -112,7 +113,8 @@ export async function loadQuoteEntry({
|
|
|
112
113
|
cacheMode: options.forceRefresh ? "refresh" : "default",
|
|
113
114
|
},
|
|
114
115
|
);
|
|
115
|
-
|
|
116
|
+
// Resolved onto an older quote, the answer stays a saved copy exactly when the router served one.
|
|
117
|
+
const resolvedQuote = withSavedCopyMarkOf(resolveQuote?.(instrument, quote) ?? quote, quote);
|
|
116
118
|
const source = resolvedQuote.providerId ?? dataProvider.id;
|
|
117
119
|
const attempts = [createAttempt(source, startedAt, "success")];
|
|
118
120
|
return quoteStore.update(key, (current) => readyQuoteEntry(current, resolvedQuote, source, attempts, { keepNewerHeldQuote: true, acceptLastKnown: true }));
|
|
@@ -183,7 +185,7 @@ export async function loadQuoteBatchEntries({
|
|
|
183
185
|
if (item.error != null) results.set(key, storeQuoteFailure(quoteStore, key, dataProvider.id, startedAt, item.error));
|
|
184
186
|
return;
|
|
185
187
|
}
|
|
186
|
-
const quote = resolveQuote?.(instrument, item.quote) ?? item.quote;
|
|
188
|
+
const quote = withSavedCopyMarkOf(resolveQuote?.(instrument, item.quote) ?? item.quote, item.quote);
|
|
187
189
|
const source = quote.providerId ?? dataProvider.id;
|
|
188
190
|
const attempts = [createAttempt(source, Date.now(), "success")];
|
|
189
191
|
results.set(key, quoteStore.update(key, (current) => readyQuoteEntry(current, quote, source, attempts, { keepNewerHeldQuote: true, acceptLastKnown: true })));
|
|
@@ -41,9 +41,9 @@ export function ratioCount(ratio: number): string {
|
|
|
41
41
|
return Number.isInteger(ratio) ? String(ratio) : String(Number(ratio.toPrecision(6)));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/** What a home line says of its receipt: `1 GGAL ADR = 10 of these shares
|
|
44
|
+
/** What a home line says of its receipt: `1 GGAL ADR = 10 of these shares`, and `1 of these shares` for one. */
|
|
45
45
|
function homeLineRatioText(pair: DepositaryPair): string {
|
|
46
|
-
return `1 ${pair.receipt} ADR = ${ratioCount(pair.ratio)} of these
|
|
46
|
+
return `1 ${pair.receipt} ADR = ${ratioCount(pair.ratio)} of these shares`;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { apiClient } from "../api-client";
|
|
2
|
+
import type { FundFactsPayload, FundFlows } from "../api-client/fund-facts";
|
|
3
|
+
import { isBondFactsShape } from "./bond-funds";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A fund facts answer as every reader takes it (the ETF pane, DES, CMP,
|
|
7
|
+
* `ticker`, `fundamentals`): each figure dated and published, the parts a
|
|
8
|
+
* server before them leaves out still readable, anything malformed refused.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fact = (value: unknown) => value === null || (typeof value === "object" && value !== null && "value" in value && "source" in value);
|
|
12
|
+
const finite = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value);
|
|
13
|
+
|
|
14
|
+
function isMetalHoldingsShape(value: FundFactsPayload["metalHoldings"]): boolean {
|
|
15
|
+
return value == null || ((value.metal === "gold" || value.metal === "silver") && typeof value.asOf === "string" && finite(value.ounces)
|
|
16
|
+
&& (value.tonnes === null || finite(value.tonnes)) && typeof value.source?.publisher === "string"
|
|
17
|
+
&& (value.change === null || (typeof value.change?.since === "string" && finite(value.change.ounces))));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Absent from servers before it; otherwise a dated factor with its reset period. */
|
|
21
|
+
const leverageShape = (value: FundFactsPayload["leverage"]) => value === undefined || value === null
|
|
22
|
+
|| (fact(value) && typeof value.value === "number" && Number.isFinite(value.value) && (value.reset === "daily" || value.reset === "monthly"));
|
|
23
|
+
|
|
24
|
+
/** A NAV's estimate range, when the sponsor published one: absent, or two ends in order. */
|
|
25
|
+
const estimateShape = (nav: FundFactsPayload["nav"]) => !nav?.estimate
|
|
26
|
+
|| (finite(nav.estimate.low) && finite(nav.estimate.high) && nav.estimate.low <= nav.estimate.high);
|
|
27
|
+
|
|
28
|
+
/** Absent from servers before them; otherwise a dated count, and a change between two dated counts. */
|
|
29
|
+
const sharesShape = (value: FundFactsPayload["sharesOutstanding"]) => value == null || (fact(value) && finite(value.value));
|
|
30
|
+
const flowsShape = (value: FundFlows | null | undefined) => value == null
|
|
31
|
+
|| (finite(value.shares) && (value.value === null || finite(value.value)) && typeof value.from === "string" && typeof value.asOf === "string");
|
|
32
|
+
|
|
33
|
+
export function validateFundFacts(data: FundFactsPayload): FundFactsPayload {
|
|
34
|
+
if (!data || typeof data.ticker !== "string" || typeof data.covered !== "boolean"
|
|
35
|
+
|| ![data.expenseRatio, data.nav, data.premiumDiscount, data.netAssets, data.sponsor, data.inception, data.index].every(fact)
|
|
36
|
+
|| !estimateShape(data.nav) || !sharesShape(data.sharesOutstanding) || !flowsShape(data.flows)
|
|
37
|
+
|| !isBondFactsShape(data.bond) || !leverageShape(data.leverage) || !isMetalHoldingsShape(data.metalHoldings)) {
|
|
38
|
+
throw new Error("Unreadable fund facts response");
|
|
39
|
+
}
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** `GET /cloud/fund-facts/:ticker`, read and checked. */
|
|
44
|
+
export async function readFundFacts(
|
|
45
|
+
symbol: string,
|
|
46
|
+
client: Pick<typeof apiClient, "getFundFacts"> = apiClient,
|
|
47
|
+
signal?: AbortSignal,
|
|
48
|
+
): Promise<FundFactsPayload> {
|
|
49
|
+
return validateFundFacts(await (signal ? client.getFundFacts(symbol, { signal }) : client.getFundFacts(symbol)));
|
|
50
|
+
}
|
|
@@ -4,10 +4,11 @@ import type { Quote } from "../../types/financials";
|
|
|
4
4
|
import { canonicalExchange } from "../../utils/exchanges";
|
|
5
5
|
import { isFiniteNumber } from "../../utils/guards";
|
|
6
6
|
import { formatUtcDayTime } from "../../utils/utc-time";
|
|
7
|
+
import { fxPrintTradingDay } from "../../utils/fx-market-hours";
|
|
7
8
|
import { zonedDateKey } from "../../utils/zoned-date-time";
|
|
8
9
|
import { futuresChangeBasis, futuresSettleText, isFuturesInstrument } from "../futures-contract";
|
|
9
10
|
import { quoteTradingDay } from "../quotes/day-range";
|
|
10
|
-
import { previousPublishedSession } from "./freshness";
|
|
11
|
+
import { hasPublishedSessionCalendar, previousPublishedSession } from "./freshness";
|
|
11
12
|
import { getActiveQuoteDisplay, getRegularSessionDisplay, regularSessionDisplayDate } from "./status";
|
|
12
13
|
|
|
13
14
|
const DAY_MS = 86_400_000;
|
|
@@ -94,6 +95,18 @@ function isCurrencyPair(quote: Quote): boolean {
|
|
|
94
95
|
|| kindFromListingSyntax(quote.symbol, quote.listingExchangeName || quote.exchangeName) === "currency";
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
/**
|
|
99
|
+
* The trading day a quote describes (quoteTradingDay); for a currency pair,
|
|
100
|
+
* whose venue has no clock, the FX trading day of its print, which turns at
|
|
101
|
+
* 17:00 New York, so every pair on a board is dated alike. Null for a pair's
|
|
102
|
+
* print made while FX is shut, which belongs to no trading day.
|
|
103
|
+
*/
|
|
104
|
+
function tradingDayOf(quote: Quote): string | null {
|
|
105
|
+
const day = quoteTradingDay(quote);
|
|
106
|
+
if (day || !isCurrencyPair(quote) || !Number.isFinite(quote.lastUpdated) || quote.lastUpdated <= 0) return day;
|
|
107
|
+
return fxPrintTradingDay(quote.lastUpdated);
|
|
108
|
+
}
|
|
109
|
+
|
|
97
110
|
/** A coin on the spot crypto venue: its day is the UTC day. */
|
|
98
111
|
function isSpotCoin(quote: Quote): boolean {
|
|
99
112
|
return quoteVenue(quote) === "CCC";
|
|
@@ -119,7 +132,9 @@ function previousIndexSession(quote: Quote, date: string): string | null {
|
|
|
119
132
|
* The session before the one a move is dated to: from the venue's published
|
|
120
133
|
* calendar, with the closures in between (an index's, the venue whose days it
|
|
121
134
|
* follows); otherwise for an index from its own sessions; for a currency pair
|
|
122
|
-
* the weekday before
|
|
135
|
+
* the weekday before; for any other listing the day its own daily closes date
|
|
136
|
+
* its previous close to (`previousCloseDate`, PreviousCloseDates). Null
|
|
137
|
+
* when nothing dates it.
|
|
123
138
|
*/
|
|
124
139
|
function previousSession(quote: Quote, sessionDate: string): DatedChangeBasis | null {
|
|
125
140
|
const venue = calendarVenue(quote);
|
|
@@ -128,9 +143,34 @@ function previousSession(quote: Quote, sessionDate: string): DatedChangeBasis |
|
|
|
128
143
|
const index = previousIndexSession(quote, sessionDate);
|
|
129
144
|
if (index) return { kind: "close", date: index };
|
|
130
145
|
if (isCurrencyPair(quote)) return { kind: "close", date: weekdayBefore(sessionDate) };
|
|
146
|
+
const dated = quote.previousCloseDate;
|
|
147
|
+
if (dated && ISO_DATE.test(dated) && dated < sessionDate) return { kind: "close", date: dated };
|
|
131
148
|
return null;
|
|
132
149
|
}
|
|
133
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Whether something other than the listing's own daily closes dates every
|
|
153
|
+
* move of the quote: a future's terms, a coin's UTC day, a perpetual's 24
|
|
154
|
+
* hours, a currency pair's weekday, or its venue's calendar for the year of
|
|
155
|
+
* `now`. A few lookups, for a caller that runs on every tick before it asks
|
|
156
|
+
* quoteChangeBasis.
|
|
157
|
+
*/
|
|
158
|
+
export function isChangeBasisDatedWithoutCloses(quote: Quote, now = Date.now()): boolean {
|
|
159
|
+
if (isSpotCoin(quote) || isCurrencyPair(quote) || isFuturesInstrument(quote.symbol, quote.instrumentType)) return true;
|
|
160
|
+
if (isPerpetualExchange(quote.listingExchangeName || quote.exchangeName)) return true;
|
|
161
|
+
return hasPublishedSessionCalendar(calendarVenue(quote), new Date(now).toISOString().slice(0, 10));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The exchange-local date of the session a quote's regular move is dated to,
|
|
166
|
+
* the one `quoteChangeBasis` measures from the session before; null when
|
|
167
|
+
* nothing dates it.
|
|
168
|
+
*/
|
|
169
|
+
export function changeBasisSessionDate(quote: Quote): string | null {
|
|
170
|
+
const date = regularSessionDisplayDate(quote) ?? tradingDayOf(quote);
|
|
171
|
+
return date && ISO_DATE.test(date) ? date : null;
|
|
172
|
+
}
|
|
173
|
+
|
|
134
174
|
/**
|
|
135
175
|
* What the quote's move is measured from. A coin moves from its previous UTC
|
|
136
176
|
* day's close, the price at 00:00 UTC, unless Gloom Cloud says it moves over
|
|
@@ -138,9 +178,10 @@ function previousSession(quote: Quote, sessionDate: string): DatedChangeBasis |
|
|
|
138
178
|
* settlement or trade its terms name, or the close of the trade date before
|
|
139
179
|
* on its venue's holiday calendar (futuresChangeBasis). Anything else is
|
|
140
180
|
* the close of the session before the move's, dated by the venue's calendar;
|
|
141
|
-
* a venue without one
|
|
142
|
-
*
|
|
143
|
-
* longer
|
|
181
|
+
* on a venue without one, by the listing's own daily closes once they were
|
|
182
|
+
* read (PreviousCloseDates), and otherwise left undated, never guessed.
|
|
183
|
+
* Null for a quote with no move: none reported, or a listing that no longer
|
|
184
|
+
* trades.
|
|
144
185
|
*/
|
|
145
186
|
export function quoteChangeBasis(
|
|
146
187
|
quote: Quote | null | undefined,
|
|
@@ -151,7 +192,7 @@ export function quoteChangeBasis(
|
|
|
151
192
|
if (!display || !isFiniteNumber(display.change)) return null;
|
|
152
193
|
if (quote.changeBasis === "24h" || isPerpetualExchange(quote.listingExchangeName || quote.exchangeName)) return { kind: "24h" };
|
|
153
194
|
if (isSpotCoin(quote)) return { kind: "utc day" };
|
|
154
|
-
const sessionDate = (session === "active" ? quote.changeSessionDate : regularSessionDisplayDate(quote)) ??
|
|
195
|
+
const sessionDate = (session === "active" ? quote.changeSessionDate : regularSessionDisplayDate(quote)) ?? tradingDayOf(quote);
|
|
155
196
|
if (isFuturesInstrument(quote.symbol, quote.instrumentType)) {
|
|
156
197
|
const basis = futuresChangeBasis(terms ?? { settlement: null }, { ...display, sessionDate }, quoteVenue(quote));
|
|
157
198
|
return basis ? { kind: basis.kind, date: basis.session } : { kind: "previous close" };
|
|
@@ -183,7 +224,7 @@ export function quoteSettleText(
|
|
|
183
224
|
export function quotePreviousCloseDate(quote: Quote | null | undefined): string | null {
|
|
184
225
|
if (!quote || !isFiniteNumber(quote.previousClose) || quote.changeBasis != null) return null;
|
|
185
226
|
if (isPerpetualExchange(quote.listingExchangeName || quote.exchangeName)) return null;
|
|
186
|
-
const sessionDate = quote.changeSessionDate ??
|
|
227
|
+
const sessionDate = quote.changeSessionDate ?? tradingDayOf(quote);
|
|
187
228
|
if (!sessionDate || !ISO_DATE.test(sessionDate)) return null;
|
|
188
229
|
if (isSpotCoin(quote)) return dayBefore(sessionDate);
|
|
189
230
|
if (isFuturesInstrument(quote.symbol, quote.instrumentType)) {
|