gloomberb 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +32 -1
- package/src/account/auth-model.ts +7 -3
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +11 -6
- package/src/api-client/catalysts.ts +2 -1
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +98 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +182 -16
- package/src/api-client/live-scan.ts +91 -0
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +18 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +224 -26
- package/src/api-client/research-activity.ts +3 -10
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +96 -2
- package/src/app/keybindings/index.ts +3 -0
- package/src/app/keybindings/labels.ts +18 -1
- package/src/app/keybindings/resolve.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/broker-import.ts +43 -26
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +9 -2
- package/src/cli/commands/keybindings.ts +25 -2
- package/src/cli/commands/market.ts +1177 -278
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-chain.ts +59 -3
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +222 -61
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +82 -46
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +194 -48
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +21 -3
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +38 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +113 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +226 -50
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +123 -27
- package/src/cli/listing-arg.ts +316 -46
- package/src/cli/name-entries.ts +30 -18
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +193 -30
- package/src/cli/pane-functions/function-help.ts +76 -30
- package/src/cli/pane-functions/headless.ts +59 -12
- package/src/cli/pane-functions/index.ts +28 -19
- package/src/cli/pane-functions/market-session.ts +15 -5
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +10 -6
- package/src/cli/pane-functions/resolver.ts +64 -11
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +45 -4
- package/src/cli/report-tables.ts +75 -19
- package/src/cli/restore-plugins.ts +42 -15
- package/src/cli/result.ts +164 -23
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +198 -68
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +395 -20
- package/src/components/chart/composite/format.ts +27 -0
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +7 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +314 -13
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/range-statistics.ts +62 -0
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +20 -4
- package/src/components/chart/composite/series-axis-tags.tsx +16 -9
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +17 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/panel/prompt-binding.ts +0 -8
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/alert.ts +1 -1
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +12 -6
- package/src/components/layout/header.tsx +33 -46
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/index.tsx +1 -0
- package/src/components/layout/pane/footer/model.ts +38 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-frame.tsx +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +10 -2
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +6 -4
- package/src/core/state/app/state.ts +9 -0
- package/src/core/state/app/types.ts +3 -0
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +123 -0
- package/src/docs/snapshot.json +422 -112
- package/src/i18n/es.ts +30 -13
- package/src/i18n/ja.ts +30 -13
- package/src/i18n/ko.ts +30 -13
- package/src/i18n/zh-cn.ts +30 -13
- package/src/i18n/zh-tw.ts +30 -13
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/coordinator/financials.ts +10 -2
- package/src/market-data/coordinator/index.ts +3 -1
- package/src/market-data/coordinator/quotes.ts +4 -2
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +81 -11
- package/src/market-data/market/dated-previous-close.ts +203 -0
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/futures-week.ts +68 -0
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/status.ts +16 -4
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/options-alternatives.ts +60 -0
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +25 -3
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +7 -2
- package/src/market-data/selectors.ts +3 -0
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/notifications/notification-log.ts +6 -4
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +34 -20
- package/src/plugins/builtin/alerts/calendar-events.ts +429 -0
- package/src/plugins/builtin/alerts/cli.ts +533 -85
- package/src/plugins/builtin/alerts/command.ts +12 -10
- package/src/plugins/builtin/alerts/constants.ts +1 -1
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +119 -0
- package/src/plugins/builtin/alerts/format.ts +10 -3
- package/src/plugins/builtin/alerts/headless.ts +107 -41
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +92 -0
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +107 -30
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/live.ts +3 -3
- package/src/plugins/builtin/alerts/metric-command.ts +61 -0
- package/src/plugins/builtin/alerts/metric-data.ts +70 -0
- package/src/plugins/builtin/alerts/metric-model.ts +175 -0
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
- package/src/plugins/builtin/alerts/pane.tsx +130 -49
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +76 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +38 -12
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/alerts/types.ts +3 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +6 -3
- package/src/plugins/builtin/backtest/headless.ts +13 -8
- package/src/plugins/builtin/backtest/pane.tsx +9 -4
- package/src/plugins/builtin/backtest/presets.ts +29 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +24 -14
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +18 -3
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +66 -24
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +19 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +83 -10
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +111 -24
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +51 -5
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +4 -1
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +3 -2
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +7 -10
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -3
- package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +9 -4
- package/src/plugins/builtin/chart-composer/formula.ts +71 -18
- package/src/plugins/builtin/chart-composer/headless-schema.ts +42 -29
- package/src/plugins/builtin/chart-composer/headless.ts +266 -37
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +144 -30
- package/src/plugins/builtin/chart-composer/presets.ts +50 -15
- package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +31 -28
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +44 -31
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/command-suggestions.ts +92 -0
- package/src/plugins/builtin/chat/content/composer.tsx +13 -6
- package/src/plugins/builtin/chat/content/footer.tsx +6 -3
- package/src/plugins/builtin/chat/content/index.tsx +51 -22
- package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
- package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
- package/src/plugins/builtin/chat/index.tsx +23 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
- package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
- package/src/plugins/builtin/chat/pane-links/commands.ts +265 -0
- package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
- package/src/plugins/builtin/chat/pane-links/open.ts +9 -2
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/plugin.tsx +1 -1
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +79 -23
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +5 -3
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +3 -2
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +18 -11
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +144 -27
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/figures.ts +72 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +144 -27
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +34 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +87 -28
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +104 -0
- package/src/plugins/builtin/econ-statistics/view.ts +19 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +47 -12
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/charts.tsx +2 -2
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +20 -1
- package/src/plugins/builtin/exposure/pane.tsx +10 -5
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/index.tsx +1 -0
- package/src/plugins/builtin/futures/model.ts +12 -10
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +3 -3
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +20 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +37 -16
- package/src/plugins/builtin/fx-matrix/index.tsx +25 -13
- package/src/plugins/builtin/fx-matrix/live-legs.ts +34 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/headless.ts +7 -4
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +10 -4
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +51 -13
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- package/src/plugins/builtin/market-movers/footer.ts +2 -2
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +29 -8
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/breadth-pane.tsx +81 -0
- package/src/plugins/builtin/members/client.ts +19 -4
- package/src/plugins/builtin/members/headless.ts +24 -10
- package/src/plugins/builtin/members/index.tsx +9 -9
- package/src/plugins/builtin/members/model.ts +23 -4
- package/src/plugins/builtin/members/pane.tsx +31 -14
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/analytics.ts +26 -2
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +5 -2
- package/src/plugins/builtin/options/strike-window.ts +2 -1
- package/src/plugins/builtin/options/table.ts +1 -7
- package/src/plugins/builtin/options/view.tsx +30 -13
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-positioning/client.ts +19 -0
- package/src/plugins/builtin/options-positioning/headless.ts +54 -14
- package/src/plugins/builtin/options-positioning/index.tsx +3 -3
- package/src/plugins/builtin/options-positioning/model.ts +47 -8
- package/src/plugins/builtin/options-positioning/pane.tsx +68 -38
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +36 -15
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +14 -9
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +168 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +49 -26
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +54 -22
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +7 -4
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +4 -1
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/rate-path/pane.tsx +2 -2
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +80 -13
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/feed.ts +2 -2
- package/src/plugins/builtin/scanner/index.ts +24 -1
- package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
- package/src/plugins/builtin/scanner/live-feed.ts +168 -0
- package/src/plugins/builtin/scanner/live-headless.ts +114 -0
- package/src/plugins/builtin/scanner/live-model.ts +351 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
- package/src/plugins/builtin/scanner/live-track.ts +186 -0
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +3 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/macro-releases.ts +65 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +21 -0
- package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +8 -2
- package/src/plugins/builtin/shared/volatility/pricing.ts +7 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +11 -6
- package/src/plugins/builtin/themes/model.ts +15 -5
- package/src/plugins/builtin/themes/pane.tsx +27 -8
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +14 -4
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
- package/src/plugins/builtin/vol-surface/client.ts +7 -4
- package/src/plugins/builtin/vol-surface/headless.ts +71 -13
- package/src/plugins/builtin/vol-surface/index.tsx +2 -2
- package/src/plugins/builtin/vol-surface/model.ts +26 -9
- package/src/plugins/builtin/vol-surface/pane.tsx +44 -7
- package/src/plugins/builtin/vol-surface/tables.ts +31 -3
- package/src/plugins/builtin/volatility/dvol.ts +46 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/volatility/pane.tsx +2 -2
- package/src/plugins/builtin/volatility/series.ts +26 -0
- package/src/plugins/builtin/world-indices/footer.ts +1 -1
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +15 -9
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +15 -13
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +15 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/app-services.ts +1 -7
- package/src/renderers/browser/config-host.ts +5 -55
- package/src/renderers/browser/main.tsx +30 -60
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/styles.css +76 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
- package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +70 -3
- package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +36 -2
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/app-name.ts +17 -0
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +1 -1
- package/src/renderers/opentui/toast-host.tsx +71 -43
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +16 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/batches.ts +10 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +58 -15
- package/src/sources/provider-router/index.ts +146 -10
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/sources/provider-router/search.ts +13 -2
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/app/context/index.tsx +3 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/auth-transition.ts +19 -9
- package/src/sync/baseline.ts +10 -4
- package/src/sync/controller.ts +67 -17
- package/src/sync/core-contributors.ts +46 -14
- package/src/sync/react.ts +4 -1
- package/src/sync/types.ts +3 -0
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/telemetry/usage-counts.ts +0 -18
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +11 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/company-name.ts +59 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-venues.ts +23 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/bare-symbol.ts +36 -0
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +111 -33
- package/src/tickers/search/ranking.ts +64 -5
- package/src/tickers/search/types.ts +5 -0
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +315 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/daily-valuation.ts +62 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/field-catalog.ts +1 -3
- package/src/time-series/forward-valuation.ts +32 -0
- package/src/time-series/fundamentals.ts +173 -10
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/hooks.ts +1 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/price-units.ts +72 -2
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +161 -0
- package/src/time-series/resolve.ts +185 -1587
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +242 -0
- package/src/time-series/spec.ts +13 -7
- package/src/time-series/studies.ts +377 -82
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/transforms.ts +1 -0
- package/src/time-series/types.ts +34 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/time-series/valuation-releases.ts +39 -0
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +23 -1
- package/src/types/desktop-window.ts +2 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +145 -8
- package/src/types/headless.ts +117 -9
- package/src/types/instrument.ts +6 -0
- package/src/types/plugin.ts +66 -9
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +180 -0
- package/src/updater/index.ts +10 -5
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +89 -5
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +86 -0
- package/src/utils/option-expiry.ts +186 -7
- package/src/utils/options.ts +10 -0
- package/src/utils/plugin-proxy-hosts.json +1 -0
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +23 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
- package/src/renderers/browser/first-screen.ts +0 -193
|
@@ -16,15 +16,18 @@
|
|
|
16
16
|
"src/cli/pane-functions/headless.ts": ["portfolio-list"],
|
|
17
17
|
"src/cli/pane-functions/options.ts": ["ticker-detail"],
|
|
18
18
|
"src/cli/pane-functions/resolver.ts": ["chart-composer"],
|
|
19
|
+
"src/cli/pane-functions/screenshot-bridge.ts": ["time-sales"],
|
|
20
|
+
"src/cli/pane-functions/screenshot-chart-evidence.ts": ["chart-composer"],
|
|
21
|
+
"src/cli/pane-functions/screenshot-data-evidence.ts": ["chart-composer","ticker-detail"],
|
|
19
22
|
"src/cli/pane-functions/screenshot-evidence.ts": ["attention","awards","catalysts","company-attention","company-kpis","credit-documents","exposure","market-heatmap","options-calculator","options-scenario","power","realized-vol","supply-chain","vol-surface","volatility","world-venue-map"],
|
|
20
|
-
"src/cli/pane-functions/screenshot.ts": ["chart-composer","econ-statistics","market-valuation","portfolio-list","ticker-detail","time-sales"],
|
|
23
|
+
"src/cli/pane-functions/screenshot-payload.ts": ["chart-composer","econ-statistics","market-valuation","portfolio-list","ticker-detail","time-sales"],
|
|
21
24
|
"src/components/command-bar/commands/direct/index.ts": ["broker-manager"],
|
|
22
25
|
"src/components/command-bar/routes/root/help-items.ts": ["help"],
|
|
23
26
|
"src/components/command-bar/workflow/ops.ts": ["correlation","portfolio-list","ticker-detail"],
|
|
24
27
|
"src/components/layout/shell/index.tsx": ["cloud"],
|
|
25
28
|
"src/components/onboarding/use-onboarding-upgrade.ts": ["chat"],
|
|
26
29
|
"src/layout/desks.ts": ["chart-composer"],
|
|
27
|
-
"src/plugins/catalog-browser.ts": ["alerts","analytics","attention","awards","backtest","bond-calculator","catalysts","cds","central-bank-rates","changelog","chart-composer","clinical-trials","cloud","comment-letters","commodities-energy","commodity-balances","company-attention","company-kpis","connections","correlation","cot","cpi","credit-boards","credit-conditions","credit-documents","crypto-board","debt-maturities","dividend-yield","docs","doe","earnings-calls","earnings-ripple","econ","econ-statistics","equity-screener","estimate-revisions","executives","exposure","fear-greed","filing-events","fixed-income","futures","futures-curve","fx-matrix","gpu","help","insider","ipo-calendar","iv-history","jobs","jodi","kelly-sizer","layout-manager","macro-day","market-halts","market-heatmap","market-valuation","members","mna","money-markets","news","openfda","options","options-calculator","options-positioning","options-scenario","pe-band","perps","portfolio-list","power","primary-dealers","rate-path","realized-vol","relative-rotation","research","research-search","revenue-breakdown","reverse-dcf","risk-factors","scanner","seasonality","sec","sectors","short-interest","short-volume","social-mentions","supply-chain","ticker-detail","time-sales","trace-bonds","treasury-auctions","treasury-daily","vol-surface","volatility","world-indices","world-venue-map","yield-curve"],
|
|
30
|
+
"src/plugins/catalog-browser.ts": ["alerts","analytics","attention","awards","backtest","bond-calculator","catalysts","cds","central-bank-rates","changelog","chart-composer","clinical-trials","cloud","comment-letters","commodities-energy","commodity-balances","company-attention","company-kpis","connections","correlation","cot","cpi","credit-boards","credit-conditions","credit-documents","crypto-board","crypto-etf-flows","debt-maturities","dividend-yield","docs","doe","earnings","earnings-calls","earnings-ripple","econ","econ-statistics","equity-screener","estimate-revisions","executives","exposure","fear-greed","filing-events","fixed-income","futures","futures-curve","fx-matrix","gpu","help","holders","insider","ipo-calendar","iv-history","jobs","jodi","kelly-sizer","layout-manager","macro-day","market-halts","market-heatmap","market-valuation","members","mna","money-markets","news","openfda","options","options-calculator","options-positioning","options-scenario","pe-band","perps","portfolio-list","power","primary-dealers","rate-path","realized-vol","relative-rotation","research","research-search","revenue-breakdown","reverse-dcf","risk-factors","scanner","seasonality","sec","sectors","short-interest","short-volume","social-mentions","supply-chain","thirteenf","ticker-detail","time-sales","trace-bonds","treasury-auctions","treasury-daily","vol-surface","volatility","world-indices","world-venue-map","yield-curve"],
|
|
28
31
|
"src/plugins/catalog-ui.ts": ["alerts","clinical-trials","cloud","comment-letters","custom-view","fear-greed","ipo-calendar","market-halts","market-heatmap","members","news","notes","openfda","research-search"],
|
|
29
32
|
"src/plugins/catalog.ts": ["debug"],
|
|
30
33
|
"src/remote/controller.ts": ["custom-view"],
|
|
@@ -65,14 +65,14 @@
|
|
|
65
65
|
"radius": 5,
|
|
66
66
|
"spacing": 2
|
|
67
67
|
},
|
|
68
|
-
"why": "Chat has its own owner and conventions; reported, not changed
|
|
68
|
+
"why": "Chat has its own owner and conventions; reported, not changed."
|
|
69
69
|
},
|
|
70
70
|
"src/plugins/builtin/chat/content/handle-prompt.tsx": {
|
|
71
71
|
"literals": {
|
|
72
72
|
"font weight": 1,
|
|
73
73
|
"spacing": 2
|
|
74
74
|
},
|
|
75
|
-
"why": "Chat has its own owner and conventions; reported, not changed
|
|
75
|
+
"why": "Chat has its own owner and conventions; reported, not changed."
|
|
76
76
|
},
|
|
77
77
|
"src/plugins/builtin/chat/message/pane-chip.tsx": {
|
|
78
78
|
"literals": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"radius": 3,
|
|
81
81
|
"spacing": 2
|
|
82
82
|
},
|
|
83
|
-
"why": "Chat has its own owner and conventions; reported, not changed
|
|
83
|
+
"why": "Chat has its own owner and conventions; reported, not changed."
|
|
84
84
|
},
|
|
85
85
|
"src/plugins/builtin/credit-documents/gauge.tsx": {
|
|
86
86
|
"literals": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"measure": "inset",
|
|
27
27
|
"value": 7.2,
|
|
28
28
|
"component": "PaneSidebarRow",
|
|
29
|
-
"why": "Chat has its own owner: its channel rows start 7px in (reported, not changed
|
|
29
|
+
"why": "Chat has its own owner: its channel rows start 7px in (reported, not changed)."
|
|
30
30
|
}
|
|
31
31
|
],
|
|
32
32
|
"FXMD_REST_HEALTH": [
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BrokerAdapter } from "../types/broker";
|
|
2
2
|
import type { AppConfig, BrokerInstanceConfig } from "../types/config";
|
|
3
3
|
import type { Portfolio, TickerPosition, TickerRecord } from "../types/ticker";
|
|
4
|
+
import type { BrokerAccount } from "../types/trading";
|
|
4
5
|
import { buildBrokerPortfolioId, getBrokerInstance, isBrokerPortfolioId } from "../utils/broker-instances";
|
|
5
6
|
import { isSignedInBrokerProfile } from "./signed-in/profile";
|
|
6
7
|
|
|
@@ -55,6 +56,42 @@ export function isHeldByOtherSignedInProfile(
|
|
|
55
56
|
return !!owner && owner.id !== instance.id && isSignedInBrokerProfile(owner);
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* The accounts `instance` reports that another enabled profile already holds
|
|
61
|
+
* under the account's own number, such as IBKR U1234567 synced on this device
|
|
62
|
+
* and linked through SnapTrade as well. That profile keeps the account, so its
|
|
63
|
+
* portfolio and positions appear once.
|
|
64
|
+
*/
|
|
65
|
+
export function accountsHeldUnderOwnNumber(
|
|
66
|
+
config: AppConfig,
|
|
67
|
+
instance: BrokerInstanceConfig,
|
|
68
|
+
accounts: readonly BrokerAccount[],
|
|
69
|
+
): Set<string> {
|
|
70
|
+
const held = new Set(config.portfolios.flatMap((portfolio) => {
|
|
71
|
+
if (!portfolio.brokerAccountId || portfolio.brokerInstanceId === instance.id) return [];
|
|
72
|
+
const owner = getBrokerInstance(config.brokerInstances, portfolio.brokerInstanceId);
|
|
73
|
+
return owner && owner.enabled !== false ? [portfolio.brokerAccountId.trim().toUpperCase()] : [];
|
|
74
|
+
}));
|
|
75
|
+
return new Set(accounts.flatMap((account) => {
|
|
76
|
+
const number = account.brokerageAccountId?.trim().toUpperCase();
|
|
77
|
+
return number && held.has(number) ? [account.accountId] : [];
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The accounts of `instance` to list: without those another enabled profile
|
|
83
|
+
* holds under their own number (`accountsHeldUnderOwnNumber`), so an account
|
|
84
|
+
* linked twice appears once wherever accounts are chosen or shown.
|
|
85
|
+
*/
|
|
86
|
+
export function accountsShownFor(
|
|
87
|
+
config: AppConfig,
|
|
88
|
+
instance: BrokerInstanceConfig,
|
|
89
|
+
accounts: BrokerAccount[],
|
|
90
|
+
): BrokerAccount[] {
|
|
91
|
+
const held = accountsHeldUnderOwnNumber(config, instance, accounts);
|
|
92
|
+
return held.size ? accounts.filter((account) => !held.has(account.accountId)) : accounts;
|
|
93
|
+
}
|
|
94
|
+
|
|
58
95
|
/**
|
|
59
96
|
* Who keeps a portfolio when the profile holding it is removed: another
|
|
60
97
|
* enabled profile of the same broker that syncs the same account. Only a
|
package/src/brokers/directory.ts
CHANGED
|
@@ -57,6 +57,17 @@ export function brokerMethodSummary(entry: BrokerDirectoryEntry): string {
|
|
|
57
57
|
return signsIn ? t("Sign in") : t("On this device");
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* The method summary with what the broker says of itself, for a list that
|
|
62
|
+
* gives each broker a line under its name: "Sign in · Brokerages you link in
|
|
63
|
+
* SnapTrade" for one that is not itself a broker.
|
|
64
|
+
*/
|
|
65
|
+
export function brokerDirectorySummary(entry: BrokerDirectoryEntry): string {
|
|
66
|
+
const described = entry.methods.find((method) => method.kind === "signed-in")?.broker.description?.trim();
|
|
67
|
+
const summary = brokerMethodSummary(entry);
|
|
68
|
+
return described ? `${summary} · ${described}` : summary;
|
|
69
|
+
}
|
|
70
|
+
|
|
60
71
|
export function brokerMethodLabel(entry: BrokerDirectoryEntry, method: BrokerMethod): string {
|
|
61
72
|
if (method.kind === "signed-in") {
|
|
62
73
|
return entry.methods.some((candidate) => candidate.kind === "device") ? t("Sign in (recommended)") : t("Sign in");
|
package/src/brokers/logos.ts
CHANGED
|
@@ -15,11 +15,13 @@ function svg(markup: string): string {
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The marks the official plugins ship as their icon, for the same brokers
|
|
18
|
-
* when Gloom connects them, keyed by the backend's broker id.
|
|
18
|
+
* when Gloom connects them, keyed by the backend's broker id. SnapTrade has
|
|
19
|
+
* no plugin: its mark is from its own site, on white.
|
|
19
20
|
*/
|
|
20
21
|
const SIGNED_IN_BROKER_LOGOS: Readonly<Record<string, string>> = {
|
|
21
22
|
ibkr: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="t" x1="0" y1="0" x2="0" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#262626"/><stop offset="1" stop-color="#0F0F0F"/></linearGradient><linearGradient id="m" gradientUnits="userSpaceOnUse" x1="3633.335" y1="66.0445" x2="3671.0737" y2="66.0445" gradientTransform="matrix(-1 0 0 1 3673.7529 0)"><stop offset="0" stop-color="#D71F27"/><stop offset="1" stop-color="#971B1E"/></linearGradient></defs><rect width="64" height="64" fill="url(#t)"/><g transform="translate(20.4 8.2) scale(0.539)"><polygon points="40.4,86.8 2.7,86.8 2.7,45.3" fill="url(#m)"/><polygon points="40.4,1.5 2.7,45.3 2.7,86.8" fill="#D71F27"/><circle cx="35.2" cy="55.5" r="11.3" fill="#D71F27"/></g></svg>'),
|
|
22
23
|
robinhood: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#CCFF00"/><path transform="translate(14 14) scale(1.5)" d="M2.84 24h.53c.096 0 .192-.048.224-.128C7.591 13.696 11.94 8.656 14.67 5.638c.112-.128.064-.225-.096-.225h-4.88a.55.55 0 0 0-.45.225L5.746 9.972c-.514.642-.642 1.236-.642 2.086v4.43c-1.14 3.194-1.862 5.361-2.392 7.32-.032.125.016.192.129.192M20.447.646c-.754-.802-4.157-.834-5.73-.224a3 3 0 0 0-.786.465 41 41 0 0 0-3.323 3.178c-.112.113-.064.225.097.225h5.409c.497 0 .786.289.786.786v6.1c0 .16.128.208.225.064l3.258-4.254c.53-.69.69-.898.835-1.861.192-1.413.08-3.58-.77-4.479m-6.982 16.18 2.231-3.676a.7.7 0 0 0 .064-.29V6.73c0-.16-.112-.225-.224-.097-3.355 3.74-5.971 7.672-8.395 12.407-.06.12.016.225.16.177l5.009-1.54c.565-.174.882-.402 1.155-.852" fill="#1A1A1A"/></svg>'),
|
|
24
|
+
snaptrade: svg('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="a" x1="14" y1="-33.2" x2="39.35" y2="10.81" gradientUnits="userSpaceOnUse"><stop stop-color="#045856"/><stop offset="1" stop-color="#52C4C2"/></linearGradient><linearGradient id="b" x1="14.33" y1="34.34" x2="-24.58" y2="-4.39" gradientUnits="userSpaceOnUse"><stop stop-color="#E6960D"/><stop offset=".27" stop-color="#F2CA86"/></linearGradient><linearGradient id="c" x1="1.95" y1="33.87" x2="-32.55" y2="-6.92" gradientUnits="userSpaceOnUse"><stop stop-color="#E6960D"/><stop offset=".27" stop-color="#F2CA86"/></linearGradient></defs><rect width="64" height="64" fill="#FFFFFF"/><g transform="translate(12.4 10.45) scale(1.4)"><path d="M27.47 11.24 27.11 10.62 22.55 2.73C21.96 1.72 20.88 1.09 19.7 1.09H11.12C9.95 1.09 8.86 1.72 8.28 2.73L3.71 10.62 8.28 18.51C8.86 19.53 9.95 20.15 11.12 20.15H15.42L9.9 10.62 15.41 1.1 20.92 10.62 25.32 18.23 27.46 14.52C28.05 13.5 28.05 12.25 27.46 11.24Z" fill="url(#a)"/><path d="M24.21 20.15 19.64 12.26C19.06 11.25 17.97 10.62 16.8 10.62H12.5L18.01 20.15 12.5 29.69H16.8C17.97 29.69 19.06 29.06 19.64 28.05Z" fill="url(#b)"/><path d="M6.99 20.15 2.59 12.54.44 16.26C-.15 17.27-.15 18.52.44 19.54L.8 20.15 5.36 28.05C5.95 29.06 7.03 29.69 8.21 29.69H12.5L6.99 20.15Z" fill="url(#c)"/></g></svg>'),
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
/** The plugin icon of a broker adapter (`getBrokerLogo` on the plugin runtime). */
|
|
@@ -10,12 +10,15 @@ import { ApiRequestError } from "../../api-client/errors";
|
|
|
10
10
|
import { openUrl } from "../../components/ui/external-link";
|
|
11
11
|
import type { BrokerAdapter, BrokerConnectionStatus, BrokerPosition } from "../../types/broker";
|
|
12
12
|
import type { BrokerInstanceConfig } from "../../types/config";
|
|
13
|
+
import type { Quote } from "../../types/financials";
|
|
13
14
|
import type {
|
|
14
15
|
BrokerAccount,
|
|
15
16
|
BrokerExecution,
|
|
16
17
|
BrokerOrder,
|
|
18
|
+
BrokerOrderPreview,
|
|
17
19
|
BrokerOrderRequest,
|
|
18
20
|
BrokerPortfolioPerformance,
|
|
21
|
+
BrokerTradingCapabilities,
|
|
19
22
|
} from "../../types/trading";
|
|
20
23
|
import { findSignedInBroker, refreshSignedInBrokers } from "./catalog";
|
|
21
24
|
import type { SignedInBroker, SignedInBrokerConnection } from "./client";
|
|
@@ -47,16 +50,50 @@ function brokerReason(lastError: string | null | undefined): string | null {
|
|
|
47
50
|
return described.replace(/[\s.]+$/, "").slice(0, 200) || null;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
/**
|
|
51
|
-
|
|
53
|
+
/** Gloom holds no live sign-in for the broker: only connecting again helps. */
|
|
54
|
+
class SignInNeededError extends Error {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* What to tell the user when Gloom answers a broker call with an error, and
|
|
58
|
+
* whether only a new sign-in, to Gloom or the broker, gets the profile going.
|
|
59
|
+
*/
|
|
60
|
+
function describeSignedInBrokerError(error: unknown, brokerName: string): { message: string; needsSignIn: boolean } {
|
|
52
61
|
const status = error instanceof ApiRequestError ? error.status : undefined;
|
|
53
|
-
if (status === 401) return `Sign in to Gloom first, then connect ${brokerName}
|
|
62
|
+
if (status === 401) return { message: `Sign in to Gloom first, then connect ${brokerName}.`, needsSignIn: true };
|
|
54
63
|
const signInAgain = `${brokerName} needs you to sign in again. Press Connect in Brokers.`;
|
|
55
64
|
// A sign-in the broker ended says why, in Gloom's words.
|
|
56
|
-
if (status === 409) return (error instanceof ApiRequestError && writtenMessage(error)) || signInAgain;
|
|
57
|
-
if (status === 404) return signInAgain;
|
|
58
|
-
if (status === 502) return `${brokerName} is not responding. Try again shortly
|
|
59
|
-
|
|
65
|
+
if (status === 409) return { message: (error instanceof ApiRequestError && writtenMessage(error)) || signInAgain, needsSignIn: true };
|
|
66
|
+
if (status === 404) return { message: signInAgain, needsSignIn: true };
|
|
67
|
+
if (status === 502) return { message: `${brokerName} is not responding. Try again shortly.`, needsSignIn: false };
|
|
68
|
+
// A refused order or a busy broker says why without its error code.
|
|
69
|
+
if (error instanceof ApiRequestError && (status === 403 || status === 422 || status === 503)) {
|
|
70
|
+
return { message: writtenMessage(error) ?? error.message, needsSignIn: false };
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
message: error instanceof Error && error.message ? error.message : String(error),
|
|
74
|
+
needsSignIn: error instanceof SignInNeededError,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gloom answered an order action and nothing was placed, changed or
|
|
80
|
+
* cancelled: the broker refused it, its check lapsed, trading is not granted,
|
|
81
|
+
* the broker was too busy to take it, or the sign-in has to be renewed. A
|
|
82
|
+
* 502 or a lost answer may have reached the broker, so it is not one.
|
|
83
|
+
*/
|
|
84
|
+
function refusedOrderAction(error: unknown): boolean {
|
|
85
|
+
if (!(error instanceof ApiRequestError)) return false;
|
|
86
|
+
return error.status !== undefined && error.status >= 400 && error.status < 500 || error.status === 503;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** A sign-in that ended or was never made, as opposed to a refused order: the profile's status says so. */
|
|
90
|
+
function signInLost(error: unknown): boolean {
|
|
91
|
+
if (!(error instanceof ApiRequestError)) return false;
|
|
92
|
+
return error.status === 401 || error.status === 404 || error.status === 409 && error.code === "reauth_required";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function refused(message: string): Error {
|
|
96
|
+
return Object.assign(new Error(message), { refused: true });
|
|
60
97
|
}
|
|
61
98
|
|
|
62
99
|
/** The broker does not offer this. A broker tool that failed is also a 422, but a failure. */
|
|
@@ -67,7 +104,7 @@ function isUnsupported(error: unknown): boolean {
|
|
|
67
104
|
type BrokerRequest = <T>(
|
|
68
105
|
broker: string,
|
|
69
106
|
path: string,
|
|
70
|
-
options?: { method?: "GET" | "POST" | "DELETE"; body?: unknown },
|
|
107
|
+
options?: { method?: "GET" | "POST" | "PUT" | "DELETE"; body?: unknown },
|
|
71
108
|
) => Promise<T>;
|
|
72
109
|
|
|
73
110
|
export interface SignedInBrokerAdapterDeps {
|
|
@@ -84,6 +121,60 @@ interface PortfolioSnapshot {
|
|
|
84
121
|
fetchedAt?: number;
|
|
85
122
|
}
|
|
86
123
|
|
|
124
|
+
/** Gloom's answer to a direct-mode order, before the user confirms it. */
|
|
125
|
+
interface DirectOrderPreview {
|
|
126
|
+
status: "preview";
|
|
127
|
+
previewId: string;
|
|
128
|
+
expiresAt: string;
|
|
129
|
+
impact: {
|
|
130
|
+
source: "broker" | "unavailable";
|
|
131
|
+
sourceLabel: string;
|
|
132
|
+
currency?: string;
|
|
133
|
+
estimatedCost?: number;
|
|
134
|
+
cashBefore?: number;
|
|
135
|
+
cashAfter?: number;
|
|
136
|
+
commission?: number;
|
|
137
|
+
fees?: number;
|
|
138
|
+
disclosure: string;
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface PlacedOrder { status: "placed"; order: BrokerOrder }
|
|
143
|
+
|
|
144
|
+
/** The quote a direct-mode broker gives the ticket. */
|
|
145
|
+
interface SignedInBrokerQuote {
|
|
146
|
+
symbol: string;
|
|
147
|
+
name?: string;
|
|
148
|
+
currency?: string;
|
|
149
|
+
price: number;
|
|
150
|
+
bid?: number;
|
|
151
|
+
ask?: number;
|
|
152
|
+
bidSize?: number;
|
|
153
|
+
askSize?: number;
|
|
154
|
+
lastTradePrice?: number;
|
|
155
|
+
lastUpdated: number;
|
|
156
|
+
dataSource: "live" | "delayed";
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** The same order always keys the same, whatever order its fields arrive in. */
|
|
160
|
+
function canonical(value: unknown): string {
|
|
161
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
162
|
+
if (value && typeof value === "object") {
|
|
163
|
+
return `{${Object.entries(value).filter(([, entry]) => entry !== undefined).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
164
|
+
.map(([key, entry]) => `${JSON.stringify(key)}:${canonical(entry)}`).join(",")}}`;
|
|
165
|
+
}
|
|
166
|
+
return JSON.stringify(value) ?? "null";
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** The ticket's fields, without the profile's own, as Gloom checks and places the order. */
|
|
170
|
+
function orderBody(request: BrokerOrderRequest): BrokerOrderRequest {
|
|
171
|
+
const { brokerInstanceId: _profile, ...body } = request;
|
|
172
|
+
const { brokerInstanceId: _contractProfile, ...contract } = body.contract;
|
|
173
|
+
return { ...body, contract };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const DIRECT_TIF = ["DAY"];
|
|
177
|
+
|
|
87
178
|
export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAdapterDeps> = {}): BrokerAdapter {
|
|
88
179
|
const deps: SignedInBrokerAdapterDeps = {
|
|
89
180
|
request: (broker, path, options) => apiClient.brokerRequest(broker, path, options),
|
|
@@ -95,12 +186,29 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
95
186
|
};
|
|
96
187
|
const statuses = new Map<string, BrokerConnectionStatus>();
|
|
97
188
|
const listeners = new Map<string, Set<() => void>>();
|
|
189
|
+
/** Whether each profile's sign-in granted trading, as its last connect read it. */
|
|
190
|
+
const canTrade = new Map<string, boolean>();
|
|
191
|
+
/** Direct mode: the check the user is reviewing, per profile, by the exact order it was for. */
|
|
192
|
+
const previews = new Map<string, { order: string; previewId: string; expiresAt: number }>();
|
|
193
|
+
/** Direct mode: the broker's own id behind each order number the app holds, per profile. */
|
|
194
|
+
const handles = new Map<string, Map<number, { accountId: string; brokerOrderId: string }>>();
|
|
98
195
|
|
|
99
196
|
const brokerName = (instance: BrokerInstanceConfig) =>
|
|
100
197
|
deps.findBroker(signedInBrokerId(instance))?.name ?? instance.label;
|
|
101
198
|
|
|
102
|
-
|
|
103
|
-
|
|
199
|
+
/** The broker's direct-mode orders, or null for one that keeps orders for review or takes none. */
|
|
200
|
+
const directOrders = (instance: BrokerInstanceConfig) => {
|
|
201
|
+
const orders = deps.findBroker(signedInBrokerId(instance))?.capabilities.orders;
|
|
202
|
+
return orders && orders.mode === "direct" ? orders : null;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const setStatus = (instance: BrokerInstanceConfig, state: "connected" | "error", message?: string, needsSignIn = false) => {
|
|
206
|
+
statuses.set(instance.id, {
|
|
207
|
+
state, message, mode: METHOD, updatedAt: deps.now(),
|
|
208
|
+
...(needsSignIn ? { needsSignIn } : {}),
|
|
209
|
+
// A direct-mode broker says per quote whether it is real-time.
|
|
210
|
+
...(directOrders(instance) ? { quoteData: "realtime" as const } : {}),
|
|
211
|
+
});
|
|
104
212
|
for (const listener of listeners.get(instance.id) ?? []) listener();
|
|
105
213
|
};
|
|
106
214
|
|
|
@@ -111,8 +219,8 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
111
219
|
setStatus(instance, "connected");
|
|
112
220
|
return result;
|
|
113
221
|
} catch (error) {
|
|
114
|
-
const message = describeSignedInBrokerError(error, brokerName(instance));
|
|
115
|
-
setStatus(instance, "error", message);
|
|
222
|
+
const { message, needsSignIn } = describeSignedInBrokerError(error, brokerName(instance));
|
|
223
|
+
setStatus(instance, "error", message, needsSignIn);
|
|
116
224
|
throw new Error(message);
|
|
117
225
|
}
|
|
118
226
|
};
|
|
@@ -130,7 +238,51 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
130
238
|
const snapshot = (instance: BrokerInstanceConfig) =>
|
|
131
239
|
track(instance, () => get<PortfolioSnapshot>(instance, "/snapshot"));
|
|
132
240
|
|
|
133
|
-
/**
|
|
241
|
+
/**
|
|
242
|
+
* An order as the app holds it: this profile's, under this adapter, and
|
|
243
|
+
* remembered by its number so a change or cancel can name it to the broker.
|
|
244
|
+
*/
|
|
245
|
+
const ownOrder = (instance: BrokerInstanceConfig, order: BrokerOrder): BrokerOrder => {
|
|
246
|
+
if (order.brokerOrderId && order.accountId) {
|
|
247
|
+
const known = handles.get(instance.id) ?? new Map();
|
|
248
|
+
known.set(order.orderId, { accountId: order.accountId, brokerOrderId: order.brokerOrderId });
|
|
249
|
+
handles.set(instance.id, known);
|
|
250
|
+
}
|
|
251
|
+
return { ...order, brokerInstanceId: instance.id, contract: { ...order.contract, brokerId: SIGNED_IN_BROKER_TYPE, brokerInstanceId: instance.id } };
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* One order action. A refusal leaves the profile's status alone (the
|
|
256
|
+
* broker is fine; the order is not) and is marked refused; a sign-in that
|
|
257
|
+
* ended shows on the profile as any failed call does.
|
|
258
|
+
*/
|
|
259
|
+
const orderAction = async <T>(instance: BrokerInstanceConfig, run: () => Promise<T>): Promise<T> => {
|
|
260
|
+
try {
|
|
261
|
+
const result = await run();
|
|
262
|
+
setStatus(instance, "connected");
|
|
263
|
+
return result;
|
|
264
|
+
} catch (error) {
|
|
265
|
+
const { message, needsSignIn } = describeSignedInBrokerError(error, brokerName(instance));
|
|
266
|
+
if (signInLost(error)) setStatus(instance, "error", message, needsSignIn);
|
|
267
|
+
throw refusedOrderAction(error) ? refused(message) : new Error(message);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/** The broker's id for an order number; nothing is sent when it cannot be found. */
|
|
272
|
+
const brokerOrderHandle = async (instance: BrokerInstanceConfig, orderId: number) => {
|
|
273
|
+
const known = handles.get(instance.id)?.get(orderId);
|
|
274
|
+
if (known) return known;
|
|
275
|
+
try {
|
|
276
|
+
for (const order of await get<BrokerOrder[]>(instance, "/orders")) ownOrder(instance, order);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
throw refused(describeSignedInBrokerError(error, brokerName(instance)).message);
|
|
279
|
+
}
|
|
280
|
+
const found = handles.get(instance.id)?.get(orderId);
|
|
281
|
+
if (!found) throw refused("This order is no longer listed. Refresh your orders.");
|
|
282
|
+
return found;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/** Checks an order against what the broker takes, before Gloom sees it: a failure sent nothing. */
|
|
134
286
|
const checkOrder = async (instance: BrokerInstanceConfig, request: BrokerOrderRequest) => {
|
|
135
287
|
const id = signedInBrokerId(instance);
|
|
136
288
|
let broker = deps.findBroker(id);
|
|
@@ -140,14 +292,25 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
140
292
|
}
|
|
141
293
|
const name = broker?.name ?? instance.label;
|
|
142
294
|
const orders = broker?.capabilities.orders;
|
|
143
|
-
if (!orders) throw
|
|
295
|
+
if (!orders) throw refused(`${name} does not take orders from Gloom.`);
|
|
144
296
|
if (!orders.types.includes(request.orderType)) {
|
|
145
|
-
throw
|
|
297
|
+
throw refused(`${name} does not take ${request.orderType} orders from Gloom.`);
|
|
298
|
+
}
|
|
299
|
+
// A server that does not say it takes a bracket, an OCO pair or a trailing stop would drop its fields and place a bare
|
|
300
|
+
// order: never send one it has not named.
|
|
301
|
+
if (!request.orderClass && (request.takeProfitPrice !== undefined || request.stopLossPrice !== undefined)) {
|
|
302
|
+
throw refused("A take profit or stop loss needs a bracket or OCO order.");
|
|
303
|
+
}
|
|
304
|
+
if (request.orderClass && !orders.orderClasses?.includes(request.orderClass)) {
|
|
305
|
+
throw refused(`${name} does not take ${request.orderClass === "oco" ? "OCO" : "bracket"} orders from Gloom.`);
|
|
306
|
+
}
|
|
307
|
+
if (request.orderType === "TRAIL" && !orders.trailing?.includes(request.trailingPercent !== undefined ? "percent" : "amount")) {
|
|
308
|
+
throw refused(`${name} does not take this trailing stop from Gloom.`);
|
|
146
309
|
}
|
|
147
|
-
if (!(request.quantity > 0)) throw
|
|
310
|
+
if (!(request.quantity > 0)) throw refused("Quantity must be positive.");
|
|
148
311
|
const needsLimit = request.orderType === "LMT" || request.orderType === "STP LMT";
|
|
149
312
|
if (needsLimit && !(typeof request.limitPrice === "number" && request.limitPrice > 0)) {
|
|
150
|
-
throw
|
|
313
|
+
throw refused("A limit order needs a limit price.");
|
|
151
314
|
}
|
|
152
315
|
return { name, mode: orders.mode };
|
|
153
316
|
};
|
|
@@ -156,6 +319,8 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
156
319
|
id: SIGNED_IN_BROKER_TYPE,
|
|
157
320
|
name: "Signed-in broker",
|
|
158
321
|
configSchema: [],
|
|
322
|
+
// A signed-in broker's quotes come through Gloom and count against the broker's allowance.
|
|
323
|
+
ticketQuotesOnly: true,
|
|
159
324
|
|
|
160
325
|
async validate() {
|
|
161
326
|
return true;
|
|
@@ -191,17 +356,51 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
191
356
|
return getOptional<BrokerExecution[]>(instance, "/executions?period=DAYS_90", []);
|
|
192
357
|
},
|
|
193
358
|
|
|
194
|
-
listOpenOrders(instance) {
|
|
195
|
-
return getOptional<BrokerOrder[]>(instance, "/orders", []);
|
|
359
|
+
async listOpenOrders(instance) {
|
|
360
|
+
return (await getOptional<BrokerOrder[]>(instance, "/orders", [])).map((order) => ownOrder(instance, order));
|
|
196
361
|
},
|
|
197
362
|
|
|
198
363
|
async previewOrder(instance, request) {
|
|
199
364
|
const { name, mode } = await checkOrder(instance, request);
|
|
200
|
-
|
|
365
|
+
if (mode === "review") return { warningText: `${name} opens this order for you to review and submit.` };
|
|
366
|
+
const answer = await orderAction(instance, () => deps.request<DirectOrderPreview>(
|
|
367
|
+
signedInBrokerId(instance),
|
|
368
|
+
"/orders",
|
|
369
|
+
{ method: "POST", body: orderBody(request) },
|
|
370
|
+
));
|
|
371
|
+
previews.set(instance.id, { order: canonical(orderBody(request)), previewId: answer.previewId, expiresAt: Date.parse(answer.expiresAt) });
|
|
372
|
+
const { impact } = answer;
|
|
373
|
+
const preview: BrokerOrderPreview = {
|
|
374
|
+
impactSource: impact.source,
|
|
375
|
+
impactSourceLabel: impact.sourceLabel,
|
|
376
|
+
disclosure: impact.disclosure,
|
|
377
|
+
currency: impact.currency,
|
|
378
|
+
estimatedCost: impact.estimatedCost,
|
|
379
|
+
commission: impact.commission,
|
|
380
|
+
commissionCurrency: impact.commission === undefined ? undefined : impact.currency,
|
|
381
|
+
fees: impact.fees,
|
|
382
|
+
cashBefore: impact.cashBefore,
|
|
383
|
+
cashAfter: impact.cashAfter,
|
|
384
|
+
};
|
|
385
|
+
return Object.fromEntries(Object.entries(preview).filter(([, value]) => value !== undefined)) as BrokerOrderPreview;
|
|
201
386
|
},
|
|
202
387
|
|
|
203
388
|
async placeOrder(instance, request) {
|
|
204
|
-
const { name } = await checkOrder(instance, request);
|
|
389
|
+
const { name, mode } = await checkOrder(instance, request);
|
|
390
|
+
if (mode === "direct") {
|
|
391
|
+
// Only the order the user reviewed, while its check stands.
|
|
392
|
+
const preview = previews.get(instance.id);
|
|
393
|
+
if (!preview || preview.order !== canonical(orderBody(request)) || !(preview.expiresAt > deps.now())) {
|
|
394
|
+
throw refused("Review this order again before placing it.");
|
|
395
|
+
}
|
|
396
|
+
const placed = await orderAction(instance, () => deps.request<PlacedOrder>(
|
|
397
|
+
signedInBrokerId(instance),
|
|
398
|
+
"/orders",
|
|
399
|
+
{ method: "POST", body: { ...orderBody(request), previewId: preview.previewId } },
|
|
400
|
+
));
|
|
401
|
+
previews.delete(instance.id);
|
|
402
|
+
return ownOrder(instance, placed.order);
|
|
403
|
+
}
|
|
205
404
|
const placed = await track(instance, () => deps.request<{ status: string; id: string; reviewUrl: string }>(
|
|
206
405
|
signedInBrokerId(instance),
|
|
207
406
|
"/orders",
|
|
@@ -228,23 +427,102 @@ export function createSignedInBrokerAdapter(overrides: Partial<SignedInBrokerAda
|
|
|
228
427
|
};
|
|
229
428
|
},
|
|
230
429
|
|
|
231
|
-
async modifyOrder(instance) {
|
|
430
|
+
async modifyOrder(instance, orderId, request) {
|
|
431
|
+
const { name, mode } = await checkOrder(instance, request);
|
|
432
|
+
if (mode !== "direct") throw refused(`Orders sent to ${name} are managed in ${name}.`);
|
|
433
|
+
const handle = await brokerOrderHandle(instance, orderId);
|
|
434
|
+
const changed = await orderAction(instance, () => deps.request<PlacedOrder>(
|
|
435
|
+
signedInBrokerId(instance),
|
|
436
|
+
`/orders/${encodeURIComponent(handle.brokerOrderId)}`,
|
|
437
|
+
{ method: "PUT", body: { ...orderBody(request), accountId: handle.accountId } },
|
|
438
|
+
));
|
|
439
|
+
return ownOrder(instance, changed.order);
|
|
440
|
+
},
|
|
441
|
+
|
|
442
|
+
async cancelOrder(instance, orderId) {
|
|
232
443
|
const name = brokerName(instance);
|
|
233
|
-
throw
|
|
444
|
+
if (!directOrders(instance)) throw refused(`Orders sent to ${name} are managed in ${name}.`);
|
|
445
|
+
const handle = await brokerOrderHandle(instance, orderId);
|
|
446
|
+
await orderAction(instance, () => deps.request<{ cancelled: boolean }>(
|
|
447
|
+
signedInBrokerId(instance),
|
|
448
|
+
`/orders/${encodeURIComponent(handle.brokerOrderId)}?accountId=${encodeURIComponent(handle.accountId)}`,
|
|
449
|
+
{ method: "DELETE" },
|
|
450
|
+
));
|
|
234
451
|
},
|
|
235
452
|
|
|
236
|
-
|
|
453
|
+
/**
|
|
454
|
+
* Direct mode only: what the ticket offers. Trading needs the profile
|
|
455
|
+
* switched on and a sign-in that granted it; the broker's linked
|
|
456
|
+
* account may still be read-only, which its check then says.
|
|
457
|
+
*/
|
|
458
|
+
getTradingCapabilities(instance) {
|
|
237
459
|
const name = brokerName(instance);
|
|
238
|
-
|
|
460
|
+
const orders = directOrders(instance);
|
|
461
|
+
if (!orders) {
|
|
462
|
+
return { enabled: false, disabledReason: `${name} does not take orders from the ticket.`, orderTypes: [], tif: [] };
|
|
463
|
+
}
|
|
464
|
+
const granted = canTrade.get(instance.id) === true;
|
|
465
|
+
const switchedOn = instance.config.tradingEnabled === true;
|
|
466
|
+
const capabilities: BrokerTradingCapabilities = {
|
|
467
|
+
enabled: granted && switchedOn,
|
|
468
|
+
orderTypes: [...orders.types],
|
|
469
|
+
tif: orders.tif?.length ? [...orders.tif] : DIRECT_TIF,
|
|
470
|
+
...(orders.orderClasses?.length ? { orderClasses: [...orders.orderClasses] } : {}),
|
|
471
|
+
...(orders.trailing?.length ? { trailing: [...orders.trailing] } : {}),
|
|
472
|
+
minQuantity: 1,
|
|
473
|
+
quantityStep: 1,
|
|
474
|
+
modify: true,
|
|
475
|
+
cancel: true,
|
|
476
|
+
executionKind: "order-summaries",
|
|
477
|
+
};
|
|
478
|
+
if (!granted) capabilities.disabledReason = `${name} is connected read-only. Connect it again in Brokers to allow trading.`;
|
|
479
|
+
else if (!switchedOn) capabilities.disabledReason = "Trading is off for this profile.";
|
|
480
|
+
return capabilities;
|
|
481
|
+
},
|
|
482
|
+
|
|
483
|
+
getTradingConfigUpdate(_instance, enabled) {
|
|
484
|
+
return { tradingEnabled: enabled };
|
|
485
|
+
},
|
|
486
|
+
|
|
487
|
+
// The ticket's quote. A symbol the broker cannot price, or its request
|
|
488
|
+
// allowance spent, is the ticket's to say; only a lost sign-in is the profile's.
|
|
489
|
+
async getQuote(ticker, instance) {
|
|
490
|
+
const id = signedInBrokerId(instance);
|
|
491
|
+
if (!directOrders(instance)) throw new Error(`${brokerName(instance)} gives no quotes to the ticket.`);
|
|
492
|
+
const answer = await orderAction(instance, () => deps.request<SignedInBrokerQuote>(
|
|
493
|
+
id,
|
|
494
|
+
`/quote?symbol=${encodeURIComponent(ticker.trim().toUpperCase())}`,
|
|
495
|
+
));
|
|
496
|
+
const quote: Quote = {
|
|
497
|
+
symbol: answer.symbol,
|
|
498
|
+
name: answer.name,
|
|
499
|
+
price: answer.price,
|
|
500
|
+
bid: answer.bid,
|
|
501
|
+
ask: answer.ask,
|
|
502
|
+
bidSize: answer.bidSize,
|
|
503
|
+
askSize: answer.askSize,
|
|
504
|
+
currency: answer.currency ?? "USD",
|
|
505
|
+
// The broker gives no prior close: no change to show.
|
|
506
|
+
change: Number.NaN,
|
|
507
|
+
changePercent: Number.NaN,
|
|
508
|
+
changeBasis: "none",
|
|
509
|
+
lastUpdated: answer.lastUpdated,
|
|
510
|
+
receivedAt: deps.now(),
|
|
511
|
+
dataSource: answer.dataSource,
|
|
512
|
+
delivery: "poll",
|
|
513
|
+
providerId: id,
|
|
514
|
+
};
|
|
515
|
+
return quote;
|
|
239
516
|
},
|
|
240
517
|
|
|
241
518
|
async connect(instance) {
|
|
242
519
|
await track(instance, async () => {
|
|
243
520
|
const connection = await get<SignedInBrokerConnection>(instance, "");
|
|
521
|
+
canTrade.set(instance.id, connection.status === "connected" && connection.canTrade === true);
|
|
244
522
|
if (connection.status !== "connected") {
|
|
245
523
|
const name = brokerName(instance);
|
|
246
524
|
const reason = brokerReason(connection.lastError);
|
|
247
|
-
throw new
|
|
525
|
+
throw new SignInNeededError(reason
|
|
248
526
|
? `${name} needs you to sign in again: ${reason}. Press Connect in Brokers.`
|
|
249
527
|
: `Press Connect in Brokers to sign in to ${name}.`);
|
|
250
528
|
}
|
|
@@ -4,12 +4,22 @@
|
|
|
4
4
|
* appears here without an app release.
|
|
5
5
|
*/
|
|
6
6
|
import { apiClient } from "../../api-client";
|
|
7
|
-
import type { BrokerOrderType } from "../../types/trading";
|
|
7
|
+
import type { BrokerOrderClass, BrokerOrderType, BrokerTrailingUnit } from "../../types/trading";
|
|
8
8
|
|
|
9
9
|
interface SignedInBrokerCapabilities {
|
|
10
10
|
history: boolean;
|
|
11
11
|
executions: boolean;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Review: the broker keeps each order for the user to submit there. Direct: Gloom checks the
|
|
14
|
+
* order with the broker, the user confirms that check in the ticket, and Gloom places it.
|
|
15
|
+
*/
|
|
16
|
+
orders: false | {
|
|
17
|
+
mode: "review" | "direct"; types: BrokerOrderType[]; tif?: string[];
|
|
18
|
+
/** Brackets and OCO pairs the broker places and runs itself; absent from a server that sends none. */
|
|
19
|
+
orderClasses?: BrokerOrderClass[];
|
|
20
|
+
/** How a trailing stop (`TRAIL` in `types`) is set. */
|
|
21
|
+
trailing?: BrokerTrailingUnit[];
|
|
22
|
+
};
|
|
13
23
|
/** Connecting Gloom replaces this broker's link to other AI apps. */
|
|
14
24
|
singleConnection: boolean;
|
|
15
25
|
/** Shown before connecting, e.g. an account the user must create first. */
|
|
@@ -19,6 +29,8 @@ interface SignedInBrokerCapabilities {
|
|
|
19
29
|
export interface SignedInBroker {
|
|
20
30
|
id: string;
|
|
21
31
|
name: string;
|
|
32
|
+
/** Under the name where brokers are listed, for one that is not itself a broker (SnapTrade). */
|
|
33
|
+
description?: string;
|
|
22
34
|
capabilities: SignedInBrokerCapabilities;
|
|
23
35
|
}
|
|
24
36
|
|