gloomberb 0.18.3 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +84 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +22 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +21 -4
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1117 -264
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +192 -47
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +300 -41
- package/src/cli/name-entries.ts +30 -18
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +24 -11
- package/src/cli/pane-functions/index.ts +18 -16
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +47 -10
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +61 -16
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +111 -22
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +198 -68
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +373 -16
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +305 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +13 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +12 -6
- package/src/components/layout/header.tsx +7 -6
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +29 -12
- package/src/i18n/ja.ts +29 -12
- package/src/i18n/ko.ts +29 -12
- package/src/i18n/zh-cn.ts +29 -12
- package/src/i18n/zh-tw.ts +29 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +76 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +6 -3
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +79 -23
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +5 -3
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +3 -2
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +18 -11
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +6 -1
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/headless.ts +4 -4
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +10 -4
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +29 -8
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/view.tsx +10 -10
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +36 -15
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +4 -1
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +21 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +5 -4
- package/src/plugins/builtin/vol-surface/headless.ts +12 -3
- package/src/plugins/builtin/vol-surface/model.ts +4 -2
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/styles.css +76 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +1 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +14 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +76 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/index.ts +10 -5
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { saveConfig } from "../../../../data/config/store";
|
|
2
|
-
import { withConfigData
|
|
2
|
+
import { withConfigData } from "../../../../cli/scoped-context";
|
|
3
|
+
import { withCollectionConfigData, withCollectionMarketData } from "../../../../cli/suffixed-listing-rows";
|
|
3
4
|
import { countCollectionTickers } from "../../../../cli/helpers";
|
|
4
5
|
import { resolveCliTicker, resolveTickerForCli } from "../../../../cli/ticker-resolution";
|
|
5
6
|
import { takeFlag, takeOption } from "../../../../cli/commands/command-utils";
|
|
6
|
-
import { EXCHANGE_OPTION, listingKeys, loadSavedListing, parseListingArg,
|
|
7
|
+
import { EXCHANGE_OPTION, listingKeys, loadSavedListing, parseListingArg, requireSavedListing, savedListingCandidates, savedListingName, type ListingArg } from "../../../../cli/listing-arg";
|
|
7
8
|
import { cliStyles, renderStats, renderTable } from "../../../../utils/cli-output";
|
|
8
9
|
import { CLI_COMMAND_GROUPS } from "../../../../cli/help";
|
|
9
10
|
import { formatMarketCostWithCurrency, formatMarketQuantity } from "../../../../market-data/market/format";
|
|
@@ -29,6 +30,8 @@ import {
|
|
|
29
30
|
removeTickerFromPortfolio,
|
|
30
31
|
resolveManualPositionCurrency,
|
|
31
32
|
setManualPortfolioPosition,
|
|
33
|
+
LotCostFxMergeError,
|
|
34
|
+
type SetManualPortfolioPositionInput,
|
|
32
35
|
setPortfolioCash,
|
|
33
36
|
setPortfolioTargetWeight,
|
|
34
37
|
} from "../../../../portfolio/mutations";
|
|
@@ -48,13 +51,16 @@ import { importedFromText } from "../imported-from";
|
|
|
48
51
|
import { savedListingCoinNote } from "../../../../cli/commands/crypto-hints";
|
|
49
52
|
import { findNamedCollection } from "../../../../portfolio/collection-name";
|
|
50
53
|
import { wholeUnitQuantityProblem } from "../../../../portfolio/position-quantity";
|
|
51
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
CLI_COST_FX_WORDING, loadPurchaseDateCostFx, readCostFxRate, readPurchaseDate, resolvePositionCostFx, type CostFxHistoryClient,
|
|
56
|
+
} from "../../../../portfolio/cost-fx";
|
|
52
57
|
import { lotCostFxRate, sameCurrency } from "../../../../portfolio/position-metrics";
|
|
53
58
|
import { formatFxRate } from "../../../../cli/fx-pair";
|
|
54
59
|
import { createBaseConverter } from "../../../../cli/base-converter";
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
60
|
+
import { heldCurrencyUnit } from "../../../../utils/currency-units";
|
|
61
|
+
import { isCurrencyCode } from "../../../../utils/currency-pair";
|
|
62
|
+
import { parseTypedNumber, readCurrencyAmount } from "../../../../utils/decimal-comma";
|
|
63
|
+
import { DATE_OPTION_EXAMPLES } from "../../../../utils/calendar-date";
|
|
58
64
|
import {
|
|
59
65
|
failPortfolioCommand,
|
|
60
66
|
isCashArgument,
|
|
@@ -68,16 +74,17 @@ import {
|
|
|
68
74
|
requirePortfolio,
|
|
69
75
|
takeCollectionName,
|
|
70
76
|
} from "./shared";
|
|
71
|
-
import { addOneSymbol, addSymbols, FILE_OPTION, printSymbolRows, removeSymbols, requireSymbolList, retryNotice, SYMBOL_LIST_HELP } from "./bulk-symbols";
|
|
77
|
+
import { addOneSymbol, addSymbols, FILE_OPTION, printSymbolRows, removeSymbols, requireSymbolList, retryNotice, shellWord, SYMBOL_LIST_HELP } from "./bulk-symbols";
|
|
72
78
|
import { readNameEntries } from "../../../../cli/name-entries";
|
|
73
79
|
import { DRIP_DEFAULT_YEARS, DRIP_MAX_YEARS, parseDripYears, parseWithholding } from "../income";
|
|
74
80
|
|
|
75
|
-
const ADD_USAGE = "Usage:
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
+
const ADD_USAGE = "Usage: gloom portfolio add <portfolio> <symbols...> [--file <path>]";
|
|
82
|
+
const CREATE_USAGE = "Usage: gloom portfolio create <name> [--currency <code>]";
|
|
83
|
+
const POSITION_USAGE = "Usage: gloom portfolio position set <portfolio> <ticker> <shares|contracts> <avg-cost> [currency] [--date <purchase date> | --cost-fx <rate>]";
|
|
84
|
+
const REMOVE_USAGE = "Usage: gloom portfolio remove <portfolio> <symbols...> [--file <path>]";
|
|
85
|
+
const CASH_USAGE = "Usage: gloom portfolio cash set <portfolio> <amount> [currency] | portfolio cash clear <portfolio>";
|
|
86
|
+
const TARGET_USAGE = "Usage: gloom portfolio target set <portfolio> <symbol|CASH> <weight%> | target clear <portfolio> [symbol] | target show <portfolio>";
|
|
87
|
+
const IMPORT_USAGE = "Usage: gloom portfolio import --13f <CIK|fund name> [--top N] [--name <portfolio>] [--notional <amount>] [--replace]";
|
|
81
88
|
const IMPORT_DEFAULT_TOP = 10;
|
|
82
89
|
const IMPORT_MAX_TOP = 100;
|
|
83
90
|
const IMPORT_DEFAULT_NOTIONAL = 100_000;
|
|
@@ -112,12 +119,53 @@ async function listCollections(ctx: CliCommandContext) {
|
|
|
112
119
|
});
|
|
113
120
|
}
|
|
114
121
|
|
|
115
|
-
|
|
122
|
+
/** What `portfolio create` makes: a name, and the currency it totals in when one was given. */
|
|
123
|
+
interface PortfolioCreateArgs {
|
|
124
|
+
name: string;
|
|
125
|
+
currency?: string;
|
|
126
|
+
/** The currency was the name's last word as typed (`Baht2 THB`), not --currency. */
|
|
127
|
+
currencyFromName?: boolean;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* `portfolio create` arguments: the name, and the currency `--currency`
|
|
132
|
+
* gives. Without --currency, an ISO code typed in capitals as the name's
|
|
133
|
+
* last word (`Baht2 THB`) is the currency, not part of the name; a name
|
|
134
|
+
* quoted as one argument (`"Baht2 THB"`), or given with --currency, keeps
|
|
135
|
+
* every word. A portfolio totals in a whole currency, so pence (GBp, GBX)
|
|
136
|
+
* and cents are refused. The error sentence otherwise.
|
|
137
|
+
*/
|
|
138
|
+
function parsePortfolioCreateArgs(words: readonly string[], currencyOption?: string): PortfolioCreateArgs | { error: string } {
|
|
139
|
+
if (currencyOption != null) {
|
|
140
|
+
const typed = currencyOption.trim();
|
|
141
|
+
const code = typed.toUpperCase();
|
|
142
|
+
if (!typed) return { error: "--currency takes the currency the portfolio totals in, such as --currency THB." };
|
|
143
|
+
const unit = heldCurrencyUnit(typed);
|
|
144
|
+
if (unit.divisor !== 1) {
|
|
145
|
+
return { error: `--currency ${typed} is a minor unit; a portfolio totals in ${unit.currency}, so give --currency ${unit.currency}.` };
|
|
146
|
+
}
|
|
147
|
+
if (!/^[A-Z]{3}$/.test(code) || !isCurrencyCode(code)) {
|
|
148
|
+
return { error: `--currency ${typed} is not a currency code; use three letters such as THB or EUR.` };
|
|
149
|
+
}
|
|
150
|
+
const name = words.join(" ").trim();
|
|
151
|
+
return name ? { name, currency: code } : { error: CREATE_USAGE };
|
|
152
|
+
}
|
|
153
|
+
const last = words.at(-1)?.trim() ?? "";
|
|
154
|
+
const named = words.length > 1 && /^[A-Z]{3}$/.test(last) && isCurrencyCode(last) ? words.slice(0, -1).join(" ").trim() : "";
|
|
155
|
+
if (named) return { name: named, currency: last, currencyFromName: true };
|
|
156
|
+
const name = words.join(" ").trim();
|
|
157
|
+
return name ? { name } : { error: CREATE_USAGE };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function createPortfolioCommand(args: PortfolioCreateArgs, words: readonly string[], ctx: CliCommandContext) {
|
|
161
|
+
const { name, currency, currencyFromName } = args;
|
|
116
162
|
await withConfigData(ctx, async ({ config }) => {
|
|
117
163
|
try {
|
|
118
|
-
const result = createManualPortfolio(config, name, config.baseCurrency);
|
|
164
|
+
const result = createManualPortfolio(config, name, config.baseCurrency, currency ? { fixedCurrency: currency } : {});
|
|
119
165
|
await saveConfig(result.config);
|
|
120
|
-
|
|
166
|
+
const typed = words.join(" ").trim();
|
|
167
|
+
const readAs = currencyFromName ? ` (read ${currency} as its currency; quote "${typed}" to keep it in the name)` : "";
|
|
168
|
+
console.log(cliStyles.success(`Created portfolio "${result.portfolio.name}"${currency ? ` in ${result.portfolio.currency}` : ""}${readAs}.`));
|
|
121
169
|
console.log(renderStats([["ID", result.portfolio.id]]));
|
|
122
170
|
} catch (error) {
|
|
123
171
|
failPortfolioCommand(ctx, error, `Failed to create portfolio "${name}".`);
|
|
@@ -126,7 +174,7 @@ async function createPortfolioCommand(name: string, ctx: CliCommandContext) {
|
|
|
126
174
|
}
|
|
127
175
|
|
|
128
176
|
async function deletePortfolioCommand(name: string, ctx: CliCommandContext) {
|
|
129
|
-
await
|
|
177
|
+
await withCollectionConfigData(ctx, async ({ config, store }) => {
|
|
130
178
|
try {
|
|
131
179
|
const portfolio = requireManualPortfolio(config, name);
|
|
132
180
|
const result = deleteManualPortfolio(config, await store.loadAllTickers(), portfolio.id);
|
|
@@ -181,27 +229,30 @@ function cashRefusal(portfolio: Portfolio, exchange: string | undefined) {
|
|
|
181
229
|
};
|
|
182
230
|
}
|
|
183
231
|
|
|
184
|
-
async function addTickerToPortfolioCommand(
|
|
232
|
+
async function addTickerToPortfolioCommand(
|
|
233
|
+
portfolio: Portfolio, symbol: string, notes: readonly string[], exchange: string | undefined, ctx: CliCommandContext, market: MarketContext,
|
|
234
|
+
) {
|
|
185
235
|
// A bare symbol is stored on the listing `quote` reads it as, as `watchlist add` does; bare CASH is the cash line.
|
|
186
236
|
await addOneSymbol(ctx, market, {
|
|
187
237
|
symbol,
|
|
188
238
|
exchange,
|
|
189
239
|
collection: { kind: "portfolio", name: portfolio.name },
|
|
190
|
-
|
|
240
|
+
notes,
|
|
241
|
+
retry: (key) => `gloom portfolio add ${shellWord(portfolio.name)} ${key}`,
|
|
191
242
|
reject: cashRefusal(portfolio, exchange),
|
|
192
243
|
add: (ticker) => addTickerToPortfolio(ticker, portfolio.id),
|
|
193
244
|
});
|
|
194
245
|
}
|
|
195
246
|
|
|
196
247
|
async function addToPortfolioCommand(args: string[], file: string | undefined, exchange: string | undefined, ctx: CliCommandContext) {
|
|
197
|
-
await
|
|
248
|
+
await withCollectionMarketData(ctx, async (market) => {
|
|
198
249
|
const { portfolio, rest } = requirePortfolioArgs(market.config, args, file, "add", ADD_USAGE, ctx);
|
|
199
250
|
const list = await requireSymbolList(ctx, rest, file, ADD_USAGE, (entries) => readNameEntries(entries, market.dataProvider));
|
|
200
251
|
if (list.single) {
|
|
201
|
-
await addTickerToPortfolioCommand(portfolio, list.single, exchange, ctx, market);
|
|
252
|
+
await addTickerToPortfolioCommand(portfolio, list.single, list.notes, exchange, ctx, market);
|
|
202
253
|
return;
|
|
203
254
|
}
|
|
204
|
-
const retry = (key: string) => `
|
|
255
|
+
const retry = (key: string) => `gloom portfolio add ${shellWord(portfolio.name)} ${key}`;
|
|
205
256
|
const dryRun = ctx.cliOptions.dryRun;
|
|
206
257
|
const rows = await addSymbols({
|
|
207
258
|
symbols: list.symbols,
|
|
@@ -225,11 +276,13 @@ function withoutTarget(config: AppConfig, portfolio: Portfolio, symbol: string):
|
|
|
225
276
|
return removed.length > 0 ? next : null;
|
|
226
277
|
}
|
|
227
278
|
|
|
228
|
-
async function removeTickerFromPortfolioCommand(
|
|
279
|
+
async function removeTickerFromPortfolioCommand(
|
|
280
|
+
portfolio: Portfolio, symbol: string, notes: readonly string[], exchange: string | undefined, ctx: CliCommandContext, { config, store }: ConfigContext,
|
|
281
|
+
) {
|
|
229
282
|
// SAN:EPA and SAN --exchange EPA name the stored listing, which a bare SAN may hold under another venue.
|
|
230
|
-
|
|
283
|
+
// GARAN.IS is the row of GARAN:BIST, else a row still saved under that key (a broker's).
|
|
284
|
+
const { listing, ticker } = await requireSavedListing(symbol, exchange, ctx, store, (row) => row.metadata.portfolios.includes(portfolio.id));
|
|
231
285
|
try {
|
|
232
|
-
const ticker = await loadSavedListing(store, listing);
|
|
233
286
|
if (!ticker) ctx.fail(`Ticker "${listing.key}" was not found in your local data.`);
|
|
234
287
|
const saved = savedListingName(ticker);
|
|
235
288
|
const result = removeTickerFromPortfolio(ticker, portfolio.id);
|
|
@@ -245,6 +298,7 @@ async function removeTickerFromPortfolioCommand(portfolio: Portfolio, symbol: st
|
|
|
245
298
|
removedPositions: result.removedPositionCount,
|
|
246
299
|
removedTarget: nextConfig != null,
|
|
247
300
|
},
|
|
301
|
+
...notes.length > 0 ? { warnings: [...notes] } : {},
|
|
248
302
|
}, {
|
|
249
303
|
text: () => [
|
|
250
304
|
cliStyles.success(`Removed ${saved.label} from "${portfolio.name}".`),
|
|
@@ -260,11 +314,11 @@ async function removeTickerFromPortfolioCommand(portfolio: Portfolio, symbol: st
|
|
|
260
314
|
}
|
|
261
315
|
|
|
262
316
|
async function removeFromPortfolioCommand(args: string[], file: string | undefined, exchange: string | undefined, ctx: CliCommandContext) {
|
|
263
|
-
await
|
|
317
|
+
await withCollectionConfigData(ctx, async (context) => {
|
|
264
318
|
const { portfolio, rest } = requirePortfolioArgs(context.config, args, file, "remove", REMOVE_USAGE, ctx);
|
|
265
319
|
const list = await requireSymbolList(ctx, rest, file, REMOVE_USAGE);
|
|
266
320
|
if (list.single) {
|
|
267
|
-
await removeTickerFromPortfolioCommand(portfolio, list.single, exchange, ctx, context);
|
|
321
|
+
await removeTickerFromPortfolioCommand(portfolio, list.single, list.notes, exchange, ctx, context);
|
|
268
322
|
return;
|
|
269
323
|
}
|
|
270
324
|
// Targets go with their holdings, all in one config write.
|
|
@@ -274,6 +328,7 @@ async function removeFromPortfolioCommand(args: string[], file: string | undefin
|
|
|
274
328
|
exchange,
|
|
275
329
|
store: context.store,
|
|
276
330
|
reject: cashRefusal(portfolio, exchange),
|
|
331
|
+
holds: (ticker) => ticker.metadata.portfolios.includes(portfolio.id),
|
|
277
332
|
remove: (ticker) => {
|
|
278
333
|
const result = removeTickerFromPortfolio(ticker, portfolio.id);
|
|
279
334
|
const withoutTargets = result.changed ? withoutTarget(nextConfig, portfolio, ticker.metadata.ticker) : null;
|
|
@@ -298,7 +353,7 @@ async function setPositionCommand(
|
|
|
298
353
|
cost: { date?: string; costFx?: number; history?: CostFxHistoryClient } = {},
|
|
299
354
|
futuresTerms?: (symbol: string) => Promise<FuturesContractTermsPayload | null>,
|
|
300
355
|
) {
|
|
301
|
-
await
|
|
356
|
+
await withCollectionMarketData(ctx, async ({ config, store, dataProvider }) => {
|
|
302
357
|
try {
|
|
303
358
|
const portfolio = requireManualPortfolio(config, portfolioName);
|
|
304
359
|
rejectCashSymbol(symbol, exchange, portfolio.name);
|
|
@@ -324,20 +379,21 @@ async function setPositionCommand(
|
|
|
324
379
|
const portfolioCurrency = resolvePortfolioTotalsCurrency(
|
|
325
380
|
valued.portfolios.find((entry) => entry.id === portfolio.id) ?? portfolio, valued.baseCurrency);
|
|
326
381
|
const toPortfolio = createBaseConverter(dataProvider, heldCurrencyUnit(portfolioCurrency).currency);
|
|
327
|
-
const costFx = await
|
|
328
|
-
|
|
382
|
+
const costFx = await resolvePositionCostFx({
|
|
383
|
+
date: cost.date, costFx: cost.costFx, history: cost.history ?? apiClient,
|
|
384
|
+
currency, portfolioCurrency, listing: savedListingName(ticker).key, wording: CLI_COST_FX_WORDING,
|
|
329
385
|
// Today's rate, in the units the lot is held in: what a typed rate is checked against.
|
|
330
386
|
todaysRate: async () => (await toPortfolio(1, heldCurrencyUnit(currency).currency))
|
|
331
387
|
/ heldCurrencyUnit(currency).divisor * heldCurrencyUnit(portfolioCurrency).divisor,
|
|
332
388
|
});
|
|
333
|
-
const result =
|
|
389
|
+
const result = setPositionKeepingLotRates(ticker, portfolio.id, {
|
|
334
390
|
shares,
|
|
335
391
|
avgCost,
|
|
336
392
|
currency,
|
|
337
393
|
...(size ? { multiplier: size.multiplier } : {}),
|
|
338
394
|
...(cost.date ? { dateAcquired: cost.date } : {}),
|
|
339
395
|
...(costFx ? { costFx: costFx.costFx } : {}),
|
|
340
|
-
});
|
|
396
|
+
}, `${portfolioCurrency} per ${currency}`);
|
|
341
397
|
const lot = result.ticker.metadata.positions.find((position) => position.portfolio === portfolio.id);
|
|
342
398
|
const multiplier = lot?.multiplier;
|
|
343
399
|
if (future && !multiplier) {
|
|
@@ -347,9 +403,16 @@ async function setPositionCommand(
|
|
|
347
403
|
if (adopted) await saveConfig(adopted);
|
|
348
404
|
const saved = savedListingName(result.ticker);
|
|
349
405
|
const quantity = formatMarketQuantity(shares, { assetCategory: result.ticker.metadata.assetCategory });
|
|
350
|
-
// A cost in another currency converts at the rate it was bought at when the lot has one, else at
|
|
406
|
+
// A cost in another currency converts at the rate it was bought at when the lot has one, else at the close of the
|
|
407
|
+
// purchase date it kept, as portfolio show reads it, else at today's, and says so.
|
|
351
408
|
const foreign = !sameCurrency(currency, portfolioCurrency);
|
|
352
|
-
const
|
|
409
|
+
const storedRate = lot ? lotCostFxRate(lot, currency, portfolioCurrency) : null;
|
|
410
|
+
const dated = foreign && storedRate === null && lot?.dateAcquired
|
|
411
|
+
? (await loadPurchaseDateCostFx([result.ticker], { into: portfolioCurrency, history: cost.history ?? apiClient, portfolioId: portfolio.id }))
|
|
412
|
+
.values().next().value ?? null
|
|
413
|
+
: null;
|
|
414
|
+
const boughtRate = storedRate ?? dated?.rate ?? null;
|
|
415
|
+
const rateDate = costFx?.date ?? dated?.date ?? null;
|
|
353
416
|
// The purchase date shows where it was given or sets the rate; a lot in the portfolio's currency otherwise prints as it did.
|
|
354
417
|
const purchaseDate = lot?.dateAcquired && (cost.date || foreign) ? lot.dateAcquired : null;
|
|
355
418
|
ctx.printResult({
|
|
@@ -357,7 +420,7 @@ async function setPositionCommand(
|
|
|
357
420
|
changed: true, ...listingFields(saved), portfolio: portfolio.name, shares, avgCost, currency,
|
|
358
421
|
...(future ? { contractMultiplier: multiplier ?? null, contractSize: size?.size ?? null } : {}),
|
|
359
422
|
...(purchaseDate ? { dateAcquired: purchaseDate } : {}),
|
|
360
|
-
...(foreign ? { costFxRate: boughtRate, costFxCurrency: portfolioCurrency, costFxDate:
|
|
423
|
+
...(foreign ? { costFxRate: boughtRate, costFxCurrency: portfolioCurrency, costFxDate: rateDate } : {}),
|
|
361
424
|
},
|
|
362
425
|
warnings: notes.length > 0 ? notes : undefined,
|
|
363
426
|
}, {
|
|
@@ -371,11 +434,13 @@ async function setPositionCommand(
|
|
|
371
434
|
["Currency", currency],
|
|
372
435
|
...(purchaseDate ? [["Purchase Date", purchaseDate] as [string, string]] : []),
|
|
373
436
|
...(boughtRate !== null
|
|
374
|
-
? [["Cost FX", `${formatFxRate(boughtRate)} ${portfolioCurrency} per ${currency}${
|
|
437
|
+
? [["Cost FX", `${formatFxRate(boughtRate)} ${portfolioCurrency} per ${currency}${rateDate ? ` (${rateDate} close)` : ""}`] as [string, string]]
|
|
375
438
|
: []),
|
|
376
439
|
]),
|
|
377
440
|
...(foreign && boughtRate === null
|
|
378
|
-
? [cliStyles.muted(
|
|
441
|
+
? [cliStyles.muted(lot?.dateAcquired
|
|
442
|
+
? `Cost converted at today's rate into ${portfolioCurrency}: the FX close of the purchase date could not be read.`
|
|
443
|
+
: `Cost converted at today's rate into ${portfolioCurrency}; add --date or --cost-fx to use the rate when bought.`)]
|
|
379
444
|
: []),
|
|
380
445
|
].join("\n"),
|
|
381
446
|
});
|
|
@@ -386,99 +451,36 @@ async function setPositionCommand(
|
|
|
386
451
|
}
|
|
387
452
|
|
|
388
453
|
/**
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
* than the portfolio's; undefined when neither was given or the position is
|
|
392
|
-
* in the portfolio's currency (a date alone then only dates the lot).
|
|
393
|
-
* `--cost-fx` on a position in the portfolio's own currency, a typed rate
|
|
394
|
-
* that reads as a mistake against today's, and a date with no FX close fail
|
|
395
|
-
* saying what to give instead.
|
|
454
|
+
* Sets the position, saying how to go on when the lots it replaces were
|
|
455
|
+
* bought at FX rates one position cannot keep: give the whole position's rate.
|
|
396
456
|
*/
|
|
397
|
-
|
|
398
|
-
date?: string; costFx?: number; history?: CostFxHistoryClient; currency: string; portfolioCurrency: string; listing: string;
|
|
399
|
-
/** Today's rate, one unit of `currency` in `portfolioCurrency`; NaN when it cannot be read. */
|
|
400
|
-
todaysRate: () => Promise<number>;
|
|
401
|
-
}): Promise<{ costFx: { rate: number; currency: string }; date: string | null } | undefined> {
|
|
402
|
-
const foreign = !sameCurrency(currency, portfolioCurrency);
|
|
403
|
-
const insteadHint = `Give the rate it was bought at instead: --cost-fx <${portfolioCurrency} per ${currency}>.`;
|
|
404
|
-
if (costFx != null) {
|
|
405
|
-
if (!foreign) {
|
|
406
|
-
const held = currency === portfolioCurrency ? currency : `${currency}, a unit of ${portfolioCurrency}`;
|
|
407
|
-
throw new PortfolioCliError(`--cost-fx converts a cost in another currency; ${listing} is held in ${held}, the portfolio's currency.`);
|
|
408
|
-
}
|
|
409
|
-
const problem = implausibleCostFx(costFx, await todaysRate().catch(() => Number.NaN), { currency, portfolioCurrency, listing });
|
|
410
|
-
if (problem) throw new PortfolioCliError(problem, "Or give the purchase --date, and its daily FX close is used.");
|
|
411
|
-
return { costFx: { rate: costFx, currency: portfolioCurrency }, date: null };
|
|
412
|
-
}
|
|
413
|
-
if (!date || !foreign) return undefined;
|
|
457
|
+
function setPositionKeepingLotRates(ticker: TickerRecord, portfolioId: string, input: SetManualPortfolioPositionInput, pair: string) {
|
|
414
458
|
try {
|
|
415
|
-
|
|
416
|
-
return { costFx: { rate: reading.rate, currency: portfolioCurrency }, date: reading.date };
|
|
459
|
+
return setManualPortfolioPosition(ticker, portfolioId, input);
|
|
417
460
|
} catch (error) {
|
|
418
|
-
if (error instanceof
|
|
419
|
-
throw new PortfolioCliError(
|
|
461
|
+
if (error instanceof LotCostFxMergeError) {
|
|
462
|
+
throw new PortfolioCliError(error.message, `Give the rate the whole position was bought at: --cost-fx <${pair}>, or its purchase --date.`);
|
|
420
463
|
}
|
|
421
|
-
|
|
422
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
423
|
-
throw new PortfolioCliError(`Could not read the ${currency} and ${portfolioCurrency} FX closes of ${date}: ${reason}.`, insteadHint);
|
|
464
|
+
throw error;
|
|
424
465
|
}
|
|
425
466
|
}
|
|
426
467
|
|
|
427
|
-
/** How far from today's rate a typed one may be: a currency that lost 99% since purchase still fits. */
|
|
428
|
-
const COST_FX_MAX_RATIO = 100;
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Why a typed `--cost-fx` reads as a mistake against today's rate, else null:
|
|
432
|
-
* a rate per pound for a lot held in pence, the inverse of the pair (0.0319
|
|
433
|
-
* for 31.37 TRY per USD), or more than a hundred times off either way. A
|
|
434
|
-
* rate is only called inverted when today's is far from 1 and the typed one
|
|
435
|
-
* lies on the other side of it, so EUR per USD near parity is never refused.
|
|
436
|
-
* Null when today's rate is not known.
|
|
437
|
-
*/
|
|
438
|
-
function implausibleCostFx(
|
|
439
|
-
rate: number,
|
|
440
|
-
today: number,
|
|
441
|
-
{ currency, portfolioCurrency, listing }: { currency: string; portfolioCurrency: string; listing: string },
|
|
442
|
-
): string | null {
|
|
443
|
-
if (!Number.isFinite(today) || today <= 0) return null;
|
|
444
|
-
const pair = `${portfolioCurrency} per ${currency}`;
|
|
445
|
-
const typed = formatFxRate(rate);
|
|
446
|
-
const todays = `today's is ${formatFxRate(today)} ${pair}`;
|
|
447
|
-
const unit = heldCurrencyUnit(currency);
|
|
448
|
-
if (unit.divisor !== 1 && rate / today >= unit.divisor / 5 && rate / today <= unit.divisor * 5) {
|
|
449
|
-
const name = currency.toUpperCase() === "USX" ? "US cents" : currencyUnitLabel(currency).replace(/^\S+ \((.+)\)$/, "$1");
|
|
450
|
-
return `--cost-fx ${typed} looks like ${portfolioCurrency} per ${unit.currency}; ${listing} is held in ${currency} (${name}), `
|
|
451
|
-
+ `so the rate is ${pair}, 1/${unit.divisor} of that: ${todays}.`;
|
|
452
|
-
}
|
|
453
|
-
if ((today >= 3 && rate < 1) || (today <= 1 / 3 && rate > 1)) {
|
|
454
|
-
return `--cost-fx ${typed} looks inverted: it is the ${portfolioCurrency} paid for one ${currency}, and ${todays}.`;
|
|
455
|
-
}
|
|
456
|
-
if (rate / today > COST_FX_MAX_RATIO || today / rate > COST_FX_MAX_RATIO) {
|
|
457
|
-
return `--cost-fx ${typed} is more than ${COST_FX_MAX_RATIO} times off today's rate (${formatFxRate(today)} ${pair}); check the rate.`;
|
|
458
|
-
}
|
|
459
|
-
return null;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
468
|
/** `--date`: the day the position was bought, as an ISO day, no later than today (UTC). */
|
|
463
469
|
function parsePurchaseDate(value: string, ctx: CliCommandContext): string {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
470
|
+
try {
|
|
471
|
+
return readPurchaseDate(value, CLI_COST_FX_WORDING);
|
|
472
|
+
} catch (error) {
|
|
473
|
+
return ctx.fail(error instanceof Error ? error.message : String(error), POSITION_USAGE);
|
|
474
|
+
}
|
|
468
475
|
}
|
|
469
476
|
|
|
470
477
|
/** `--cost-fx`: one unit of the position's currency in the portfolio's when it was bought, a positive number (32,15 reads as 32.15). */
|
|
471
478
|
function parseCostFx(value: string, ctx: CliCommandContext): number {
|
|
472
|
-
let rate = Number.NaN;
|
|
473
479
|
try {
|
|
474
|
-
|
|
480
|
+
return readCostFxRate(value, CLI_COST_FX_WORDING);
|
|
475
481
|
} catch (error) {
|
|
476
|
-
ctx.fail(error instanceof Error ? error.message : String(error), POSITION_USAGE);
|
|
477
|
-
}
|
|
478
|
-
if (!Number.isFinite(rate) || rate <= 0) {
|
|
479
|
-
ctx.fail(`--cost-fx is the rate the cost was bought at, a positive number such as 32.15 (TRY per USD); got "${value.trim()}".`, POSITION_USAGE);
|
|
482
|
+
return ctx.fail(error instanceof Error ? error.message : String(error), POSITION_USAGE);
|
|
480
483
|
}
|
|
481
|
-
return rate;
|
|
482
484
|
}
|
|
483
485
|
|
|
484
486
|
const CURRENCY_CODE = /^[A-Za-z]{3}$/;
|
|
@@ -565,18 +567,25 @@ function targetSumNote(config: AppConfig, portfolioId: string, tickers: readonly
|
|
|
565
567
|
* that key, else any row of the symbol.
|
|
566
568
|
*/
|
|
567
569
|
async function findListedTicker(store: TickerRepository, portfolio: Portfolio, symbol: string, exchange?: string): Promise<TickerRecord | null> {
|
|
568
|
-
const listing = parseListingArg(symbol, exchange);
|
|
569
570
|
const listed = (await store.loadAllTickers()).filter((ticker) => ticker.metadata.portfolios.includes(portfolio.id));
|
|
570
571
|
const savedAs = (ticker: TickerRecord, key: string) => ticker.metadata.ticker.toUpperCase() === key;
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
572
|
+
const listedAs = (listing: ListingArg) => {
|
|
573
|
+
if (!listing.exchange) {
|
|
574
|
+
const sameSymbol = listed.filter((ticker) => parsePublicTickerKey(ticker.metadata.ticker).symbol === listing.symbol);
|
|
575
|
+
return sameSymbol.find((ticker) => savedAs(ticker, listing.symbol)) ?? sameSymbol[0] ?? null;
|
|
576
|
+
}
|
|
577
|
+
// 7203:TSE is the row on any venue TSE names.
|
|
578
|
+
const keys = listingKeys(listing);
|
|
579
|
+
const onVenue = listed.filter((ticker) => keys.includes(canonicalTickerKey(ticker.metadata.ticker, ticker.metadata.exchange)));
|
|
580
|
+
// The key as saved (VTI:XMEX), else the same listing under another spelling of its venue (VTI:BMV).
|
|
581
|
+
return onVenue.find((ticker) => keys.some((key) => savedAs(ticker, key))) ?? onVenue[0] ?? null;
|
|
582
|
+
};
|
|
583
|
+
// GARAN.IS is the row of GARAN:BIST, else a row the portfolio still holds under that key (a broker's).
|
|
584
|
+
for (const listing of [parseListingArg(symbol, exchange, { listingSuffix: true }), ...savedListingCandidates(symbol, exchange)]) {
|
|
585
|
+
const row = listedAs(listing);
|
|
586
|
+
if (row) return row;
|
|
574
587
|
}
|
|
575
|
-
|
|
576
|
-
const keys = listingKeys(listing);
|
|
577
|
-
const onVenue = listed.filter((ticker) => keys.includes(canonicalTickerKey(ticker.metadata.ticker, ticker.metadata.exchange)));
|
|
578
|
-
// The key as saved (VTI:XMEX), else the same listing under another spelling of its venue (VTI:BMV).
|
|
579
|
-
return onVenue.find((ticker) => keys.some((key) => savedAs(ticker, key))) ?? onVenue[0] ?? null;
|
|
588
|
+
return null;
|
|
580
589
|
}
|
|
581
590
|
|
|
582
591
|
/** What a target command reports for the cash line, in the fields a listing has. */
|
|
@@ -587,7 +596,7 @@ async function setTargetCommand(rest: string[], exchange: string | undefined, ct
|
|
|
587
596
|
const symbol = rest.at(-2);
|
|
588
597
|
const name = rest.slice(0, -2).join(" ");
|
|
589
598
|
if (!name || !symbol || !rawWeight) ctx.fail(TARGET_USAGE);
|
|
590
|
-
await
|
|
599
|
+
await withCollectionMarketData(ctx, async ({ config, store, dataProvider }) => {
|
|
591
600
|
try {
|
|
592
601
|
const portfolio = requirePortfolio(config, name);
|
|
593
602
|
const weight = parseTargetWeight(rawWeight);
|
|
@@ -650,14 +659,14 @@ async function setTargetCommand(rest: string[], exchange: string | undefined, ct
|
|
|
650
659
|
|
|
651
660
|
async function clearTargetCommand(rest: string[], exchange: string | undefined, ctx: CliCommandContext) {
|
|
652
661
|
if (rest.length === 0) ctx.fail(TARGET_USAGE);
|
|
653
|
-
await
|
|
662
|
+
await withCollectionConfigData(ctx, async ({ config, store }) => {
|
|
654
663
|
try {
|
|
655
664
|
// The whole argument naming a portfolio clears every target; otherwise the last word is the symbol.
|
|
656
665
|
const whole = findNamedCollection(config.portfolios, rest.join(" ")) != null;
|
|
657
666
|
const portfolio = requirePortfolio(config, whole ? rest.join(" ") : rest.slice(0, -1).join(" "));
|
|
658
667
|
const rawSymbol = whole ? undefined : rest.at(-1);
|
|
659
668
|
const cash = rawSymbol != null && isCashArgument(rawSymbol, exchange);
|
|
660
|
-
const listing = rawSymbol == null || cash ? null : parseListingArg(rawSymbol, exchange);
|
|
669
|
+
const listing = rawSymbol == null || cash ? null : parseListingArg(rawSymbol, exchange, { listingSuffix: true });
|
|
661
670
|
// The row the listing is: the portfolio's own, else any saved one; a target is kept under that row's key.
|
|
662
671
|
const ticker = listing ? await findListedTicker(store, portfolio, rawSymbol!, exchange) ?? await loadSavedListing(store, listing) : null;
|
|
663
672
|
const saved = ticker ? savedListingName(ticker) : null;
|
|
@@ -707,7 +716,7 @@ async function showTargetsCommand(name: string, ctx: CliCommandContext) {
|
|
|
707
716
|
}
|
|
708
717
|
console.log(cliStyles.bold(`${portfolio.name} targets`));
|
|
709
718
|
if (rows.length === 0) {
|
|
710
|
-
console.log(cliStyles.muted(`No targets. Set one with:
|
|
719
|
+
console.log(cliStyles.muted(`No targets. Set one with: gloom portfolio target set "${portfolio.name}" <symbol|CASH> <weight%>`));
|
|
711
720
|
return;
|
|
712
721
|
}
|
|
713
722
|
console.log("");
|
|
@@ -757,7 +766,7 @@ function parseImportOptions(args: string[], ctx: CliCommandContext): ThirteenFIm
|
|
|
757
766
|
const path = args.find((arg) => /\.(csv|tsv|txt)$/i.test(arg));
|
|
758
767
|
if (!query && path) {
|
|
759
768
|
ctx.fail(
|
|
760
|
-
`portfolio import reads a manager's 13F filing. To add the symbols in ${path}, run:
|
|
769
|
+
`portfolio import reads a manager's 13F filing. To add the symbols in ${path}, run: gloom portfolio add <portfolio> --file ${path}`,
|
|
761
770
|
IMPORT_USAGE,
|
|
762
771
|
);
|
|
763
772
|
}
|
|
@@ -787,8 +796,8 @@ function parseImportOptions(args: string[], ctx: CliCommandContext): ThirteenFIm
|
|
|
787
796
|
async function importThirteenFCommand(options: ThirteenFImportOptions, ctx: CliCommandContext) {
|
|
788
797
|
// The manager's holdings as `fn 13F <manager>` reports them, through the 13F function of the plugins that are on.
|
|
789
798
|
const thirteenF = ctx.plugins.flatMap((plugin) => plugin.paneTemplates ?? []).find((template) => template.shortcut?.prefix === "13F")?.headless;
|
|
790
|
-
if (!thirteenF) ctx.fail("13F filings are not available: the Ownership & Insiders plugin is off.", "Turn it on with
|
|
791
|
-
await
|
|
799
|
+
if (!thirteenF) ctx.fail("13F filings are not available: the Ownership & Insiders plugin is off.", "Turn it on with gloom plugin enable ownership.");
|
|
800
|
+
await withCollectionMarketData(ctx, async ({ config, store, dataProvider }) => {
|
|
792
801
|
try {
|
|
793
802
|
const report = await thirteenF.load(
|
|
794
803
|
{ rawArgument: options.query, argument: options.query, symbols: [], options: { view: "holdings", limit: IMPORT_13F_ROWS } },
|
|
@@ -912,8 +921,9 @@ const POSITION_HELP = {
|
|
|
912
921
|
title: "Positions",
|
|
913
922
|
lines: [
|
|
914
923
|
"position set replaces the portfolio's lots of the symbol with one: a negative size is a short, and 0 is refused (portfolio remove drops the symbol).",
|
|
924
|
+
"Several lots set as one keep their earliest purchase date and their cost FX rates weighted by cost; lots bought at rates one position cannot keep (some at today's rate) are refused until --cost-fx or --date gives the position's own.",
|
|
915
925
|
"A future's size is in contracts, at a price per unit of its contract (GC=F: per troy ounce); the contract size is read from its terms, as quote shows them.",
|
|
916
|
-
"The cost is in the currency named after it, else the listing's. A holding in another currency than the portfolio's (a US stock in a TRY portfolio) can be entered at its cost in the portfolio's currency (position set Lira BRK-B 10 20310 TRY), so P&L is in what was paid.",
|
|
926
|
+
"The cost is in the currency named after it (GBp or GBX for pence, gbp for pounds), else the listing's. A holding in another currency than the portfolio's (a US stock in a TRY portfolio) can be entered at its cost in the portfolio's currency (position set Lira BRK-B 10 20310 TRY), so P&L is in what was paid.",
|
|
917
927
|
"Entered at its cost in its own currency, its P&L converts the cost at today's rate unless --date gives the purchase date, whose daily FX close is used, or --cost-fx gives the rate paid (portfolio currency per unit of the holding's: 32.15 TRY per USD); then the P&L carries the currency's move since. portfolio show names the holdings whose cost converts at today's rate.",
|
|
918
928
|
],
|
|
919
929
|
};
|
|
@@ -947,7 +957,7 @@ export const portfolioCliCommand: CliCommandDef = {
|
|
|
947
957
|
usage: [
|
|
948
958
|
"portfolio [list]",
|
|
949
959
|
"portfolio show <name> [--close] [--explain] [--drip [--years 1-5] [--withholding <pct>]]",
|
|
950
|
-
"portfolio create <name>",
|
|
960
|
+
"portfolio create <name> [--currency <code>]",
|
|
951
961
|
"portfolio delete <name>",
|
|
952
962
|
"portfolio add <portfolio> <symbols...> [--file <path>]",
|
|
953
963
|
"portfolio remove <portfolio> <symbols...> [--file <path>]",
|
|
@@ -971,12 +981,14 @@ export const portfolioCliCommand: CliCommandDef = {
|
|
|
971
981
|
{ flags: "--name <portfolio>", description: "portfolio import: the portfolio to create or fill (default: the manager's name and 13F)" },
|
|
972
982
|
{ flags: "--notional <amount>", description: "portfolio import: the USD total the shares add up to at the filing's prices (default 100,000)" },
|
|
973
983
|
{ flags: "--replace", description: "portfolio import: replace the positions of an existing portfolio of that name" },
|
|
984
|
+
{ flags: "--currency <code>", description: "portfolio create: the currency the portfolio totals in, whatever the base currency (a name's last word in capitals, such as THB, is read as one too)" },
|
|
974
985
|
{ flags: "--date <purchase date>", description: `position set: the day it was bought, as ${DATE_OPTION_EXAMPLES}; a holding in another currency converts its cost at that day's FX close` },
|
|
975
986
|
{ flags: "--cost-fx <rate>", description: "position set: the rate a holding in another currency was bought at, in the portfolio's currency per unit of the holding's (32.15 TRY per USD)" },
|
|
976
|
-
{ flags: "--explain", description: "portfolio show: follow the report with what its terms mean (Weight, Target, Drift, Trade);
|
|
987
|
+
{ flags: "--explain", description: "portfolio show: follow the report with what its terms mean (Weight, Target, Drift, Trade); gloom catalog glossary lists every term" },
|
|
977
988
|
],
|
|
978
989
|
examples: [
|
|
979
990
|
"portfolio show Research",
|
|
991
|
+
"portfolio create Baht --currency THB",
|
|
980
992
|
"portfolio add Research ASML",
|
|
981
993
|
"portfolio add Research ASML:AMS",
|
|
982
994
|
"portfolio add Research --file holdings.csv",
|
|
@@ -1018,11 +1030,11 @@ export const portfolioCliCommand: CliCommandDef = {
|
|
|
1018
1030
|
if (explain && !shows) {
|
|
1019
1031
|
ctx.fail(
|
|
1020
1032
|
`--explain is an option of portfolio show, not portfolio ${action ?? "list"}.`,
|
|
1021
|
-
"Run
|
|
1033
|
+
"Run gloom portfolio show <name> --explain, or gloom catalog glossary for every term.",
|
|
1022
1034
|
);
|
|
1023
1035
|
}
|
|
1024
|
-
if (close && !shows) ctx.fail(`--close is an option of portfolio show, not portfolio ${action ?? "list"}.`, "Usage:
|
|
1025
|
-
const dripUsage = "Usage:
|
|
1036
|
+
if (close && !shows) ctx.fail(`--close is an option of portfolio show, not portfolio ${action ?? "list"}.`, "Usage: gloom portfolio show <name> --close");
|
|
1037
|
+
const dripUsage = "Usage: gloom portfolio show <name> --drip [--years 1-5] [--withholding <pct>]";
|
|
1026
1038
|
if ((dripFlag || hasYears || hasWithholding) && !shows) {
|
|
1027
1039
|
ctx.fail(`${dripFlag ? "--drip" : hasYears ? "--years" : "--withholding"} is an option of portfolio show, not portfolio ${action ?? "list"}.`, dripUsage);
|
|
1028
1040
|
}
|
|
@@ -1042,6 +1054,11 @@ export const portfolioCliCommand: CliCommandDef = {
|
|
|
1042
1054
|
if ((hasDate || hasCostFx) && action !== "position") {
|
|
1043
1055
|
ctx.fail(`${hasDate ? "--date" : "--cost-fx"} is an option of portfolio position set, not portfolio ${action ?? "list"}.`, POSITION_USAGE);
|
|
1044
1056
|
}
|
|
1057
|
+
const hasCurrency = args.some((arg) => arg === "--currency" || arg.startsWith("--currency="));
|
|
1058
|
+
const currencyText = hasCurrency ? takeOption(args, "--currency") ?? "" : undefined;
|
|
1059
|
+
if (hasCurrency && action !== "create") {
|
|
1060
|
+
ctx.fail(`--currency is an option of portfolio create, not portfolio ${action ?? "list"}.`, CREATE_USAGE);
|
|
1061
|
+
}
|
|
1045
1062
|
const purchaseDate = dateText != null ? parsePurchaseDate(dateText, ctx) : undefined;
|
|
1046
1063
|
const costFx = costFxText != null ? parseCostFx(costFxText, ctx) : undefined;
|
|
1047
1064
|
const hasFile = args.some((arg) => arg === "--file" || arg.startsWith("--file="));
|
|
@@ -1060,21 +1077,21 @@ export const portfolioCliCommand: CliCommandDef = {
|
|
|
1060
1077
|
|
|
1061
1078
|
if (action === "show") {
|
|
1062
1079
|
const name = args.slice(1).join(" ");
|
|
1063
|
-
if (!name) ctx.fail("Usage:
|
|
1080
|
+
if (!name) ctx.fail("Usage: gloom portfolio show <name> [--close] [--explain] [--drip]");
|
|
1064
1081
|
await showCollection(name, ctx, { explain, basis, drip });
|
|
1065
1082
|
return;
|
|
1066
1083
|
}
|
|
1067
1084
|
|
|
1068
1085
|
if (action === "create") {
|
|
1069
|
-
const
|
|
1070
|
-
if (
|
|
1071
|
-
await createPortfolioCommand(
|
|
1086
|
+
const created = parsePortfolioCreateArgs(args.slice(1), currencyText);
|
|
1087
|
+
if ("error" in created) return ctx.fail(created.error, created.error === CREATE_USAGE ? undefined : CREATE_USAGE);
|
|
1088
|
+
await createPortfolioCommand(created, args.slice(1), ctx);
|
|
1072
1089
|
return;
|
|
1073
1090
|
}
|
|
1074
1091
|
|
|
1075
1092
|
if (action === "delete" || action === "rm") {
|
|
1076
1093
|
const name = args.slice(1).join(" ");
|
|
1077
|
-
if (!name) ctx.fail("Usage:
|
|
1094
|
+
if (!name) ctx.fail("Usage: gloom portfolio delete <name>");
|
|
1078
1095
|
await deletePortfolioCommand(name, ctx);
|
|
1079
1096
|
return;
|
|
1080
1097
|
}
|