@gloom-sh/terminal 0.18.5 → 0.19.1
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 +163 -8
- package/src/api-client/app-attention.ts +3 -0
- package/src/api-client/beneficial-owners.ts +3 -0
- package/src/api-client/company-kpis.ts +3 -0
- package/src/api-client/cot.ts +6 -2
- package/src/api-client/credit-documents.ts +6 -0
- package/src/api-client/data.ts +19 -7
- package/src/api-client/equity-screener.ts +24 -0
- package/src/api-client/fund-facts.ts +45 -4
- package/src/api-client/hiring.ts +3 -0
- package/src/api-client/index.ts +15 -0
- package/src/api-client/ipo.ts +24 -1
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/market-movers.ts +7 -0
- package/src/api-client/members.ts +1 -1
- package/src/api-client/mna.ts +3 -0
- package/src/api-client/paths.ts +9 -1
- package/src/api-client/perps.ts +43 -0
- package/src/api-client/research-activity.ts +3 -2
- package/src/api-client/roadmap.ts +85 -0
- package/src/api-client/types.ts +82 -2
- package/src/app/pane-runtime/plugin-bindings.ts +9 -5
- package/src/app/runtime/broker-import.ts +0 -2
- package/src/app/runtime/plugin-bindings.ts +73 -56
- package/src/architecture/core-builtin-allowlist.json +2 -2
- 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/market.ts +107 -38
- package/src/cli/commands/news-search.ts +22 -0
- package/src/cli/commands/options-chain.ts +48 -7
- package/src/cli/commands/options-leaps.ts +9 -3
- package/src/cli/commands/overview.ts +147 -32
- package/src/cli/commands/search.ts +21 -1
- package/src/cli/commands/themes.ts +11 -2
- package/src/cli/commands/ticker.ts +87 -36
- package/src/cli/company-name-hint.ts +41 -0
- package/src/cli/earnings-calendar.ts +1 -1
- package/src/cli/errors.ts +25 -2
- package/src/cli/glossary.ts +31 -2
- package/src/cli/history-rows.ts +57 -9
- package/src/cli/index-roots.ts +0 -7
- package/src/cli/index.ts +2 -0
- package/src/cli/listing-arg.ts +235 -60
- package/src/cli/output-file.ts +68 -0
- package/src/cli/pane-functions/capabilities.ts +4 -0
- package/src/cli/pane-functions/catalog.ts +80 -7
- package/src/cli/pane-functions/discovery.ts +21 -1
- package/src/cli/pane-functions/dom.ts +13 -3
- package/src/cli/pane-functions/freshness.ts +93 -4
- package/src/cli/pane-functions/function-help.ts +20 -10
- package/src/cli/pane-functions/headless.ts +17 -7
- package/src/cli/pane-functions/index.ts +54 -16
- package/src/cli/pane-functions/market-session.ts +66 -4
- package/src/cli/pane-functions/options.ts +19 -1
- package/src/cli/pane-functions/resolver.ts +19 -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 +22 -11
- package/src/cli/saved-copy-persistence.ts +88 -0
- package/src/cli/ticker-resolution.ts +3 -2
- package/src/components/chart/composite/composite-chart.tsx +4 -0
- package/src/components/chart/composite/interactions.ts +6 -0
- package/src/components/chart/composite/legend.tsx +45 -7
- package/src/components/chart/composite/panel-gestures.ts +33 -0
- package/src/components/chart/composite/panel-surface.tsx +52 -3
- package/src/components/chart/composite/rasterizer.ts +24 -13
- package/src/components/chart/composite/scene.ts +39 -4
- 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/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/list/model.ts +5 -0
- package/src/components/command-bar/pane-templates/items.ts +3 -2
- package/src/components/command-bar/routes/root/runtime.ts +6 -7
- package/src/components/command-bar/selection-runtime.ts +52 -3
- package/src/components/command-bar/surface/index.tsx +2 -0
- package/src/components/command-bar/workflow/collection-actions.ts +3 -3
- package/src/components/layout/pane/capture-stamp.ts +2 -2
- package/src/components/layout/pane/footer/index.tsx +22 -6
- package/src/components/layout/pane/footer/model.ts +83 -15
- package/src/components/layout/pane/status-footer.ts +35 -2
- package/src/components/layout/status-widget-space.ts +9 -0
- package/src/components/onboarding/onboarding-wizard.tsx +4 -1
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +12 -7
- 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 +8 -21
- 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 +18 -3
- package/src/components/ui/icon.tsx +4 -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/data/config/chart-settings.ts +1 -1
- package/src/data/json-ticker-repository.ts +17 -8
- package/src/data/plugin-cache.ts +5 -3
- package/src/data/saved-copies.ts +8 -0
- 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 +103 -142
- package/src/i18n/es.ts +20 -6
- package/src/i18n/ja.ts +20 -6
- package/src/i18n/ko.ts +20 -6
- package/src/i18n/zh-cn.ts +20 -6
- package/src/i18n/zh-tw.ts +20 -6
- package/src/market-data/depositary-pair.ts +27 -3
- package/src/market-data/fund-facts.ts +50 -0
- package/src/market-data/market/change-basis.ts +16 -3
- package/src/market-data/market/format.ts +25 -0
- package/src/market-data/market/freshness.ts +2 -1
- package/src/market-data/options-alternatives.ts +81 -4
- package/src/market-data/quotes/metadata.ts +7 -0
- package/src/news/aggregator.ts +119 -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 +17 -0
- package/src/plugins/builtin/alerts/alert-engine.ts +20 -1
- package/src/plugins/builtin/alerts/alert-log.ts +33 -0
- package/src/plugins/builtin/alerts/calendar-events.ts +10 -4
- package/src/plugins/builtin/alerts/cli-forms.ts +216 -0
- package/src/plugins/builtin/alerts/cli.ts +362 -80
- package/src/plugins/builtin/alerts/command.ts +25 -1
- package/src/plugins/builtin/alerts/event-rows.ts +24 -3
- package/src/plugins/builtin/alerts/events-pane.tsx +34 -10
- package/src/plugins/builtin/alerts/fired-log.ts +73 -9
- package/src/plugins/builtin/alerts/format.ts +75 -5
- package/src/plugins/builtin/alerts/headless.ts +34 -12
- package/src/plugins/builtin/alerts/history-rows.ts +3 -2
- package/src/plugins/builtin/alerts/history.ts +1 -1
- package/src/plugins/builtin/alerts/index.tsx +79 -16
- package/src/plugins/builtin/alerts/metric-command.ts +77 -4
- package/src/plugins/builtin/alerts/metric-data.ts +54 -13
- package/src/plugins/builtin/alerts/metric-model.ts +163 -14
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +1 -1
- package/src/plugins/builtin/alerts/pane.tsx +61 -23
- package/src/plugins/builtin/alerts/quotes.ts +6 -0
- package/src/plugins/builtin/alerts/storage.ts +12 -8
- package/src/plugins/builtin/alerts/types.ts +4 -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/broker-manager/index.tsx +7 -3
- 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 +6 -2
- package/src/plugins/builtin/cds/client.ts +142 -30
- package/src/plugins/builtin/cds/headless.ts +35 -8
- package/src/plugins/builtin/cds/model.ts +145 -18
- package/src/plugins/builtin/cds/pane.tsx +16 -5
- package/src/plugins/builtin/changelog/index.tsx +9 -6
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +3 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +4 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -0
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -2
- package/src/plugins/builtin/chart-composer/follow-binding.ts +14 -2
- package/src/plugins/builtin/chart-composer/headless-schema.ts +7 -1
- package/src/plugins/builtin/chart-composer/headless.ts +6 -1
- package/src/plugins/builtin/chart-composer/index.tsx +5 -6
- package/src/plugins/builtin/chart-composer/pane.tsx +37 -8
- package/src/plugins/builtin/chart-composer/settings.ts +27 -0
- package/src/plugins/builtin/chat/content/command-suggestions.ts +1 -0
- package/src/plugins/builtin/chat/controller/index.ts +5 -1
- package/src/plugins/builtin/chat/controller/notifications.ts +33 -3
- package/src/plugins/builtin/chat/controller/state.ts +25 -2
- package/src/plugins/builtin/chat/controller/unread-people.ts +89 -23
- package/src/plugins/builtin/chat/controller/utils.ts +7 -2
- package/src/plugins/builtin/chat/pane-links/commands.ts +7 -1
- package/src/plugins/builtin/chat/status-preview.ts +79 -0
- package/src/plugins/builtin/chat/status-widget.tsx +147 -10
- package/src/plugins/builtin/chat/unread-badge.ts +51 -10
- package/src/plugins/builtin/clinical-trials/client.ts +49 -4
- package/src/plugins/builtin/clinical-trials/model.ts +86 -31
- package/src/plugins/builtin/clinical-trials/pane.tsx +61 -49
- package/src/plugins/builtin/clinical-trials/sponsor-listing.ts +90 -0
- package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +95 -15
- package/src/plugins/builtin/clinical-trials/trial-pages.ts +50 -0
- package/src/plugins/builtin/cloud/askg/manifest.ts +2 -0
- 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/headless.ts +2 -1
- package/src/plugins/builtin/company-attention/moves.tsx +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +12 -2
- package/src/plugins/builtin/company-attention/signals.tsx +5 -1
- package/src/plugins/builtin/company-kpis/headless.ts +8 -3
- package/src/plugins/builtin/company-kpis/model.ts +73 -5
- package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
- package/src/plugins/builtin/composite-plugins.ts +2 -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 +10 -10
- 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/doe/headless.ts +3 -2
- package/src/plugins/builtin/doe/pane.tsx +13 -3
- 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/data.ts +18 -6
- package/src/plugins/builtin/earnings-calls/format.ts +31 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +20 -5
- package/src/plugins/builtin/earnings-calls/model.ts +6 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +12 -4
- package/src/plugins/builtin/econ/calendar-model.ts +48 -1
- package/src/plugins/builtin/econ/calendar-source.ts +4 -2
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/figures.ts +48 -0
- package/src/plugins/builtin/econ/index.tsx +14 -5
- package/src/plugins/builtin/econ/print-watch.ts +3 -1
- package/src/plugins/builtin/econ/types.ts +2 -0
- package/src/plugins/builtin/econ-statistics/client.ts +11 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +6 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +16 -6
- package/src/plugins/builtin/econ-statistics/pane.tsx +8 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +39 -9
- 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 +68 -13
- package/src/plugins/builtin/fixed-income/pane.tsx +2 -1
- 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 +6 -3
- package/src/plugins/builtin/fx-matrix/headless.ts +1 -1
- package/src/plugins/builtin/fx-matrix/index.tsx +4 -2
- package/src/plugins/builtin/fx-matrix/live-legs.ts +42 -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 +62 -59
- package/src/plugins/builtin/help/shortcut-model.ts +1 -1
- package/src/plugins/builtin/help/shortcut-table.tsx +5 -6
- package/src/plugins/builtin/help/table-cells.tsx +13 -2
- package/src/plugins/builtin/holders/beneficial-client.ts +5 -1
- package/src/plugins/builtin/holders/beneficial-view.tsx +3 -0
- package/src/plugins/builtin/holders/fund-holders.ts +51 -0
- package/src/plugins/builtin/holders/headless.ts +22 -3
- package/src/plugins/builtin/holders/pane.tsx +3 -0
- package/src/plugins/builtin/holders/report-rows.ts +4 -1
- package/src/plugins/builtin/insider/headless.ts +2 -2
- package/src/plugins/builtin/ipo-calendar/client.ts +18 -2
- package/src/plugins/builtin/ipo-calendar/headless.ts +75 -11
- package/src/plugins/builtin/ipo-calendar/listing-ipo.ts +160 -0
- package/src/plugins/builtin/ipo-calendar/model.ts +98 -2
- 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 +33 -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/headless.ts +12 -5
- package/src/plugins/builtin/macro-day/index.tsx +1 -1
- package/src/plugins/builtin/macro-day/model.ts +39 -5
- package/src/plugins/builtin/macro-day/pane.tsx +27 -19
- 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 +27 -7
- package/src/plugins/builtin/market-movers/headless.ts +34 -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 +22 -4
- 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 +2 -1
- package/src/plugins/builtin/mna/headless.ts +2 -0
- package/src/plugins/builtin/mna/pane.tsx +3 -1
- package/src/plugins/builtin/news/headless.ts +3 -1
- package/src/plugins/builtin/news/index.tsx +4 -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 +29 -5
- package/src/plugins/builtin/options/enrichment.ts +17 -5
- package/src/plugins/builtin/options/table.ts +5 -2
- package/src/plugins/builtin/options/types.ts +2 -0
- package/src/plugins/builtin/options/view.tsx +17 -4
- package/src/plugins/builtin/options-positioning/client.ts +11 -0
- package/src/plugins/builtin/options-positioning/headless.ts +21 -8
- package/src/plugins/builtin/options-positioning/index.tsx +1 -1
- package/src/plugins/builtin/options-positioning/model.ts +78 -9
- package/src/plugins/builtin/options-positioning/pane.tsx +21 -6
- 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/headless.ts +65 -9
- package/src/plugins/builtin/perps/index.tsx +7 -5
- package/src/plugins/builtin/perps/model.ts +18 -4
- package/src/plugins/builtin/perps/pane.tsx +19 -22
- 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 +7 -5
- package/src/plugins/builtin/portfolio-list/pane/futures-front.ts +40 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -7
- 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/index.tsx +0 -14
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +5 -2
- package/src/plugins/builtin/portfolio-list/table.tsx +15 -9
- package/src/plugins/builtin/primary-dealers/client.ts +13 -38
- package/src/plugins/builtin/realized-vol/client.ts +13 -5
- package/src/plugins/builtin/realized-vol/evidence.ts +29 -4
- package/src/plugins/builtin/realized-vol/headless.ts +8 -4
- package/src/plugins/builtin/realized-vol/index.tsx +2 -2
- package/src/plugins/builtin/realized-vol/model.ts +37 -6
- package/src/plugins/builtin/realized-vol/pane.tsx +11 -9
- 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 +40 -12
- package/src/plugins/builtin/research/headless.ts +1 -1
- package/src/plugins/builtin/research/index.tsx +7 -3
- package/src/plugins/builtin/research/relative-valuation-headless.ts +13 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +31 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +59 -20
- package/src/plugins/builtin/research/relative-valuation-peers.ts +217 -20
- package/src/plugins/builtin/research/relative-valuation-settings.ts +44 -0
- 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/risk-factors/data.ts +4 -2
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/roadmap/index.tsx +28 -0
- package/src/plugins/builtin/roadmap/model.ts +67 -0
- package/src/plugins/builtin/roadmap/pane.tsx +244 -0
- 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 +16 -5
- package/src/plugins/builtin/scanner/live-headless.ts +48 -5
- package/src/plugins/builtin/scanner/live-model.ts +11 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +3 -3
- 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 +4 -2
- package/src/plugins/builtin/sec/index.tsx +3 -0
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +16 -7
- 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/headless-market-data.ts +2 -2
- package/src/plugins/builtin/shared/job-posting.ts +1 -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 +11 -2
- package/src/plugins/builtin/shared/research-cells.tsx +1 -1
- package/src/plugins/builtin/shared/series-cache.ts +4 -4
- 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 +2 -1
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -8
- package/src/plugins/builtin/shared/volatility/pricing.ts +19 -0
- package/src/plugins/builtin/shared/wall-view-lifecycle.ts +3 -1
- package/src/plugins/builtin/themes/model.ts +16 -7
- package/src/plugins/builtin/themes/pane.tsx +5 -5
- package/src/plugins/builtin/thirteenf/api.ts +12 -1
- package/src/plugins/builtin/thirteenf/data.ts +7 -7
- package/src/plugins/builtin/thirteenf/headless.ts +31 -4
- 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 +11 -3
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/pane.tsx +14 -8
- 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-auctions/headless.ts +21 -12
- package/src/plugins/builtin/treasury-auctions/pane.tsx +9 -3
- 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/client.ts +3 -13
- package/src/plugins/builtin/vol-surface/headless.ts +3 -3
- package/src/plugins/builtin/vol-surface/index.tsx +1 -1
- package/src/plugins/builtin/vol-surface/pane.tsx +7 -5
- package/src/plugins/builtin/volatility/index.tsx +2 -2
- package/src/plugins/builtin/volatility/pane.tsx +7 -4
- package/src/plugins/builtin/world-venue-map/headless.ts +3 -3
- package/src/plugins/builtin/yield-curve/client.ts +61 -1
- package/src/plugins/builtin/yield-curve/headless.ts +9 -6
- package/src/plugins/builtin/yield-curve/index.tsx +34 -10
- package/src/plugins/builtin/yield-curve/swaps.tsx +9 -5
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/catalog-manifest.ts +2 -1
- package/src/plugins/host-link.ts +1 -1
- package/src/plugins/marketplace/model.ts +18 -5
- package/src/portfolio/column-values.ts +11 -7
- package/src/portfolio/futures-positions.ts +6 -3
- package/src/portfolio/position-quantity.ts +15 -9
- package/src/remote/resources.ts +2 -1
- package/src/renderers/dom/data-table/row.tsx +26 -0
- package/src/renderers/dom/desktop/icons.tsx +7 -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 +3 -3
- package/src/renderers/electrobun/bun/desktop/backend.ts +21 -10
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +15 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -0
- package/src/renderers/electrobun/bun/desktop/installer-folder.ts +731 -0
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +102 -10
- package/src/renderers/electrobun/bun/desktop/update.ts +115 -14
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +52 -0
- package/src/renderers/electrobun/bun/desktop/windows-script.ts +92 -0
- package/src/renderers/electrobun/bun/index.ts +26 -2
- package/src/renderers/electrobun/bun/window/create.ts +43 -4
- package/src/renderers/electrobun/bun/window/events.ts +20 -0
- package/src/renderers/electrobun/bun/window/windows-custom-chrome.ts +9 -2
- package/src/renderers/electrobun/bun/window/windows-native.ts +78 -0
- package/src/renderers/electrobun/bun/window/windows-quit.ts +57 -0
- package/src/renderers/electrobun/shared/app-name.ts +13 -0
- package/src/renderers/electrobun/shared/protocol.ts +12 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +6 -0
- package/src/renderers/electrobun/view/main.tsx +24 -1
- package/src/renderers/electrobun/view/news-source.ts +5 -1
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +14 -7
- package/src/renderers/electrobun/view/ui-host.tsx +8 -0
- package/src/renderers/electrobun/view/view-ids.ts +85 -0
- package/src/renderers/opentui/start.tsx +5 -0
- 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/fred-series.ts +3 -1
- package/src/sources/gloomberb-cloud/index.ts +43 -8
- package/src/sources/gloomberb-cloud/news.ts +47 -7
- package/src/sources/provider-router/financials.ts +15 -3
- package/src/sources/provider-router/index.ts +8 -5
- package/src/state/ticker-cleanup.ts +50 -0
- package/src/sync/controller.ts +4 -3
- package/src/sync/core-contributors.ts +90 -31
- 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/test-support/preload.ts +14 -0
- package/src/theme/themes.ts +10 -0
- package/src/tickers/company-name-listing.ts +53 -13
- package/src/tickers/company-name.ts +50 -4
- package/src/tickers/index-roots.ts +7 -0
- package/src/tickers/listing-fate.ts +2 -2
- package/src/tickers/listing-venues.ts +15 -3
- package/src/tickers/search/index.ts +6 -2
- package/src/tickers/search/ranking.ts +5 -1
- package/src/tickers/search/upsert.ts +13 -0
- package/src/tickers/terminal-codes.ts +19 -0
- package/src/tickers/ticker-changes.ts +8 -4
- package/src/time-series/alignment.ts +1 -1
- package/src/time-series/economic.ts +18 -4
- package/src/time-series/field-catalog.ts +1 -1
- package/src/time-series/filed-trailing-eps.ts +197 -0
- package/src/time-series/fundamentals.ts +44 -1
- package/src/time-series/ice-credit.ts +3 -0
- package/src/time-series/price-comparison.ts +30 -2
- package/src/time-series/resolve-context.ts +3 -1
- package/src/time-series/resolve.ts +56 -4
- package/src/time-series/session-bar.ts +11 -0
- package/src/time-series/spec.ts +3 -2
- package/src/time-series/studies.ts +8 -2
- package/src/time-series/total-return.ts +160 -0
- package/src/time-series/transforms.ts +2 -3
- package/src/time-series/types.ts +22 -1
- package/src/types/company-from.ts +40 -0
- package/src/types/data-provider.ts +7 -0
- package/src/types/financials.ts +59 -1
- package/src/types/headless.ts +27 -3
- package/src/types/news-source.ts +1 -0
- package/src/types/plugin.ts +9 -0
- package/src/ui/host.tsx +3 -0
- package/src/updater/failure.ts +4 -1
- package/src/utils/cli-output.ts +42 -1
- package/src/utils/crypto-pair.ts +165 -7
- package/src/utils/declared-dividends.ts +1 -1
- package/src/utils/forward-dividend.ts +2 -0
- package/src/utils/fundamentals.ts +60 -8
- 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/price-history.ts +7 -1
- package/src/utils/shell-word.ts +8 -0
- package/src/utils/trailing-dividend.ts +53 -4
- package/src/version.ts +2 -2
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +0 -17
|
@@ -3,6 +3,7 @@ import type { CliCommandDef } from "../../types/plugin";
|
|
|
3
3
|
import { TIME_RANGES, type TimeRange } from "../../time-series/range";
|
|
4
4
|
import { yearToDateStartIndex } from "../../market-data/market/year-to-date";
|
|
5
5
|
import type { EarningsEvent, QuoteBatchResult, QuoteSubscriptionTarget, SecFilingItem } from "../../types/data-provider";
|
|
6
|
+
import { companyDataNotes, type CompanyFrom } from "../../types/company-from";
|
|
6
7
|
import type { NewsArticle, NewsFeed, NewsQuery } from "../../news/types";
|
|
7
8
|
import type {
|
|
8
9
|
AnalystResearchData,
|
|
@@ -12,7 +13,7 @@ import type {
|
|
|
12
13
|
Quote,
|
|
13
14
|
TickerFinancials,
|
|
14
15
|
} from "../../types/financials";
|
|
15
|
-
import { currencyPriceMinDigits, formatMarketPrice, formatMarketPriceWithCurrency, quoteFormatOptions, resolveAssetDisplayKind, withCurrencyMinorDigits } from "../../market-data/market/format";
|
|
16
|
+
import { currencyPriceMinDigits, formatMarketPrice, formatMarketPriceWithCurrency, penceFigure, quoteFormatOptions, resolveAssetDisplayKind, withCurrencyMinorDigits } from "../../market-data/market/format";
|
|
16
17
|
import { INDEX_POINTS_EXPORT_UNIT, isIndexLevel, reportedQuoteVolume } from "../../market-data/market/index-level";
|
|
17
18
|
import { changeBasisJson, changeBasisLabel, changeBasisNote, quoteChangeBasis, quotePreviousCloseDate, quoteSettleText } from "../../market-data/market/change-basis";
|
|
18
19
|
import {
|
|
@@ -41,6 +42,7 @@ import {
|
|
|
41
42
|
import { cliArrow, cliStyles, colorBySign, renderSection, renderStats } from "../../utils/cli-output";
|
|
42
43
|
import { filledPeriodsNote, stalePeriodNote, statementHistoryNotes } from "../../utils/financial-statements";
|
|
43
44
|
import { formatPerShareNumber } from "../../utils/reported-money";
|
|
45
|
+
import { isCurrencyPairListing } from "../../utils/fx-market-hours";
|
|
44
46
|
import {
|
|
45
47
|
analystTargetCurrency,
|
|
46
48
|
formatAnalystPrice,
|
|
@@ -58,7 +60,7 @@ import {
|
|
|
58
60
|
} from "../../market-data/options-alternatives";
|
|
59
61
|
import {
|
|
60
62
|
atReportTtmRate, cliFuturesContract, futuresContractMetrics, exportedDividendFundamentals, fundamentalsReportTables, loadDividendDistributions,
|
|
61
|
-
|
|
63
|
+
loadReportFundFacts, renderFundamentalsReport, writesCurrencyCodes,
|
|
62
64
|
} from "./ticker";
|
|
63
65
|
import { createBaseConverter } from "../base-converter";
|
|
64
66
|
import { loadStatementFilings } from "../statement-filings";
|
|
@@ -75,6 +77,7 @@ import {
|
|
|
75
77
|
loadOptionModelInputs,
|
|
76
78
|
loadOptionsChainOpenInterest,
|
|
77
79
|
chainCoinCurrency,
|
|
80
|
+
chainHasFilledIv,
|
|
78
81
|
formatCoinPremiumCell,
|
|
79
82
|
formatOptionDeltaCell,
|
|
80
83
|
formatOptionDollarCell,
|
|
@@ -90,6 +93,7 @@ import {
|
|
|
90
93
|
optionsBasisFields,
|
|
91
94
|
optionsBasisFootnote,
|
|
92
95
|
parseOptionExpiration,
|
|
96
|
+
takeExpirationOption,
|
|
93
97
|
valueChainAtModelSpot,
|
|
94
98
|
type OptionsChainBasis,
|
|
95
99
|
} from "./options-chain";
|
|
@@ -139,6 +143,7 @@ import {
|
|
|
139
143
|
historyPriceDecimals,
|
|
140
144
|
historyRows,
|
|
141
145
|
historyUnit,
|
|
146
|
+
quotedPriceDivisor,
|
|
142
147
|
historyVolume,
|
|
143
148
|
historyVolumeText,
|
|
144
149
|
type HistoryRow,
|
|
@@ -153,7 +158,7 @@ import {
|
|
|
153
158
|
symbolListNotes,
|
|
154
159
|
type HistoryListRow,
|
|
155
160
|
} from "../history-export";
|
|
156
|
-
import { isCliFailure } from "../errors";
|
|
161
|
+
import { fail, isCliFailure, NO_DATA_CODE } from "../errors";
|
|
157
162
|
import { mapWithConcurrency } from "../../utils/concurrency";
|
|
158
163
|
import { MISSING_VOLUME_TEXT } from "../../utils/price-history-integrity";
|
|
159
164
|
import { CRYPTO_BOARD_HINT, quoteNotes } from "./crypto-hints";
|
|
@@ -161,6 +166,7 @@ import { bareFuturesCode, futuresBoardContract } from "../../market-data/futures
|
|
|
161
166
|
import { commodityNamedIn, commoditySearchName } from "../../market-data/commodity-names";
|
|
162
167
|
import { newsEmptyMessage } from "./news-hints";
|
|
163
168
|
import {
|
|
169
|
+
closestStoriesReason,
|
|
164
170
|
commodityNewsRoute,
|
|
165
171
|
commonWordCandidate,
|
|
166
172
|
METALS_NEWS_TOPIC,
|
|
@@ -175,6 +181,7 @@ import {
|
|
|
175
181
|
noMetalStoriesMessage,
|
|
176
182
|
noStoriesMessage,
|
|
177
183
|
quotedSearchCommand,
|
|
184
|
+
searchClosestNewsStories,
|
|
178
185
|
searchNewsStories,
|
|
179
186
|
wordMeansMore,
|
|
180
187
|
} from "./news-search";
|
|
@@ -185,7 +192,7 @@ import { exportedFundamentals } from "../../utils/price-earnings";
|
|
|
185
192
|
import { fundamentalsFreshness, fxPairFreshness, quotesFreshness, rowsFreshness, valuationFreshness } from "../freshness";
|
|
186
193
|
import { fxRateNotes } from "../../plugins/builtin/shared/fx-rate-freshness";
|
|
187
194
|
import { quoteBarNotes } from "../../market-data/quotes/intraday-bar";
|
|
188
|
-
import { depositaryPairText, isReceiptSide, listingDepositaryPair } from "../../market-data/depositary-pair";
|
|
195
|
+
import { cedearRatioText, depositaryPairText, isReceiptSide, listingCedearRatio, listingDepositaryPair } from "../../market-data/depositary-pair";
|
|
189
196
|
import { isPesoDollarPair, loadPesoDollarRates, pesoDollarRateLines, pesoDollarRatesJson } from "../peso-dollar-rates";
|
|
190
197
|
import { atRegularSessionPrice, regularSessionValuationPrice } from "../../market-data/quotes/regular-session-valuation";
|
|
191
198
|
import { viewMarketCapitalization } from "../../utils/market-capitalization";
|
|
@@ -195,6 +202,7 @@ import {
|
|
|
195
202
|
cloudNewsFreshness,
|
|
196
203
|
cloudRealtimeAccess,
|
|
197
204
|
REPORTED_DATA,
|
|
205
|
+
SEC_FILING_ROWS,
|
|
198
206
|
SEC_FILINGS,
|
|
199
207
|
} from "../../plugins/builtin/shared/report-freshness";
|
|
200
208
|
import {
|
|
@@ -215,6 +223,7 @@ import {
|
|
|
215
223
|
type ResolvedEarningsEvent,
|
|
216
224
|
} from "../../plugins/builtin/shared/earnings-calendar";
|
|
217
225
|
import {
|
|
226
|
+
coinListingNotes,
|
|
218
227
|
EXCHANGE_OPTION,
|
|
219
228
|
listingHeading,
|
|
220
229
|
listingIdentity,
|
|
@@ -237,7 +246,7 @@ import {
|
|
|
237
246
|
type ListingIdentity,
|
|
238
247
|
} from "../listing-arg";
|
|
239
248
|
import { bareListingNote, listingFateNotes, noLongerTradingNote, tradingListing } from "../../tickers/listing-fate";
|
|
240
|
-
import { isYieldIndexSymbol } from "
|
|
249
|
+
import { isYieldIndexSymbol } from "../../tickers/index-roots";
|
|
241
250
|
import {
|
|
242
251
|
analyzeTaxEquivalent, distributionBasis, loadTreasuryTenors, parseTaxRates, TAX_RATE_HELP_OPTIONS, taxEquivalentJson, type TaxRates,
|
|
243
252
|
} from "../../market-data/tax-equivalent";
|
|
@@ -303,6 +312,7 @@ import {
|
|
|
303
312
|
unvaluedHoldersNote,
|
|
304
313
|
} from "../../plugins/builtin/holders/report-rows";
|
|
305
314
|
import { fetchBeneficialOwners } from "../../plugins/builtin/holders/beneficial-client";
|
|
315
|
+
import { fundHoldersAnswer } from "../../plugins/builtin/holders/fund-holders";
|
|
306
316
|
import { centralBankEventsMessage } from "../central-bank-events";
|
|
307
317
|
import { classSharesAsOf, classSharesToday } from "../../plugins/builtin/holders/client";
|
|
308
318
|
import {
|
|
@@ -465,7 +475,8 @@ const QUOTE_LEAD_COLUMNS = [
|
|
|
465
475
|
row.error && !row.price
|
|
466
476
|
// A typo is not an outage: say what is wrong with the symbol itself.
|
|
467
477
|
? isNotATickerMessage(row.error) ? cliStyles.warning("not a ticker") : cliStyles.danger("unavailable")
|
|
468
|
-
:
|
|
478
|
+
// A London line adds the pence it trades in, as the exchange and RNS write it, muted as a table cell's note is: £6.308 630.8p.
|
|
479
|
+
: `${yieldLevelCell(row.price, row)}${row.pence ? ` ${cliStyles.muted(row.pence)}` : ""}`
|
|
469
480
|
),
|
|
470
481
|
},
|
|
471
482
|
{
|
|
@@ -729,10 +740,12 @@ function quoteRows(results: QuoteCliRecord[], now = Date.now()) {
|
|
|
729
740
|
// A price in cents says what it is per, as the contract terms word it: 314.95¢/lb.
|
|
730
741
|
const per = display.price != null ? futuresPricePer(result.futuresContract, quote?.currency) : "";
|
|
731
742
|
const previousClose = display.price != null && display.change != null ? display.price - display.change : quote?.previousClose;
|
|
743
|
+
const last = price(display.price);
|
|
732
744
|
return {
|
|
733
745
|
symbol: result.target.symbol,
|
|
734
746
|
name: quote?.name || result.listing?.name || "",
|
|
735
|
-
price: `${
|
|
747
|
+
price: `${last}${per}`,
|
|
748
|
+
pence: penceFigure(display.price, quote, /\.(\d+)/.exec(last)?.[1]?.length ?? 0),
|
|
736
749
|
rawPrice: display.price,
|
|
737
750
|
priceBasis: quote?.priceBasis ?? null,
|
|
738
751
|
instrumentType: quote?.instrumentType ?? null,
|
|
@@ -904,7 +917,7 @@ function corporateActionRows(data: CorporateActionsData) {
|
|
|
904
917
|
...declaredDividends(data).map((event) => ({
|
|
905
918
|
type: "dividend",
|
|
906
919
|
date: event.exDate,
|
|
907
|
-
detail: `declared ${currency ? formatDistributionAmount(event.amount, currency) : cleanDecimal(event.amount)}`
|
|
920
|
+
detail: `declared ${event.special ? "special " : ""}${currency ? formatDistributionAmount(event.amount, currency) : cleanDecimal(event.amount)}`
|
|
908
921
|
+ (event.payDate ? `, payable ${event.payDate}` : ""),
|
|
909
922
|
})),
|
|
910
923
|
...data.splits.map((event) => ({
|
|
@@ -1096,13 +1109,15 @@ async function runQuote(rawArgs: string[], ctx: Parameters<CliCommandDef["execut
|
|
|
1096
1109
|
const quiet = ended ? null : noPrintsTodayText(row.quote, now);
|
|
1097
1110
|
return [ended ?? (quiet ? `${label}: ${quiet}` : []), quoteBarNotes(label, row.quote, now)].flat();
|
|
1098
1111
|
}),
|
|
1099
|
-
// A receipt and its home line each say the ratio, as `ticker` does.
|
|
1112
|
+
// A receipt and its home line each say the ratio, as `ticker` does; a CEDEAR names itself in its own.
|
|
1100
1113
|
...data.flatMap((row) => {
|
|
1114
|
+
const cedear = listingCedearRatio({ quote: row.quote });
|
|
1115
|
+
if (cedear) return [`${cedearRatioText(cedear)}.`];
|
|
1101
1116
|
const pair = listingDepositaryPair({ quote: row.quote });
|
|
1102
1117
|
return pair ? [`${row.target.symbol}: ${depositaryPairText(pair, isReceiptSide({ quote: row.quote }))}.`] : [];
|
|
1103
1118
|
}),
|
|
1104
1119
|
// A cell shows only "unavailable", and an exported row only its status, so stderr names each failure; the JSON rows carry each reason.
|
|
1105
|
-
...ctx.cliOptions.format !== "json" ? quoteNotes(data
|
|
1120
|
+
...ctx.cliOptions.format !== "json" ? quoteNotes(data) : [],
|
|
1106
1121
|
];
|
|
1107
1122
|
const columns = commandName === "compare" ? compareColumns() : quoteColumns();
|
|
1108
1123
|
const basisNotes = changeBasisNotes(data, now);
|
|
@@ -1117,7 +1132,8 @@ async function runQuote(rawArgs: string[], ctx: Parameters<CliCommandDef["execut
|
|
|
1117
1132
|
// close does not read as a contradiction of DGS10 or GC for the same day.
|
|
1118
1133
|
// Dated by the quotes as served, which say whether one is the saved copy.
|
|
1119
1134
|
freshness: withSavedCopy(
|
|
1120
|
-
|
|
1135
|
+
// A table across markets (US and London lines) dates each market's session and says when each opens.
|
|
1136
|
+
quotesFreshness(data.map((row) => row.quote), { datesEachVenue: true, ...yieldsOnly ? { schedule: `Cboe close ${CBOE_YIELD_INDEX_CLOSE}` } : {} }),
|
|
1121
1137
|
answers.map(({ result }) => result.quote),
|
|
1122
1138
|
),
|
|
1123
1139
|
}, {
|
|
@@ -1399,7 +1415,11 @@ async function loadListingHistory(
|
|
|
1399
1415
|
};
|
|
1400
1416
|
// A coin's volume is traded value in its quote currency: said in every row and on the status line.
|
|
1401
1417
|
const volume = historyVolume(unit, traded);
|
|
1402
|
-
|
|
1418
|
+
// Spot FX has no exchange to count its trades: a source's 0 is no volume, printed as missing.
|
|
1419
|
+
const pair = quote?.instrumentType === "CURRENCY" || isCurrencyPairListing(symbol, exchange);
|
|
1420
|
+
// A London line's bars were priced in pence: cleaned there, and printed to the pence decimals `quote` shows.
|
|
1421
|
+
const priceDivisor = quotedPriceDivisor(quote);
|
|
1422
|
+
const rows = historyRows(pair ? points.map(({ volume: _volume, ...point }) => point) : points, resolution, unit.currency, unit.unit, volume, priceDivisor);
|
|
1403
1423
|
// Bars stop arriving on the listing's own trading days, not New York's.
|
|
1404
1424
|
const venue = quote?.listingExchangeName || exchange || undefined;
|
|
1405
1425
|
const served = range === "YTD" && !window ? rows.slice(Math.max(0, yearToDateStartIndex(rows.map((row) => row.date), rows[0]?.interval, venue))) : rows;
|
|
@@ -1450,7 +1470,7 @@ async function loadListingHistory(
|
|
|
1450
1470
|
].flat();
|
|
1451
1471
|
return {
|
|
1452
1472
|
listing, identity, unit, data, resolution, interval, intraday, volume, freshness, notes,
|
|
1453
|
-
decimals: historyPriceDecimals(data, listing.saved?.metadata.assetCategory),
|
|
1473
|
+
decimals: historyPriceDecimals(data, listing.saved?.metadata.assetCategory, priceDivisor),
|
|
1454
1474
|
};
|
|
1455
1475
|
}
|
|
1456
1476
|
|
|
@@ -1720,6 +1740,22 @@ const STATEMENT_COLUMNS: CliResultColumn<ReturnType<typeof financialStatementRow
|
|
|
1720
1740
|
{ key: "currency", header: "Cur" },
|
|
1721
1741
|
];
|
|
1722
1742
|
|
|
1743
|
+
/** A symbol as typed in capitals (`NEE`, `BP:LSE`, `7203.T`), never a word of a company's name. */
|
|
1744
|
+
const TYPED_SYMBOL = /^[A-Z0-9][A-Z0-9.:^=&-]{0,15}$/;
|
|
1745
|
+
|
|
1746
|
+
/**
|
|
1747
|
+
* The symbols of a command given several where it takes one: `NEE FSLR` as
|
|
1748
|
+
* two words, or as one (`"NEE FSLR"`, `NEE,FSLR`). One word with spaces is
|
|
1749
|
+
* a list only when every part is a symbol as typed, so a company's name
|
|
1750
|
+
* (`"Bank of America"`) is still searched for. Null for one symbol.
|
|
1751
|
+
*/
|
|
1752
|
+
export function comparedSymbols(args: readonly string[]): string[] | null {
|
|
1753
|
+
const words = args.flatMap((arg) => arg.split(/[\s,]+/)).filter(Boolean);
|
|
1754
|
+
if (words.length < 2) return null;
|
|
1755
|
+
if (args.length > 1 || args.some((arg) => arg.includes(","))) return words;
|
|
1756
|
+
return words.every((word) => TYPED_SYMBOL.test(word)) ? words : null;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1723
1759
|
async function runFinancials(rawArgs: string[], ctx: Parameters<CliCommandDef["execute"]>[1], view: FinancialsView) {
|
|
1724
1760
|
const args = [...rawArgs];
|
|
1725
1761
|
const exchangeOption = takeOption(args, "--exchange");
|
|
@@ -1744,6 +1780,12 @@ async function runFinancials(rawArgs: string[], ctx: Parameters<CliCommandDef["e
|
|
|
1744
1780
|
const tabular = ctx.cliOptions.format === "csv" || ctx.cliOptions.format === "ndjson";
|
|
1745
1781
|
if (sectionFlag && !tabular) ctx.fail("--section picks one table of --csv or --ndjson output.");
|
|
1746
1782
|
if (sectionFlag && !section?.trim()) ctx.fail("--section needs a section title or number.");
|
|
1783
|
+
// Several symbols are a comparison, which RV draws side by side.
|
|
1784
|
+
const compared = view === "valuation" ? comparedSymbols(args) : null;
|
|
1785
|
+
if (compared) {
|
|
1786
|
+
ctx.fail(`valuation takes one symbol; got ${compared.join(" ")}.`,
|
|
1787
|
+
`To compare their valuations side by side: gloom fn RV ${compared.join(",")}\nUsage: gloom valuation <symbol>`);
|
|
1788
|
+
}
|
|
1747
1789
|
const raw = requireOneArg(args, `${commandName} <symbol>`, "symbol", ctx);
|
|
1748
1790
|
const selectTables = (tables: CliReportTables) => {
|
|
1749
1791
|
try {
|
|
@@ -1765,8 +1807,8 @@ async function runFinancials(rawArgs: string[], ctx: Parameters<CliCommandDef["e
|
|
|
1765
1807
|
// declared distribution it annualizes (not in JSON), and one whose dividend stopped says so; read beside the listing notes.
|
|
1766
1808
|
const distributions = view === "statements" ? null : loadDividendDistributions(
|
|
1767
1809
|
market.dataProvider, listing.request, financials, { declared: ctx.cliOptions.format !== "json" });
|
|
1768
|
-
// A
|
|
1769
|
-
const
|
|
1810
|
+
// A fund's facts: its bond figures beside its distribution yield, and whether fn ETF has any to point to.
|
|
1811
|
+
const fundFacts = view === "statements" ? null : loadReportFundFacts(listing.request.symbol,
|
|
1770
1812
|
financials.quote?.tradingExchangeName || listing.request.exchange || financials.quote?.listingExchangeName || financials.quote?.exchangeName,
|
|
1771
1813
|
financials, listing.saved);
|
|
1772
1814
|
const treasury = rates ? loadTreasuryTenors() : null;
|
|
@@ -1795,13 +1837,14 @@ async function runFinancials(rawArgs: string[], ctx: Parameters<CliCommandDef["e
|
|
|
1795
1837
|
loadBankFigures(market.statementSources, listing.request, financials),
|
|
1796
1838
|
])
|
|
1797
1839
|
: [null, { bank: null, note: null }];
|
|
1798
|
-
const
|
|
1840
|
+
const facts = await fundFacts;
|
|
1841
|
+
const bond = facts?.bond ?? null;
|
|
1799
1842
|
// On the SEC yield when the sponsor publishes one, else the distribution yield the line above shows.
|
|
1800
1843
|
const taxEquivalent = rates ? analyzeTaxEquivalent({
|
|
1801
1844
|
symbol: identity.symbol || listing.key, bond, rates, treasury: await treasury,
|
|
1802
1845
|
distribution: distributionBasis(priced.fundamentals?.dividendYield, priced.fundamentals?.dividendYieldBasis === "trailing" ? "trailing" : "forward"),
|
|
1803
1846
|
}) : null;
|
|
1804
|
-
const report = { ...data, distributions: await distributions, statementFilings, bank: bank.bank, bankNote: bank.note, bondFund: bond, taxEquivalent,
|
|
1847
|
+
const report = { ...data, distributions: await distributions, statementFilings, bank: bank.bank, bankNote: bank.note, bondFund: bond, fundFacts: facts, taxEquivalent,
|
|
1805
1848
|
// A base currency other than USD reads every amount with its code, as `ticker` does.
|
|
1806
1849
|
currencyCodes: writesCurrencyCodes(market.config) };
|
|
1807
1850
|
ctx.printResult({
|
|
@@ -1895,26 +1938,29 @@ const NEWS_COLUMNS = [
|
|
|
1895
1938
|
async function printNewsSearch(
|
|
1896
1939
|
text: string,
|
|
1897
1940
|
articles: NewsArticle[],
|
|
1898
|
-
{ reason, empty, commodity = true, failure, ticker = null }: {
|
|
1941
|
+
{ reason, empty, commodity = true, failure, ticker = null, closest = false }: {
|
|
1899
1942
|
reason?: string;
|
|
1900
1943
|
empty?: string;
|
|
1901
1944
|
commodity?: boolean;
|
|
1902
1945
|
failure?: string;
|
|
1903
1946
|
/** The listing a coin pair's search stands in for. */
|
|
1904
1947
|
ticker?: string | null;
|
|
1948
|
+
/** No story has every word: these are the ones with the most. */
|
|
1949
|
+
closest?: boolean;
|
|
1905
1950
|
},
|
|
1906
1951
|
ctx: Parameters<CliCommandDef["execute"]>[1],
|
|
1907
1952
|
) {
|
|
1908
1953
|
const searched = failure === undefined;
|
|
1909
1954
|
const named = searched && commodity && articles.length === 0 && commodityNamedIn(text) !== null;
|
|
1910
1955
|
const route = named ? await commodityNewsRoute(text) : null;
|
|
1956
|
+
const closestReason = closest && articles.length > 0 ? closestStoriesReason(text) : null;
|
|
1911
1957
|
ctx.printResult({
|
|
1912
1958
|
data: articles,
|
|
1913
1959
|
...(searched ? {} : { warnings: [`Searching stories for "${text}" failed: ${failure}`] }),
|
|
1914
|
-
metadata: { ticker, search: text, feed: null, ...(route ? { futuresNews: route.command } : {}) },
|
|
1960
|
+
metadata: { ticker, search: text, feed: null, ...(closestReason ? { match: "closest" } : {}), ...(route ? { futuresNews: route.command } : {}) },
|
|
1915
1961
|
freshness: rowsFreshness(newsRows(articles), cloudNewsFreshness(await cloudRealtimeAccess())),
|
|
1916
1962
|
}, {
|
|
1917
|
-
heading: newsSearchHeading(text, reason),
|
|
1963
|
+
heading: newsSearchHeading(text, [reason, closestReason].filter(Boolean).join(" · ") || undefined),
|
|
1918
1964
|
rows: newsRows,
|
|
1919
1965
|
columns: NEWS_COLUMNS,
|
|
1920
1966
|
empty: named ? noStoriesMessage(text, route) : empty ?? (searched ? noStoriesMessage(text, null) : "No stories to show."),
|
|
@@ -1976,7 +2022,8 @@ async function runNews(rawArgs: string[], ctx: Parameters<CliCommandDef["execute
|
|
|
1976
2022
|
if (exchangeOption || feed) ctx.fail(`${exchangeOption ? "--exchange" : "--feed"} goes with a symbol, not with text to search stories for.`, "Usage: gloom news <query>");
|
|
1977
2023
|
const problem = newsSearchTextProblem(text);
|
|
1978
2024
|
if (problem) ctx.fail(problem);
|
|
1979
|
-
|
|
2025
|
+
const answer = await searchClosestNewsStories(text, limit);
|
|
2026
|
+
await printNewsSearch(text, answer.found, { closest: answer.closest }, ctx);
|
|
1980
2027
|
return;
|
|
1981
2028
|
}
|
|
1982
2029
|
// A metal's future or name is its market's news, not a company's: GOLD in capitals stays Gold.com's.
|
|
@@ -2043,7 +2090,8 @@ async function runNews(rawArgs: string[], ctx: Parameters<CliCommandDef["execute
|
|
|
2043
2090
|
return;
|
|
2044
2091
|
}
|
|
2045
2092
|
const empty = emptyMessage(false);
|
|
2046
|
-
|
|
2093
|
+
// A bare coin ticker read as another listing (ETH, the Grayscale fund) says where the coin is, as `quote` does.
|
|
2094
|
+
const read = listing ? [...listingReadNotes(listing), ...coinListingNotes(listing, quote)] : [];
|
|
2047
2095
|
// A word that is also the company's name ("gold" for Gold.com Inc.) says once which ticker it found and how
|
|
2048
2096
|
// to search the stories that mention it instead, when those stories are mostly about something else.
|
|
2049
2097
|
const typed = args[0]?.trim() ?? "";
|
|
@@ -2155,7 +2203,7 @@ async function runFilings(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2155
2203
|
...listingMetadata(resolved), ...(form ? { form } : {}),
|
|
2156
2204
|
...(page ? { announcementsPage: page.url } : {}),
|
|
2157
2205
|
},
|
|
2158
|
-
freshness: rowsFreshness(filingRows(filings),
|
|
2206
|
+
freshness: rowsFreshness(filingRows(filings), SEC_FILING_ROWS),
|
|
2159
2207
|
...(choice.length > 0 ? { warnings: choice } : {}),
|
|
2160
2208
|
}, {
|
|
2161
2209
|
heading: listingHeading(resolved),
|
|
@@ -2167,7 +2215,7 @@ async function runFilings(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2167
2215
|
empty: [form ? `No ${form} filings found for ${listingTitle(resolved)}.`
|
|
2168
2216
|
: identity ? noSecReportsNotice(resolved)
|
|
2169
2217
|
: `No SEC filings found for ${listingTitle(resolved)}.`, pageLine].filter(Boolean).join("\n"),
|
|
2170
|
-
...(pageLine
|
|
2218
|
+
...filingsFootnote(pageLine, filings[0]?.companyFrom),
|
|
2171
2219
|
});
|
|
2172
2220
|
} catch (error) {
|
|
2173
2221
|
if (!(error instanceof SecRegistrantMismatchError)) throw error;
|
|
@@ -2185,6 +2233,16 @@ async function runFilings(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2185
2233
|
});
|
|
2186
2234
|
}
|
|
2187
2235
|
|
|
2236
|
+
/**
|
|
2237
|
+
* The lines `filings` prints under its rows and CSV writes as notes: an ASX
|
|
2238
|
+
* listing's announcements page, and whose filings a foreign line shows when
|
|
2239
|
+
* they are its company's home line's.
|
|
2240
|
+
*/
|
|
2241
|
+
function filingsFootnote(pageLine: string | null | undefined, companyFrom: CompanyFrom | undefined): { footnote?: string; exportNotes?: string[] } {
|
|
2242
|
+
const lines = [...(pageLine ? [pageLine] : []), ...companyDataNotes(companyFrom)];
|
|
2243
|
+
return lines.length ? { footnote: lines.join("\n"), exportNotes: lines } : {};
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2188
2246
|
/**
|
|
2189
2247
|
* `filings` for a company on ASX that files nothing with the SEC: its latest
|
|
2190
2248
|
* ASX announcements from Gloom Cloud, newest first, under the line saying it
|
|
@@ -2355,7 +2413,8 @@ async function printBeneficialOwners(
|
|
|
2355
2413
|
heading: `${listingHeading(identity)}${cliStyles.muted(beneficialListFacts(payload, form, rows.length, history).map((fact) => ` · ${fact}`).join(""))}`,
|
|
2356
2414
|
// Text draws each column as the HDS report does; CSV and JSON keep the raw values.
|
|
2357
2415
|
textColumns: BENEFICIAL_REPORT_COLUMNS.map((column) => ({ ...column, format: column.textFormat ?? column.format })),
|
|
2358
|
-
|
|
2416
|
+
// A foreign line's owners read from its company's home line say whose.
|
|
2417
|
+
...(legend || payload.companyFrom ? { footnote: [legend, ...companyDataNotes(payload.companyFrom)].filter(Boolean).join("\n") } : {}),
|
|
2359
2418
|
columns: [
|
|
2360
2419
|
...BENEFICIAL_REPORT_COLUMNS.map(({ key, header, align }) => ({ key, header, ...(align ? { align } : {}) })),
|
|
2361
2420
|
{ key: "otherPersons", header: "Other persons" },
|
|
@@ -2401,14 +2460,20 @@ async function runHolders(
|
|
|
2401
2460
|
// --tail counts back from the end of the rows loaded, so it loads at least as many as it asks for.
|
|
2402
2461
|
const tail = ctx.cliOptions.tail;
|
|
2403
2462
|
const indexLimit = Math.min(ctx.cliOptions.limit ?? Math.max(tail ?? 0, HOLDERS_DEFAULT_ROWS), HOLDER_ROWS_MAX);
|
|
2463
|
+
const quoted = loadListingQuote(market.dataProvider, listing);
|
|
2404
2464
|
const [source, quote, form4, index] = await Promise.all([
|
|
2405
2465
|
loadForListing(
|
|
2406
2466
|
listing, market, ctx,
|
|
2407
2467
|
() => market.dataProvider.getHolders(listing.request.symbol, listing.request.exchange),
|
|
2408
2468
|
(found) => found.holders.length === 0,
|
|
2409
2469
|
{ command: commandName, noun: "holder data" },
|
|
2410
|
-
)
|
|
2411
|
-
|
|
2470
|
+
).catch(async (error: unknown) => {
|
|
2471
|
+
// A fund has no ownership breakdown: say so, and what reads it, rather than the source's NO_DATA.
|
|
2472
|
+
const fund = await fundHoldersAnswer(listing.symbol, error, await quoted, apiClient);
|
|
2473
|
+
if (fund) fail(fund.message, fund.details.join("\n") || undefined, NO_DATA_CODE);
|
|
2474
|
+
throw error;
|
|
2475
|
+
}),
|
|
2476
|
+
quoted,
|
|
2412
2477
|
insiderCommand ? loadForm4Report(market, listing) : null,
|
|
2413
2478
|
indexTicker ? loadIndexedHolders(indexTicker, indexLimit).catch(logFailure("cli.commands-market", "Read the 13F holder index failed", null)) : null,
|
|
2414
2479
|
]);
|
|
@@ -2450,7 +2515,7 @@ async function runHolders(
|
|
|
2450
2515
|
const columns = holderReportColumns(shownRows, valueCurrency);
|
|
2451
2516
|
// Dated as HDS dates it: by the list's as-of; an insider report of Form 4 filings alone as INS dates it, by the newest.
|
|
2452
2517
|
const freshness = form4Only
|
|
2453
|
-
? rowsFreshness(form4?.newestFiled ? [{ filingDate: form4.newestFiled }] : [], { ...
|
|
2518
|
+
? rowsFreshness(form4?.newestFiled ? [{ filingDate: form4.newestFiled }] : [], { ...SEC_FILING_ROWS, basis: "Form 4 filings" })
|
|
2454
2519
|
: rowsFreshness(shownRows, { ...SEC_FILINGS, basis: "13F filings" }, { asOf: data.asOf ?? null });
|
|
2455
2520
|
// Named as fn HDS takes it, so the closing notes point to the same listing.
|
|
2456
2521
|
const requested = exchangeOption && !raw.includes(":") ? `${raw}:${exchangeOption.toUpperCase()}` : raw;
|
|
@@ -2520,6 +2585,8 @@ async function runHolders(
|
|
|
2520
2585
|
insiderCommand ? insiderSummary(data, listing, identity, form4) : "",
|
|
2521
2586
|
].filter(Boolean).join("\n"),
|
|
2522
2587
|
empty: `No holders reported for ${listingTitle(identity)}.`,
|
|
2588
|
+
// Holders read from the company's home line say whose; the SEC index's are the listing's own.
|
|
2589
|
+
...(!indexed && data.companyFrom ? { footnote: companyDataNotes(data.companyFrom).join("\n") } : {}),
|
|
2523
2590
|
});
|
|
2524
2591
|
});
|
|
2525
2592
|
}
|
|
@@ -2616,12 +2683,13 @@ async function runEvents(rawArgs: string[], ctx: Parameters<CliCommandDef["execu
|
|
|
2616
2683
|
async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["execute"]>[1]) {
|
|
2617
2684
|
const args = [...rawArgs];
|
|
2618
2685
|
const leapsOptions = takeLeapsOptions(args);
|
|
2619
|
-
const
|
|
2686
|
+
const expirationOption = takeExpirationOption(args);
|
|
2687
|
+
const { value: expiration, flag: expirationFlag } = expirationOption;
|
|
2688
|
+
if (expirationOption.both) ctx.fail("--expiry is --expiration; give one of them.", `Usage: gloom ${OPTIONS_USAGE}`);
|
|
2620
2689
|
const exchangeOption = takeOption(args, "--exchange");
|
|
2621
2690
|
if (leapsOptions.leaps) {
|
|
2622
2691
|
// With --leaps, --expiration is a window of one expiry.
|
|
2623
|
-
const
|
|
2624
|
-
const criteria = parseLeapsCriteria({ ...leapsOptions.raw, ...expirationGiven ? { "--expiration": expiration ?? "" } : {} });
|
|
2692
|
+
const criteria = parseLeapsCriteria({ ...leapsOptions.raw, ...expirationOption.given ? { "--expiration": expiration ?? "" } : {} });
|
|
2625
2693
|
if ("error" in criteria) ctx.fail(criteria.error, `Usage: gloom ${LEAPS_USAGE}`);
|
|
2626
2694
|
const entries = normalizeSymbols(args);
|
|
2627
2695
|
if (entries.length === 0) ctx.fail("--leaps needs at least one symbol.", `Usage: gloom ${LEAPS_USAGE}`);
|
|
@@ -2633,11 +2701,11 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2633
2701
|
}
|
|
2634
2702
|
const raw = requireOneArg(args, OPTIONS_USAGE, "symbol", ctx);
|
|
2635
2703
|
let expirationDate: number | undefined;
|
|
2636
|
-
if (
|
|
2704
|
+
if (expirationOption.given) {
|
|
2637
2705
|
const parsed = expiration == null ? null : parseOptionExpiration(expiration);
|
|
2638
2706
|
if (parsed == null) {
|
|
2639
2707
|
ctx.fail(
|
|
2640
|
-
expiration == null ?
|
|
2708
|
+
expiration == null ? `${expirationFlag} needs a date.` : `Invalid ${expirationFlag} "${expiration}".`,
|
|
2641
2709
|
`Use ${OPTION_EXPIRATION_FORMAT}.${expiration == null ? "" : expirationHint(expiration)}\nUsage: gloom ${OPTIONS_USAGE}`,
|
|
2642
2710
|
);
|
|
2643
2711
|
}
|
|
@@ -2669,7 +2737,7 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2669
2737
|
const listed = await readChain(undefined).then(({ chain }) => chain.expirationDates,
|
|
2670
2738
|
logFailure("cli-market", "Read available option expirations failed", []));
|
|
2671
2739
|
ctx.fail(`expiry ${expiryIsoDate(expirationDate)} for ${listing.key} `
|
|
2672
|
-
+ expiredExpiryText(expirationDate, listed, now, { exchange: expiryVenue, flag:
|
|
2740
|
+
+ expiredExpiryText(expirationDate, listed, now, { exchange: expiryVenue, flag: expirationFlag.slice(2) }),
|
|
2673
2741
|
`Run gloom options ${listing.key} to list the live expiries.`);
|
|
2674
2742
|
}
|
|
2675
2743
|
const { result, chain: read } = await loadForListing(listing, market, ctx, async () => {
|
|
@@ -2711,7 +2779,7 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2711
2779
|
// IV and delta are valued at one spot and instant, named under the table and on every exported row.
|
|
2712
2780
|
const { chain, spot: modelSpot } = valueChainAtModelSpot(loaded, inputs, Date.now(), identity.exchange);
|
|
2713
2781
|
const basis: OptionsChainBasis = { spot: modelSpot, dividendYield: inputs.dividendYield ?? null,
|
|
2714
|
-
openInterest: await loadOptionsChainOpenInterest(symbol, chain) };
|
|
2782
|
+
openInterest: await loadOptionsChainOpenInterest(symbol, chain), ivFilled: chainHasFilledIv(chain) };
|
|
2715
2783
|
const basisFields = optionsBasisFields(basis);
|
|
2716
2784
|
const currency = [...chain.calls, ...chain.puts].find((contract) => contract.currency?.trim())?.currency.trim().toUpperCase()
|
|
2717
2785
|
?? quote?.currency ?? null;
|
|
@@ -2783,6 +2851,7 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2783
2851
|
{ key: "bid", header: "Bid" },
|
|
2784
2852
|
{ key: "ask", header: "Ask" },
|
|
2785
2853
|
{ key: "iv", header: "IV (annualized decimal)" },
|
|
2854
|
+
{ key: "ivSource", header: "IV source" },
|
|
2786
2855
|
{ key: "delta", header: "Delta (decimal)" },
|
|
2787
2856
|
{ key: "volume", header: "Vol" },
|
|
2788
2857
|
{ key: "openInterest", header: "OI" },
|
|
@@ -2810,7 +2879,7 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2810
2879
|
{ key: "coinAsk", header: `Ask ${coin}`, align: "right", format: formatCoinPremiumCell },
|
|
2811
2880
|
{ key: "coinMark", header: `Mark ${coin}`, align: "right", format: formatCoinPremiumCell },
|
|
2812
2881
|
{ key: "mark", header: "Mark $", align: "right", format: formatOptionDollarCell },
|
|
2813
|
-
{ key: "iv", header: "IV", align: "right", format: formatOptionIvCell },
|
|
2882
|
+
{ key: "iv", header: "IV", align: "right", format: (value, row) => formatOptionIvCell(value, row) },
|
|
2814
2883
|
{ key: "delta", header: "Delta", align: "right", format: formatOptionDeltaCell },
|
|
2815
2884
|
{ key: "gamma", header: "Gamma", align: "right", format: formatOptionGammaCell, optional: true, dropPriority: 3 },
|
|
2816
2885
|
{ key: "vega", header: "Vega $", align: "right", format: formatOptionDollarCell, optional: true, dropPriority: 2 },
|
|
@@ -2826,7 +2895,7 @@ async function runOptions(rawArgs: string[], ctx: Parameters<CliCommandDef["exec
|
|
|
2826
2895
|
{ key: "last", header: "Last", align: "right" },
|
|
2827
2896
|
{ key: "bid", header: "Bid", align: "right", format: (_value, row) => formatOptionQuoteCell(row, "bid") },
|
|
2828
2897
|
{ key: "ask", header: "Ask", align: "right", format: (_value, row) => formatOptionQuoteCell(row, "ask") },
|
|
2829
|
-
{ key: "iv", header: "IV", align: "right", format: formatOptionIvCell },
|
|
2898
|
+
{ key: "iv", header: "IV", align: "right", format: (value, row) => formatOptionIvCell(value, row) },
|
|
2830
2899
|
{ key: "delta", header: "Delta", align: "right", format: formatOptionDeltaCell },
|
|
2831
2900
|
{ key: "volume", header: "Vol", align: "right", format: formatCountCell, optional: true, dropPriority: 1 },
|
|
2832
2901
|
{ key: "openInterest", header: "OI", align: "right", format: formatCountCell, optional: true, dropPriority: 1 },
|
|
@@ -3250,7 +3319,7 @@ export const marketDataCliCommands: BuiltinCliCommandDef[] = [
|
|
|
3250
3319
|
usage: [OPTIONS_USAGE, LEAPS_USAGE],
|
|
3251
3320
|
options: [
|
|
3252
3321
|
{
|
|
3253
|
-
flags: `--expiration <${OPTION_EXPIRATION_PLACEHOLDER}>`,
|
|
3322
|
+
flags: `--expiration <${OPTION_EXPIRATION_PLACEHOLDER}>, --expiry <${OPTION_EXPIRATION_PLACEHOLDER}>`,
|
|
3254
3323
|
description: "Expiration as a date (2028-01-21) or Unix seconds; defaults to the nearest one, and lists the others. With --leaps: rank that expiry alone",
|
|
3255
3324
|
},
|
|
3256
3325
|
EXCHANGE_OPTION,
|
|
@@ -82,6 +82,28 @@ export async function searchNewsStories(text: string, limit: number, topics?: re
|
|
|
82
82
|
return response.items.map((item) => mapCloudNewsArticle(item));
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/** A search's stories, and whether they are its closest ones because no story has every word. */
|
|
86
|
+
export interface NewsSearchAnswer {
|
|
87
|
+
found: NewsArticle[];
|
|
88
|
+
closest: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The stories matching the text; when no story has every word of a search of
|
|
93
|
+
* several, the ones with the most of them, most words first. Spellings of
|
|
94
|
+
* one word are one word to the service: lockup, lock-up and lock up;
|
|
95
|
+
* spinoff and spin-off; expiry and expiration.
|
|
96
|
+
*/
|
|
97
|
+
export async function searchClosestNewsStories(text: string, limit: number): Promise<NewsSearchAnswer> {
|
|
98
|
+
const response = await apiClient.searchCloudNews(text, limit, undefined, { closest: true });
|
|
99
|
+
return { found: response.items.map((item) => mapCloudNewsArticle(item)), closest: response.match === "closest" };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** What the heading says of a search no story has every word of. */
|
|
103
|
+
export function closestStoriesReason(text: string): string {
|
|
104
|
+
return `no story has every word of "${text}"; the closest, most words first`;
|
|
105
|
+
}
|
|
106
|
+
|
|
85
107
|
/** The NI code of the metal markets: prices, futures, bullion and the trusts that hold it, not a miner's releases. */
|
|
86
108
|
export const METALS_NEWS_TOPIC = "metals";
|
|
87
109
|
|