gloomberb 0.18.0 → 0.18.2
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/package.json +1 -1
- package/src/api-client/commodity-balances.ts +6 -0
- package/src/api-client/company-kpis.ts +9 -0
- package/src/api-client/crypto-markets.ts +9 -0
- package/src/api-client/data.ts +6 -5
- package/src/api-client/equity-screener.ts +2 -0
- package/src/api-client/market-movers.ts +7 -0
- package/src/api-client/types.ts +14 -0
- package/src/app/pane-runtime/plugin-bindings.ts +3 -1
- package/src/app/pane-runtime/ticker-open-runtime.ts +17 -5
- package/src/app/runtime/plugin-bindings.ts +6 -2
- package/src/brokers/logos.ts +66 -0
- package/src/brokers/profile-form.ts +3 -0
- package/src/brokers/remote-broker-adapter.ts +13 -3
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/service-capabilities.ts +7 -1
- package/src/cli/base-converter.ts +60 -18
- package/src/cli/commands/fred-series.ts +15 -5
- package/src/cli/commands/market.ts +290 -159
- package/src/cli/commands/news-search.ts +35 -8
- package/src/cli/commands/overview.ts +31 -6
- package/src/cli/commands/system.ts +35 -1
- package/src/cli/commands/ticker.ts +105 -52
- package/src/cli/currency-hints.ts +27 -0
- package/src/cli/fx-pair.ts +41 -4
- package/src/cli/glossary.ts +57 -4
- package/src/cli/helpers.ts +36 -3
- package/src/cli/index.ts +4 -1
- package/src/cli/known-gaps.ts +37 -1
- package/src/cli/listing-arg.ts +37 -2
- package/src/cli/pane-functions/catalog.ts +3 -1
- package/src/cli/pane-functions/discovery.ts +15 -1
- package/src/cli/pane-functions/dom.ts +9 -4
- package/src/cli/pane-functions/freshness.ts +4 -4
- package/src/cli/pane-functions/function-help.ts +31 -7
- package/src/cli/pane-functions/headless.ts +6 -5
- package/src/cli/pane-functions/index.ts +3 -2
- package/src/cli/pane-functions/lock-note.ts +7 -4
- package/src/cli/pane-functions/resolver.ts +2 -1
- package/src/cli/quote-answer.ts +179 -0
- package/src/cli/series-search.ts +2 -1
- package/src/cli/symbol-list.ts +51 -16
- package/src/cli/types.ts +4 -0
- package/src/components/chart/composite/composite-chart.tsx +22 -7
- package/src/components/chart/composite/format.ts +13 -1
- package/src/components/chart/composite/level-labels.ts +30 -0
- package/src/components/chart/composite/levels.ts +17 -6
- package/src/components/chart/composite/panel-surface.tsx +64 -16
- package/src/components/chart/composite/price-axis-labels.tsx +2 -1
- package/src/components/chart/composite/types.ts +4 -0
- package/src/components/command-bar/routes/ticker-search/actions.ts +6 -0
- package/src/components/command-bar/workflow/collection-actions.ts +4 -0
- package/src/components/index.ts +2 -0
- package/src/components/layout/pane/content.tsx +16 -14
- package/src/components/layout/pane/footer/index.tsx +22 -3
- package/src/components/layout/pane/footer/model.ts +99 -4
- package/src/components/layout/pane/header-tabs.tsx +15 -1
- package/src/components/onboarding/onboarding-frame.tsx +9 -11
- package/src/components/onboarding/use-onboarding-broker-form.ts +5 -2
- package/src/components/onboarding/wizard-model.ts +10 -3
- package/src/components/onboarding/wizard-positions.ts +8 -0
- package/src/components/ui/button.tsx +11 -4
- package/src/components/ui/choice-dialog.tsx +8 -5
- package/src/components/ui/display.tsx +11 -6
- package/src/components/ui/fields.tsx +100 -20
- package/src/components/ui/icon.tsx +6 -1
- package/src/components/ui/list-row-lines.tsx +87 -0
- package/src/components/ui/list-view.tsx +14 -0
- package/src/components/ui/logo-mark.tsx +64 -0
- package/src/components/ui/number-step.ts +54 -0
- package/src/components/ui/select-button.tsx +5 -4
- package/src/components/ui/select-field.tsx +3 -3
- package/src/components/ui/status.tsx +17 -3
- package/src/components/ui/tabs.tsx +9 -1
- package/src/components/ui/toggle.tsx +17 -3
- package/src/core/state/app/instrument.ts +8 -3
- package/src/data/config/store/normalize.ts +4 -1
- package/src/data/plugin-cache.ts +32 -6
- package/src/docs/snapshot.json +57 -22
- package/src/i18n/es.ts +9 -3
- package/src/i18n/ja.ts +9 -3
- package/src/i18n/ko.ts +9 -3
- package/src/i18n/zh-cn.ts +10 -4
- package/src/i18n/zh-tw.ts +10 -4
- package/src/market-data/commodity-names.ts +80 -0
- package/src/market-data/coordinator/auxiliary.ts +3 -1
- package/src/market-data/coordinator/chart.ts +3 -1
- package/src/market-data/futures-board.ts +38 -1
- package/src/market-data/futures-contract.ts +91 -0
- package/src/market-data/fx-closes.ts +78 -1
- package/src/market-data/market/change-basis.ts +219 -0
- package/src/market-data/market/format.ts +28 -12
- package/src/market-data/market/freshness.ts +38 -0
- package/src/market-data/market/status.ts +55 -9
- package/src/market-data/market/year-to-date.ts +46 -0
- package/src/market-data/quotes/contributions.ts +12 -0
- package/src/market-data/quotes/delisting.ts +34 -0
- package/src/market-data/quotes/live-valuation.ts +23 -0
- package/src/market-data/quotes/resolution.ts +8 -2
- package/src/market-data/tax-equivalent.ts +10 -2
- package/src/notifications/app-notifier.ts +2 -2
- package/src/notifications/notification-log.ts +8 -6
- package/src/plugins/builtin/alerts/cli.ts +26 -18
- package/src/plugins/builtin/alerts/headless.ts +1 -1
- package/src/plugins/builtin/alerts/index.tsx +13 -4
- package/src/plugins/builtin/analytics/index.tsx +1 -1
- package/src/plugins/builtin/analytics/risk-client.ts +44 -11
- package/src/plugins/builtin/analytics/risk-fx.ts +61 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +10 -1
- package/src/plugins/builtin/analytics/risk-model.ts +79 -16
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
- package/src/plugins/builtin/analytics/risk-test-data.ts +3 -0
- package/src/plugins/builtin/attention/trending.tsx +8 -6
- package/src/plugins/builtin/backtest/client.ts +5 -2
- package/src/plugins/builtin/backtest/window.ts +16 -3
- package/src/plugins/builtin/broker-manager/add-flow.tsx +40 -8
- package/src/plugins/builtin/broker-manager/detail.tsx +26 -1
- package/src/plugins/builtin/broker-manager/index.tsx +20 -9
- package/src/plugins/builtin/broker-manager/model.ts +5 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -1
- package/src/plugins/builtin/broker-manager/table.ts +5 -1
- package/src/plugins/builtin/broker-trading/account-picker.tsx +91 -0
- package/src/plugins/builtin/broker-trading/chart-levels.ts +54 -0
- package/src/plugins/builtin/broker-trading/command.ts +103 -0
- package/src/plugins/builtin/broker-trading/controller.ts +688 -0
- package/src/plugins/builtin/broker-trading/dock.tsx +182 -0
- package/src/plugins/builtin/broker-trading/headless.ts +76 -0
- package/src/plugins/builtin/broker-trading/index.tsx +77 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +383 -0
- package/src/plugins/builtin/broker-trading/orders-data.ts +133 -0
- package/src/plugins/builtin/broker-trading/orders.tsx +437 -0
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +121 -0
- package/src/plugins/builtin/broker-trading/pane-model.ts +207 -0
- package/src/plugins/builtin/broker-trading/pane.tsx +505 -0
- package/src/plugins/builtin/broker-trading/strategy.ts +153 -0
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +117 -0
- package/src/plugins/builtin/broker-trading/ticket.tsx +573 -0
- package/src/plugins/builtin/buildout/data-runtime.ts +1 -1
- package/src/plugins/builtin/buildout/format.ts +1 -0
- package/src/plugins/builtin/buildout/model/index.ts +16 -7
- package/src/plugins/builtin/buildout/pane/index.tsx +3 -2
- package/src/plugins/builtin/buildout/pane/status.tsx +3 -3
- package/src/plugins/builtin/chart-composer/cli-options.ts +19 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +3 -3
- package/src/plugins/builtin/chart-composer/headless.ts +2 -1
- package/src/plugins/builtin/chart-composer/option-range.ts +39 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +31 -11
- package/src/plugins/builtin/chart-composer/presets.ts +2 -2
- package/src/plugins/builtin/chart-composer/series-catalog.ts +4 -2
- package/src/plugins/builtin/chart-composer/shortcuts.ts +3 -3
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +5 -2
- package/src/plugins/builtin/chat/index.tsx +1 -1
- package/src/plugins/builtin/chat/status-widget.tsx +1 -1
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +6 -1
- package/src/plugins/builtin/chat/unread-inbox.ts +1 -1
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +10 -3
- package/src/plugins/builtin/cloud/team/pane.tsx +30 -9
- package/src/plugins/builtin/commodity-balances/client.ts +6 -4
- package/src/plugins/builtin/commodity-balances/headless.ts +41 -7
- package/src/plugins/builtin/commodity-balances/index.tsx +19 -4
- package/src/plugins/builtin/commodity-balances/model.ts +22 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +36 -5
- package/src/plugins/builtin/company-kpis/client.ts +3 -2
- package/src/plugins/builtin/company-kpis/headless.ts +5 -7
- package/src/plugins/builtin/company-kpis/model.ts +85 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +26 -12
- package/src/plugins/builtin/composite-plugins.ts +3 -2
- package/src/plugins/builtin/cot/headless.ts +1 -1
- package/src/plugins/builtin/cot/index.tsx +1 -1
- package/src/plugins/builtin/cot/model.ts +35 -12
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +2 -1
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -1
- package/src/plugins/builtin/crypto-board/client.ts +33 -2
- package/src/plugins/builtin/crypto-board/headless.ts +5 -2
- package/src/plugins/builtin/crypto-board/model.ts +28 -8
- package/src/plugins/builtin/custom-view/loader.ts +3 -2
- package/src/plugins/builtin/custom-view/pane.tsx +5 -4
- package/src/plugins/builtin/custom-view/view-spec.ts +1 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +30 -8
- package/src/plugins/builtin/dividend-yield/provider-client.ts +3 -1
- package/src/plugins/builtin/earnings-calls/headless.ts +4 -4
- package/src/plugins/builtin/earnings-calls/lock-note.ts +12 -3
- package/src/plugins/builtin/econ/calendar-model.ts +38 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +6 -2
- package/src/plugins/builtin/econ/fred-series-map.ts +12 -1
- package/src/plugins/builtin/econ/index.tsx +31 -4
- package/src/plugins/builtin/econ/print-watch.ts +279 -0
- package/src/plugins/builtin/equity-screener/headless.ts +20 -5
- package/src/plugins/builtin/equity-screener/model.ts +40 -2
- package/src/plugins/builtin/equity-screener/pane.tsx +24 -21
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -2
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +29 -7
- package/src/plugins/builtin/executives/data.ts +24 -8
- package/src/plugins/builtin/executives/index.tsx +2 -18
- package/src/plugins/builtin/executives/pane.tsx +34 -10
- package/src/plugins/builtin/exposure/client.ts +4 -1
- package/src/plugins/builtin/exposure/editor.tsx +3 -3
- package/src/plugins/builtin/exposure/evidence.ts +4 -1
- package/src/plugins/builtin/exposure/holdings.ts +3 -1
- package/src/plugins/builtin/exposure/pane.tsx +37 -16
- package/src/plugins/builtin/filing-events/index.tsx +9 -3
- package/src/plugins/builtin/futures/table.tsx +6 -3
- package/src/plugins/builtin/futures-curve/pane.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +72 -0
- package/src/plugins/builtin/insider/headless.ts +29 -4
- package/src/plugins/builtin/jobs/headless.ts +2 -2
- package/src/plugins/builtin/jobs/lock-note.ts +14 -3
- package/src/plugins/builtin/market-halts/model.ts +31 -6
- package/src/plugins/builtin/market-halts/pane.tsx +3 -0
- package/src/plugins/builtin/market-movers/client.ts +2 -2
- package/src/plugins/builtin/market-movers/index.tsx +0 -3
- package/src/plugins/builtin/market-movers/session-body.tsx +27 -11
- package/src/plugins/builtin/market-movers/session.ts +25 -10
- package/src/plugins/builtin/market-valuation/pane.tsx +2 -1
- package/src/plugins/builtin/members/pane.tsx +8 -3
- package/src/plugins/builtin/news/wire/feed-config.ts +33 -13
- package/src/plugins/builtin/news/wire/index.tsx +7 -2
- package/src/plugins/builtin/news/wire/letters/client.ts +1 -0
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +6 -3
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +2 -1
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +11 -3
- package/src/plugins/builtin/news/wire/news/table.tsx +2 -1
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -2
- package/src/plugins/builtin/news/wire/rss/feed-xml.ts +6 -1
- package/src/plugins/builtin/news/wire/rss/managed-feed.ts +1 -0
- package/src/plugins/builtin/news/wire/rss/source.ts +13 -4
- package/src/plugins/builtin/notes/cli.ts +33 -8
- package/src/plugins/builtin/notes/export.ts +49 -3
- package/src/plugins/builtin/notes/files.ts +14 -3
- package/src/plugins/builtin/notes/index.tsx +3 -3
- package/src/plugins/builtin/notes/quick-notes-pane.tsx +45 -10
- package/src/plugins/builtin/notes/store.ts +13 -3
- package/src/plugins/builtin/options/footer.ts +25 -20
- package/src/plugins/builtin/options/live-quotes.ts +33 -18
- package/src/plugins/builtin/options/view.tsx +77 -22
- package/src/plugins/builtin/options-calculator/pane.tsx +4 -2
- package/src/plugins/builtin/options-scenario/pane.tsx +41 -6
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +3 -0
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +8 -7
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +166 -15
- package/src/plugins/builtin/portfolio-list/cli/render.ts +69 -15
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +2 -2
- package/src/plugins/builtin/portfolio-list/headless.ts +3 -1
- package/src/plugins/builtin/portfolio-list/pane/data.ts +23 -1
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +44 -17
- package/src/plugins/builtin/portfolio-list/settings.ts +20 -2
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +22 -1
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +42 -7
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +24 -3
- package/src/plugins/builtin/primary-dealers/client.ts +137 -62
- package/src/plugins/builtin/primary-dealers/headless.ts +30 -5
- package/src/plugins/builtin/primary-dealers/index.tsx +3 -2
- package/src/plugins/builtin/primary-dealers/model.ts +179 -129
- package/src/plugins/builtin/primary-dealers/pane.tsx +135 -15
- package/src/plugins/builtin/research/analyst-model.ts +5 -1
- package/src/plugins/builtin/risk-factors/index.tsx +12 -3
- package/src/plugins/builtin/scanner/feed.ts +6 -1
- package/src/plugins/builtin/scanner/headless.ts +1 -1
- package/src/plugins/builtin/scanner/lock-note.ts +3 -2
- package/src/plugins/builtin/series-inventory.ts +1 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +105 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +7 -6
- package/src/plugins/builtin/shared/cloud-upgrade.ts +10 -11
- package/src/plugins/builtin/shared/free-routes.ts +24 -0
- package/src/plugins/builtin/shared/headless-options.ts +11 -0
- package/src/plugins/builtin/shared/pro-feature-wall.tsx +9 -4
- package/src/plugins/builtin/shared/pro-lock-note.ts +89 -7
- package/src/plugins/builtin/shared/research-trading.tsx +62 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- package/src/plugins/builtin/social-mentions/lock-note.ts +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -2
- package/src/plugins/builtin/themes/model.ts +43 -10
- package/src/plugins/builtin/themes/pane.tsx +8 -6
- package/src/plugins/builtin/thirteenf/api.ts +4 -1
- package/src/plugins/builtin/thirteenf/data.ts +5 -1
- package/src/plugins/builtin/thirteenf/headless.ts +3 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +8 -3
- package/src/plugins/builtin/ticker-detail/overview/model.ts +44 -10
- package/src/plugins/builtin/ticker-detail/overview/option-contract.ts +64 -0
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +82 -21
- package/src/plugins/builtin/ticker-detail/pane.tsx +21 -14
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +5 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +37 -8
- package/src/plugins/builtin/time-sales/pane.tsx +2 -2
- package/src/plugins/builtin/trace-bonds/client.ts +14 -3
- package/src/plugins/builtin/trace-bonds/headless.ts +1 -1
- package/src/plugins/builtin/vol-surface/pane.tsx +2 -2
- package/src/plugins/builtin-editorial.ts +1 -1
- package/src/plugins/compat.ts +3 -0
- package/src/plugins/external-runtime.ts +5 -0
- package/src/plugins/loader.ts +6 -0
- package/src/plugins/plugin-icon.ts +61 -0
- package/src/plugins/registry/host-actions.ts +2 -1
- package/src/plugins/registry/index.ts +9 -1
- package/src/plugins/runtime/context.tsx +5 -0
- package/src/plugins/runtime/index.tsx +3 -0
- package/src/portfolio/column-values.ts +13 -4
- package/src/portfolio/cost-fx.ts +61 -0
- package/src/portfolio/mutations.ts +16 -2
- package/src/portfolio/position-metrics.ts +45 -4
- package/src/portfolio/position-quantity.ts +43 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +5 -0
- package/src/public/broker.ts +8 -0
- package/src/public/market-data.ts +5 -0
- package/src/renderers/dom/desktop/control-styles.ts +7 -1
- package/src/renderers/dom/desktop/controls.tsx +39 -7
- package/src/renderers/dom/desktop/icons.tsx +14 -0
- package/src/renderers/dom/desktop/list-view.tsx +51 -19
- package/src/renderers/dom/desktop/menu.tsx +10 -1
- package/src/renderers/dom/desktop/select-field.tsx +8 -6
- package/src/renderers/dom/host/style.ts +6 -1
- package/src/renderers/dom/host/tabs.tsx +6 -0
- package/src/renderers/dom/styles.css +12 -5
- package/src/renderers/electrobun/bun/core-capabilities.ts +12 -0
- package/src/renderers/electrobun/bun/external-plugins.ts +3 -0
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/broker-remote-client.ts +16 -0
- package/src/renderers/electrobun/view/external-plugins.ts +1 -0
- package/src/series/validate.ts +2 -2
- package/src/sources/gloomberb-cloud/fred-series.ts +27 -2
- package/src/sources/gloomberb-cloud/index.ts +50 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +4 -0
- package/src/sources/history-result.ts +3 -0
- package/src/sources/provider-errors.ts +3 -1
- package/src/sources/provider-router/history.ts +49 -6
- package/src/sources/provider-router/index.ts +2 -1
- package/src/state/app/activity.ts +13 -0
- package/src/sync/controller.ts +4 -0
- package/src/sync/core-contributors.ts +63 -11
- package/src/sync/local-only.ts +121 -0
- package/src/sync/react.ts +6 -0
- package/src/sync/types.ts +3 -0
- package/src/team/collections.ts +2 -0
- package/src/tickers/listing-fate.ts +27 -8
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/search/index.ts +24 -3
- package/src/time-series/price-comparison.ts +35 -0
- package/src/time-series/resolve.ts +52 -11
- package/src/time-series/spec.ts +1 -1
- package/src/time-series/types.ts +5 -0
- package/src/types/broker.ts +56 -1
- package/src/types/config.ts +6 -0
- package/src/types/data-provider.ts +5 -1
- package/src/types/financials.ts +23 -0
- package/src/types/headless.ts +12 -2
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +24 -6
- package/src/types/price-history.ts +6 -1
- package/src/types/ticker.ts +9 -0
- package/src/types/trading.ts +67 -0
- package/src/ui/host.tsx +4 -0
- package/src/utils/base-currency.ts +108 -0
- package/src/utils/currency-names.ts +128 -0
- package/src/utils/currency-pair.ts +2 -1
- package/src/utils/currency-units.ts +41 -1
- package/src/utils/dom-screenshot.ts +22 -9
- package/src/utils/exchange-notation.generated.ts +360 -0
- package/src/utils/exchanges.ts +15 -322
- package/src/utils/format.ts +31 -1
- package/src/utils/instrument-identity.ts +38 -1
- package/src/utils/options.ts +46 -1
- package/src/utils/price-history.ts +4 -0
- package/src/utils/reported-money.ts +8 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logFailure } from "../utils/log-failure";
|
|
2
2
|
import { resolveAssetDisplayKind } from "../market-data/market/format";
|
|
3
3
|
import { hasValidQuoteObservationTime } from "../market-data/quotes/freshness";
|
|
4
|
+
import { delistingLabel } from "../market-data/quotes/delisting";
|
|
4
5
|
import { SnapshotHistoryUnavailableError } from "../market-data/snapshot-provider";
|
|
5
6
|
import { financialPeriodCoverage, financialPeriodCoverageWarnings, limitSeriesObservations } from "./financial-period-coverage";
|
|
6
7
|
import { HistoryCoverageError, historyCoverageNotice } from "../sources/history-coverage";
|
|
@@ -10,6 +11,7 @@ import { getRouterEntityKey } from "../sources/provider-router/cache";
|
|
|
10
11
|
import { publicListingTarget } from "../sources/listing-target";
|
|
11
12
|
import { fetchHistoryResult } from "../sources/history-result";
|
|
12
13
|
import type { HistorySession, PriceHistoryResult } from "../types/price-history";
|
|
14
|
+
import type { BrokerContractRef } from "../types/instrument";
|
|
13
15
|
import { FINANCIAL_VINTAGE_NOTICE, SEC_EPS_BASIS_NOTICE } from "../utils/financial-statements";
|
|
14
16
|
import { appendLiveQuotePoint, hasUnknownBondHistoryBasis } from "./chart-data";
|
|
15
17
|
import { LiveBarAccumulator } from "./live-bars";
|
|
@@ -63,7 +65,7 @@ import {
|
|
|
63
65
|
} from "./studies";
|
|
64
66
|
import { applyResolvedSeriesTransform } from "./transforms";
|
|
65
67
|
import { clipSeriesToWindow } from "./alignment";
|
|
66
|
-
import { clipPriceComparison, priceComparisonBoundsForSeries, priceComparisonSeriesIds, priceObservationWindowFilter, resolvePriceComparison, type PriceComparison } from "./price-comparison";
|
|
68
|
+
import { bufferPriceComparison, clipPriceComparison, comparedBufferPoints, priceComparisonBoundsForSeries, priceComparisonSeriesIds, priceObservationWindowFilter, resolvePriceComparison, type PriceComparison } from "./price-comparison";
|
|
67
69
|
import { reportingCurrencySeries } from "./reporting-currency";
|
|
68
70
|
import { chartQuoteOverrideKeyForSource, compareChartQuoteRecency } from "./live-quotes";
|
|
69
71
|
import { chartSeriesSourceKey } from "../capabilities/chart-series";
|
|
@@ -754,8 +756,8 @@ export function seedChartResolutionResult(
|
|
|
754
756
|
const axisWarnings: string[] = [];
|
|
755
757
|
const bufferedSeries = assignAxes([
|
|
756
758
|
...baseSeries,
|
|
757
|
-
...applyStudyPresentationTransforms(studies.series, spec.studies, series, comparisonBounds, undefined, priceComparison),
|
|
758
|
-
], [...spec.series, ...spec.studies], axisWarnings).map((entry) =>
|
|
759
|
+
...applyStudyPresentationTransforms(studies.series, spec.studies, series, comparisonBounds, undefined, priceComparison, bounds),
|
|
760
|
+
], [...spec.series, ...spec.studies], axisWarnings).map((entry) => bufferPriceComparison(entry, priceComparison, bounds));
|
|
759
761
|
const visible = bufferedSeries.map((entry) => {
|
|
760
762
|
const entryBounds = presentationBounds(entry, spec.studies, priceComparison, bounds);
|
|
761
763
|
const clipped = entryBounds.start !== null && entryBounds.end !== null
|
|
@@ -1168,6 +1170,17 @@ async function loadPriceHistory(
|
|
|
1168
1170
|
return { ...result, expiresAt: retryAt ?? Date.now() + HISTORY_RETENTION_MAX_AGE_MS };
|
|
1169
1171
|
}
|
|
1170
1172
|
|
|
1173
|
+
/**
|
|
1174
|
+
* A US stock or fund listing, including one a broker contract routes through
|
|
1175
|
+
* SMART in dollars. Options and futures have no pre-market session.
|
|
1176
|
+
*/
|
|
1177
|
+
function tradesUsExtendedHours(exchange: string | undefined, contract: BrokerContractRef | null | undefined): boolean {
|
|
1178
|
+
if (contract?.secType && !["STK", "ETF"].includes(contract.secType.toUpperCase())) return false;
|
|
1179
|
+
const venue = exchange || contract?.primaryExchange || contract?.exchange;
|
|
1180
|
+
return isUsListingExchange(venue) || isUsListingExchange(contract?.primaryExchange)
|
|
1181
|
+
|| (!!contract && canonicalExchange(venue) === "SMART" && (!contract.currency || contract.currency.toUpperCase() === "USD"));
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1171
1184
|
function baseSecuritySeries(
|
|
1172
1185
|
spec: ChartSeriesSpec,
|
|
1173
1186
|
financials: TickerFinancials,
|
|
@@ -1185,7 +1198,8 @@ function baseSecuritySeries(
|
|
|
1185
1198
|
const symbol = instrumentLabel(spec.source);
|
|
1186
1199
|
const statementCurrency = field.id.startsWith("fundamental.") && field.unit.startsWith("currency")
|
|
1187
1200
|
? reportingCurrencySeries(points, financials.financialCurrency) : null;
|
|
1188
|
-
|
|
1201
|
+
// A broker contract names its currency even before (or without) a quote.
|
|
1202
|
+
const currency = statementCurrency ? statementCurrency.currency : financials.quote?.currency || quoteMetadata?.currency || spec.source.instrument.instrument?.currency;
|
|
1189
1203
|
const assetKind = resolveAssetDisplayKind({ assetCategory: financials.quote?.instrumentType || quoteMetadata?.instrumentType });
|
|
1190
1204
|
const unknownBondBasis = hasUnknownBondHistoryBasis(financials.quote,
|
|
1191
1205
|
spec.source.instrument.instrument?.secType, quoteMetadata?.instrumentType);
|
|
@@ -1220,10 +1234,25 @@ function baseSecuritySeries(
|
|
|
1220
1234
|
|| financials.quote?.listingExchangeName
|
|
1221
1235
|
|| financials.quote?.exchangeName;
|
|
1222
1236
|
const marketField = isMarketFieldId(spec.source.fieldId);
|
|
1237
|
+
// A routing code such as a broker's SMART names no venue. The quote's
|
|
1238
|
+
// listing then supplies the session clock, so closed hours stay off the axis.
|
|
1239
|
+
const sessionExchange = [marketExchange, financials.quote?.listingExchangeName, quoteMetadata?.listingExchangeName, financials.quote?.exchangeName]
|
|
1240
|
+
.find((value) => resolveExchangeTimeZone(value));
|
|
1241
|
+
// A dollar listing saved with IBKR's SMART route and no other venue trades on
|
|
1242
|
+
// the US session, and so does a dollar option, which names no venue at all.
|
|
1243
|
+
const dollars = !currency || currency === "USD";
|
|
1244
|
+
const usOption = dollars && (spec.source.instrument.instrument?.secType?.toUpperCase() === "OPT"
|
|
1245
|
+
|| /^OPTION$/i.test(financials.quote?.instrumentType ?? quoteMetadata?.instrumentType ?? ""));
|
|
1246
|
+
const routedUsListing = !sessionExchange && ((canonicalExchange(marketExchange) === "SMART" && dollars) || usOption);
|
|
1223
1247
|
const marketTimeZone = marketField
|
|
1224
1248
|
&& canonicalExchange(marketExchange) !== "CCC"
|
|
1225
|
-
? resolveExchangeTimeZone(
|
|
1249
|
+
? resolveExchangeTimeZone(sessionExchange) ?? (routedUsListing ? "America/New_York" : null)
|
|
1226
1250
|
: null;
|
|
1251
|
+
// A route has no hours of its own: its sessions, which the day view and
|
|
1252
|
+
// VWAP follow, are the venue's, and NYSE's for an unnamed dollar listing.
|
|
1253
|
+
const listingExchange = canonicalExchange(marketExchange) === "SMART" || usOption
|
|
1254
|
+
? canonicalExchange(sessionExchange) || (routedUsListing ? "NYSE" : marketExchange)
|
|
1255
|
+
: marketExchange;
|
|
1227
1256
|
const latestChangePercent = marketField && field.unit.startsWith("currency")
|
|
1228
1257
|
&& !unknownBondBasis
|
|
1229
1258
|
&& financials.quote && hasValidQuoteObservationTime(financials.quote)
|
|
@@ -1259,12 +1288,12 @@ function baseSecuritySeries(
|
|
|
1259
1288
|
panelId: spec.panelId,
|
|
1260
1289
|
interpolation: spec.interpolation,
|
|
1261
1290
|
observationKind: marketField ? "market" : undefined,
|
|
1262
|
-
...(marketField ? { listing: { symbol: spec.source.instrument.symbol, exchange:
|
|
1291
|
+
...(marketField ? { listing: { symbol: spec.source.instrument.symbol, exchange: listingExchange ?? "" } } : {}),
|
|
1263
1292
|
timeBasis: marketTimeZone
|
|
1264
1293
|
? {
|
|
1265
1294
|
kind: "market",
|
|
1266
1295
|
timeZone: marketTimeZone,
|
|
1267
|
-
exchange: canonicalExchange(
|
|
1296
|
+
exchange: canonicalExchange(sessionExchange) || undefined,
|
|
1268
1297
|
cadenceMs: marketResolution
|
|
1269
1298
|
? CHART_RESOLUTION_STEP_MS[marketResolution]
|
|
1270
1299
|
: undefined,
|
|
@@ -1487,6 +1516,7 @@ function applyStudyPresentationTransforms(
|
|
|
1487
1516
|
visibleBounds: DateBounds,
|
|
1488
1517
|
fallbackBaselineBounds?: DateBounds,
|
|
1489
1518
|
priceComparison?: PriceComparison | null,
|
|
1519
|
+
view: DateBounds = visibleBounds,
|
|
1490
1520
|
): ResolvedSeries[] {
|
|
1491
1521
|
const rawById = new Map(rawSeries.map((series) => [series.id, series] as const));
|
|
1492
1522
|
return outputs.map((output) => {
|
|
@@ -1502,7 +1532,7 @@ function applyStudyPresentationTransforms(
|
|
|
1502
1532
|
: undefined;
|
|
1503
1533
|
const transformed = applyResolvedSeriesTransform(output, input.transform, { baseline });
|
|
1504
1534
|
const inputBounds = priceComparison?.sourceBounds?.[input.id];
|
|
1505
|
-
return inputBounds ? { ...transformed, points:
|
|
1535
|
+
return inputBounds ? { ...transformed, points: comparedBufferPoints(transformed.points, inputBounds, view) } : transformed;
|
|
1506
1536
|
});
|
|
1507
1537
|
}
|
|
1508
1538
|
|
|
@@ -1612,6 +1642,7 @@ async function resolveChartSpecPass(
|
|
|
1612
1642
|
&& entry.source.kind === "security" && isFundamentalFieldId(entry.source.fieldId))
|
|
1613
1643
|
? [FINANCIAL_VINTAGE_NOTICE] : [];
|
|
1614
1644
|
const priorityWarnings: string[] = [];
|
|
1645
|
+
const delistings = new Map<string, { symbol: string; label: string; notice: string }>();
|
|
1615
1646
|
const baseSeriesIds = new Set(spec.series.map((entry) => entry.id));
|
|
1616
1647
|
const visibleSeriesIds = new Set(spec.series
|
|
1617
1648
|
.filter((entry) => entry.visible !== false)
|
|
@@ -1813,10 +1844,10 @@ async function resolveChartSpecPass(
|
|
|
1813
1844
|
const hasExplicitWindow = explicitBounds(spec) !== null || movedWindow;
|
|
1814
1845
|
const initialCalculationBounds = calculationBounds(spec, requestVisibleBounds, initialResolution);
|
|
1815
1846
|
|
|
1816
|
-
// Only US
|
|
1847
|
+
// Only US stocks and funds trade before and after the regular session; asking elsewhere costs a request for nothing.
|
|
1817
1848
|
const extendedHoursFor = (source: Extract<ChartSeriesSpec["source"], { kind: "security" }>, resolution: ManualChartResolution) => (
|
|
1818
1849
|
spec.viewport.extendedHours === true && isMarketFieldId(source.fieldId) && isIntradayResolution(resolution)
|
|
1819
|
-
&&
|
|
1850
|
+
&& tradesUsExtendedHours(source.instrument.exchange, source.instrument.instrument)
|
|
1820
1851
|
);
|
|
1821
1852
|
// A history starts after the visible window because its source keeps no more.
|
|
1822
1853
|
let retainedHistoryOnly = false;
|
|
@@ -1952,6 +1983,14 @@ async function resolveChartSpecPass(
|
|
|
1952
1983
|
const history = loaded.points;
|
|
1953
1984
|
const coverageNotice = historyCoverageNotice(loaded.coverageStart, request.visibleBounds.start);
|
|
1954
1985
|
if (coverageNotice) priorityWarnings.push(coverageNotice);
|
|
1986
|
+
// A listing that no longer trades is named so beside its bars, which end on its last session.
|
|
1987
|
+
if (loaded.delisting) {
|
|
1988
|
+
const symbol = parsePublicTickerKey(source.instrument.symbol).symbol;
|
|
1989
|
+
const label = delistingLabel(loaded.delisting);
|
|
1990
|
+
const notice = `${symbol}: ${label}`;
|
|
1991
|
+
priorityWarnings.push(notice);
|
|
1992
|
+
if (!delistings.has(notice)) delistings.set(notice, { symbol, label, notice });
|
|
1993
|
+
}
|
|
1955
1994
|
// Read per request: one recovered window answers every visible window that shares its acquisition.
|
|
1956
1995
|
if (loaded.recovery && request.visibleBounds.start !== null && request.visibleBounds.start < loaded.recovery.start) {
|
|
1957
1996
|
priorityWarnings.push(historyRetentionNotice(loaded.recovery.retention, loaded.resolution ?? request.resolution,
|
|
@@ -2294,6 +2333,7 @@ async function resolveChartSpecPass(
|
|
|
2294
2333
|
comparisonBounds,
|
|
2295
2334
|
priceComparison ? undefined : requestVisibleBounds,
|
|
2296
2335
|
priceComparison,
|
|
2336
|
+
bounds,
|
|
2297
2337
|
),
|
|
2298
2338
|
];
|
|
2299
2339
|
warnings.push(...studyResult.warnings);
|
|
@@ -2301,7 +2341,7 @@ async function resolveChartSpecPass(
|
|
|
2301
2341
|
}
|
|
2302
2342
|
|
|
2303
2343
|
const bufferedSeries = assignAxes(adoptPriceUnits(resolved, spec.series), [...spec.series, ...spec.studies], warnings)
|
|
2304
|
-
.map((entry) =>
|
|
2344
|
+
.map((entry) => bufferPriceComparison(entry, priceComparison, bounds));
|
|
2305
2345
|
resolved = bufferedSeries.map((entry) => {
|
|
2306
2346
|
const entryBounds = presentationBounds(entry, spec.studies, priceComparison, bounds);
|
|
2307
2347
|
return entryBounds.start !== null && entryBounds.end !== null
|
|
@@ -2388,6 +2428,7 @@ async function resolveChartSpecPass(
|
|
|
2388
2428
|
loading: false,
|
|
2389
2429
|
errors,
|
|
2390
2430
|
warnings: [...new Set([...priorityWarnings, ...warnings])],
|
|
2431
|
+
...(delistings.size ? { delistings: [...delistings.values()] } : {}),
|
|
2391
2432
|
viewport,
|
|
2392
2433
|
resolution,
|
|
2393
2434
|
};
|
package/src/time-series/spec.ts
CHANGED
|
@@ -85,7 +85,7 @@ export function coerceSeriesInterpolationForStyle(
|
|
|
85
85
|
return style === "step" ? "step-after" : "none";
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
export const MAX_CHART_SERIES =
|
|
88
|
+
export const MAX_CHART_SERIES = 20;
|
|
89
89
|
|
|
90
90
|
export const DEFAULT_CHART_SPEC: ChartSpec = Object.freeze({
|
|
91
91
|
version: CHART_SPEC_VERSION,
|
package/src/time-series/types.ts
CHANGED
|
@@ -281,6 +281,11 @@ export interface ChartResolutionResult {
|
|
|
281
281
|
loading: boolean;
|
|
282
282
|
errors: string[];
|
|
283
283
|
warnings: string[];
|
|
284
|
+
/**
|
|
285
|
+
* Each charted listing that no longer trades: its symbol and label
|
|
286
|
+
* ("Delisted Oct 27, 2022"), which `warnings` carries as "TWTR: Delisted Oct 27, 2022".
|
|
287
|
+
*/
|
|
288
|
+
delistings?: { symbol: string; label: string; notice: string }[];
|
|
284
289
|
/** Effective inclusive bounds used to clip the resolved chart data. */
|
|
285
290
|
viewport?: { start: Date; end: Date };
|
|
286
291
|
/** Bar resolution the loaded market history was fetched at. */
|
package/src/types/broker.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
BrokerOrderPreview,
|
|
12
12
|
BrokerOrderRequest,
|
|
13
13
|
BrokerPortfolioPerformance,
|
|
14
|
+
BrokerTradingCapabilities,
|
|
14
15
|
} from "./trading";
|
|
15
16
|
import type { CachePolicy, CachePolicyMap } from "./persistence";
|
|
16
17
|
|
|
@@ -85,10 +86,44 @@ export interface BrokerProfileAction {
|
|
|
85
86
|
disabledReason?: string;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
/** How a chart asks a broker for history beyond the regular session. */
|
|
90
|
+
export interface BrokerHistoryOptions {
|
|
91
|
+
/** Include pre-market and after-hours bars. Only a broker that sets `extendedHoursHistory` is asked. */
|
|
92
|
+
session?: "extended";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** What a broker's order stream calls. */
|
|
96
|
+
export interface BrokerOrderListener {
|
|
97
|
+
/**
|
|
98
|
+
* An order as the broker now reports it: placed, partly or wholly filled,
|
|
99
|
+
* replaced, cancelled, rejected or expired. The same `orderId` names the
|
|
100
|
+
* order through all of them, as `getOrderStatus` and `cancelOrder` take it.
|
|
101
|
+
*/
|
|
102
|
+
order(order: BrokerOrder): void;
|
|
103
|
+
/**
|
|
104
|
+
* Whether changes are being pushed now. While false, as before the first
|
|
105
|
+
* call, the host polls open orders instead; on true it reconciles once.
|
|
106
|
+
*/
|
|
107
|
+
live?(live: boolean): void;
|
|
108
|
+
}
|
|
109
|
+
|
|
88
110
|
export interface BrokerAdapter {
|
|
89
111
|
readonly id: string;
|
|
90
112
|
readonly name: string;
|
|
91
113
|
readonly cachePolicy?: CachePolicyMap;
|
|
114
|
+
/**
|
|
115
|
+
* Intraday history includes pre-market and after-hours bars when its
|
|
116
|
+
* `BrokerHistoryOptions` ask for the extended session. The chart then
|
|
117
|
+
* starts the day at the pre-market open; without it, the regular session.
|
|
118
|
+
*/
|
|
119
|
+
readonly extendedHoursHistory?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* The quotes and bars this broker supplies stay on the user's device: Gloom Cloud sync never
|
|
122
|
+
* uploads them, for a broker whose terms restrict redistributing its market data. Its accounts
|
|
123
|
+
* sync like any broker's, unless the user keeps a connection on the device (`localOnly` on the
|
|
124
|
+
* profile). Hosts that honor it export `LOCAL_BROKER_MARKET_DATA` from `gloomberb/broker`.
|
|
125
|
+
*/
|
|
126
|
+
readonly localMarketData?: boolean;
|
|
92
127
|
validate(instance: BrokerInstanceConfig): Promise<boolean>;
|
|
93
128
|
importPositions(instance: BrokerInstanceConfig): Promise<BrokerPosition[]>;
|
|
94
129
|
importPortfolioSnapshot?(instance: BrokerInstanceConfig): Promise<{ accounts: BrokerAccount[]; positions: BrokerPosition[] }>;
|
|
@@ -116,9 +151,10 @@ export interface BrokerAdapter {
|
|
|
116
151
|
bufferRange: TimeRange,
|
|
117
152
|
resolution: ManualChartResolution,
|
|
118
153
|
instrument?: BrokerContractRef | null,
|
|
154
|
+
options?: BrokerHistoryOptions,
|
|
119
155
|
): Promise<PricePoint[]>;
|
|
120
156
|
/** Fetch higher-resolution price data for a specific date window (e.g. when zoomed in). */
|
|
121
|
-
getDetailedPriceHistory?(ticker: string, instance: BrokerInstanceConfig, exchange: string, startDate: Date, endDate: Date, barSize: string, instrument?: BrokerContractRef | null): Promise<PricePoint[]>;
|
|
157
|
+
getDetailedPriceHistory?(ticker: string, instance: BrokerInstanceConfig, exchange: string, startDate: Date, endDate: Date, barSize: string, instrument?: BrokerContractRef | null, options?: BrokerHistoryOptions): Promise<PricePoint[]>;
|
|
122
158
|
getChartResolutionSupport?(
|
|
123
159
|
ticker: string,
|
|
124
160
|
instance: BrokerInstanceConfig,
|
|
@@ -136,6 +172,8 @@ export interface BrokerAdapter {
|
|
|
136
172
|
* Whether this profile can stream quotes at all. Return false for modes that
|
|
137
173
|
* only sync statements, so their positions stream from the cloud instead.
|
|
138
174
|
* Quotes are also only routed to a broker whose status is "connected".
|
|
175
|
+
* Answer from the profile's configuration, not from session state: the
|
|
176
|
+
* desktop app asks in its view, while the session lives in the backend.
|
|
139
177
|
*/
|
|
140
178
|
canStreamQuotes?(instance: BrokerInstanceConfig): boolean;
|
|
141
179
|
subscribeQuotes?(
|
|
@@ -144,8 +182,25 @@ export interface BrokerAdapter {
|
|
|
144
182
|
onQuote: (target: QuoteSubscriptionTarget, quote: Quote) => void,
|
|
145
183
|
): () => void;
|
|
146
184
|
listOpenOrders?(instance: BrokerInstanceConfig): Promise<BrokerOrder[]>;
|
|
185
|
+
/**
|
|
186
|
+
* Pushes order changes as the broker reports them, for every account the
|
|
187
|
+
* profile includes. The host baselines from `listOpenOrders` and polls it
|
|
188
|
+
* while `live` is false or never called; see BrokerOrderListener.
|
|
189
|
+
*/
|
|
190
|
+
subscribeOrders?(instance: BrokerInstanceConfig, listener: BrokerOrderListener): () => void;
|
|
191
|
+
/** Explicit status, including terminal orders. Null means unconfirmed, never cancelled by absence. */
|
|
192
|
+
getOrderStatus?(instance: BrokerInstanceConfig, orderId: number): Promise<BrokerOrder | null>;
|
|
147
193
|
listExecutions?(instance: BrokerInstanceConfig): Promise<BrokerExecution[]>;
|
|
194
|
+
/** Opt into the shared ticket with supported combinations and current trading permission. */
|
|
195
|
+
getTradingCapabilities?(instance: BrokerInstanceConfig, contract?: BrokerContractRef, orderType?: BrokerOrderRequest["orderType"]): BrokerTradingCapabilities;
|
|
196
|
+
/** Config patch for the host's explicit enable/disable trading confirmation. Must not perform I/O. */
|
|
197
|
+
getTradingConfigUpdate?(instance: BrokerInstanceConfig, enabled: boolean): Record<string, unknown>;
|
|
148
198
|
previewOrder?(instance: BrokerInstanceConfig, request: BrokerOrderRequest): Promise<BrokerOrderPreview>;
|
|
199
|
+
/**
|
|
200
|
+
* Place, change and cancel throw when the broker did not take the action. An error with `refused: true` says the
|
|
201
|
+
* broker answered no, or nothing was sent: the order is as it was, and its message is one short line the app shows as
|
|
202
|
+
* it is ("Aries cannot find this order"). Any other error is a lost answer, whose outcome the app treats as unknown.
|
|
203
|
+
*/
|
|
149
204
|
placeOrder?(instance: BrokerInstanceConfig, request: BrokerOrderRequest): Promise<BrokerOrder>;
|
|
150
205
|
modifyOrder?(instance: BrokerInstanceConfig, orderId: number, request: BrokerOrderRequest): Promise<BrokerOrder>;
|
|
151
206
|
cancelOrder?(instance: BrokerInstanceConfig, orderId: number): Promise<void>;
|
package/src/types/config.ts
CHANGED
|
@@ -18,6 +18,12 @@ export interface BrokerInstanceConfig {
|
|
|
18
18
|
config: Record<string, unknown>;
|
|
19
19
|
enabled?: boolean;
|
|
20
20
|
lastSyncedAt?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The user keeps this connection's data on this device: Cloud sync leaves out the profile, its
|
|
23
|
+
* accounts' portfolios and account values, and the positions in them. Daily roundups, the weekly
|
|
24
|
+
* brief, position alerts, the mobile app and Ask Gloom's portfolio context then go without it.
|
|
25
|
+
*/
|
|
26
|
+
localOnly?: boolean;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export interface ColumnConfig {
|
|
@@ -119,7 +119,11 @@ export interface MarketDataRequestContext {
|
|
|
119
119
|
brokerId?: string;
|
|
120
120
|
brokerInstanceId?: string;
|
|
121
121
|
instrument?: BrokerContractRef | null;
|
|
122
|
-
|
|
122
|
+
/**
|
|
123
|
+
* "refresh" always fetches. "current" refetches a stored value past its stale time before answering, and
|
|
124
|
+
* answers with it only if that fetch fails: for a caller that cannot see a refresh landing in the background.
|
|
125
|
+
*/
|
|
126
|
+
cacheMode?: "default" | "refresh" | "current";
|
|
123
127
|
statementHistory?: "extended";
|
|
124
128
|
/** A validated, same-target detailed retry constrained to one exhausted source. */
|
|
125
129
|
historyRecovery?: import("../sources/history-retention").HistoryRecoveryCandidate;
|
package/src/types/financials.ts
CHANGED
|
@@ -34,6 +34,20 @@ export interface QuoteProvenance {
|
|
|
34
34
|
rejectedPriceProviders?: string[];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* A US listing that no longer trades, as Gloom Cloud states it: TWTR, last
|
|
39
|
+
* traded 2022-10-27 and removed from NYSE the next day. Its daily history is
|
|
40
|
+
* still served, ending on that session. Dates are New York trading dates.
|
|
41
|
+
*/
|
|
42
|
+
export interface ListingDelisting {
|
|
43
|
+
/** "delisted": the exchange's removal of the listing is on record; "inactive": only its last trade is known. */
|
|
44
|
+
status: "delisted" | "inactive";
|
|
45
|
+
/** The last session with a trade (YYYY-MM-DD). */
|
|
46
|
+
lastTradeDate: string;
|
|
47
|
+
/** The first session served (YYYY-MM-DD). */
|
|
48
|
+
historyStart: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
37
51
|
/** Static listing facts from a quote observation, without an investable price. */
|
|
38
52
|
export interface QuoteMetadataSource {
|
|
39
53
|
providerId?: string;
|
|
@@ -81,6 +95,13 @@ export interface Quote extends DepositaryReceiptFacts {
|
|
|
81
95
|
providerPriceDivisor?: number;
|
|
82
96
|
change: number;
|
|
83
97
|
changePercent: number;
|
|
98
|
+
/**
|
|
99
|
+
* What change and changePercent measure from when it is not previousClose,
|
|
100
|
+
* as Gloom Cloud says of a coin whose previous close it cannot date to the
|
|
101
|
+
* last two days: the last 24 hours ("24h", previousClose absent), or
|
|
102
|
+
* nothing ("none", no move). Absent on every other quote.
|
|
103
|
+
*/
|
|
104
|
+
changeBasis?: "24h" | "none";
|
|
84
105
|
previousClose?: number;
|
|
85
106
|
/** Official close of a completed regular session, in this quote's currency. */
|
|
86
107
|
regularClose?: number;
|
|
@@ -100,6 +121,8 @@ export interface Quote extends DepositaryReceiptFacts {
|
|
|
100
121
|
receivedAt?: number; // local receipt timestamp ms for streamed/display freshness
|
|
101
122
|
delivery?: QuoteDelivery;
|
|
102
123
|
stale?: boolean;
|
|
124
|
+
/** The listing no longer trades: the price is its last trade (ListingDelisting). */
|
|
125
|
+
delisting?: ListingDelisting;
|
|
103
126
|
exchangeName?: string;
|
|
104
127
|
fullExchangeName?: string;
|
|
105
128
|
listingExchangeName?: string;
|
package/src/types/headless.ts
CHANGED
|
@@ -103,6 +103,8 @@ export interface HeadlessPaneContext {
|
|
|
103
103
|
/** Effective instance settings, after template creation and option normalization. */
|
|
104
104
|
settings?: Record<string, unknown>;
|
|
105
105
|
capabilities?: CapabilityInvoker;
|
|
106
|
+
/** Locally registered broker adapters. Reports may read account data; they never submit orders. */
|
|
107
|
+
resolveBroker?: (brokerType: string) => import("./broker").BrokerAdapter | null;
|
|
106
108
|
/** Read one local portfolio without passing holdings through a remote endpoint. */
|
|
107
109
|
resolvePortfolio?: (id: string) => Promise<{
|
|
108
110
|
portfolio: import("./ticker").Portfolio;
|
|
@@ -131,6 +133,12 @@ export interface HeadlessPaneColumn {
|
|
|
131
133
|
header: string;
|
|
132
134
|
/** Print `header` as written, a field name such as `source`, where reports would otherwise title-case it. */
|
|
133
135
|
literalHeader?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* What the text report heads the column with when it can say more than an
|
|
138
|
+
* export's header should (`Chg % UTC` over `Chg %`), printed as written;
|
|
139
|
+
* CSV keeps `header`, so a column read by its name stays where it was.
|
|
140
|
+
*/
|
|
141
|
+
textHeader?: string;
|
|
134
142
|
align?: "left" | "right" | "center";
|
|
135
143
|
width?: number;
|
|
136
144
|
/** False keeps the column whole when the text table is fitted to a narrow width, so a time or an id is never cut. */
|
|
@@ -229,9 +237,11 @@ export interface HeadlessPaneFreshness {
|
|
|
229
237
|
/**
|
|
230
238
|
* How often the data is published, when its dates mark the start of a period
|
|
231
239
|
* (a monthly statistic is dated the 1st). The report then names the month,
|
|
232
|
-
* quarter or year, not a day it was never observed on.
|
|
240
|
+
* quarter or year, not a day it was never observed on. A semiannual estimate
|
|
241
|
+
* is dated by the month it was made in (USDA's coffee and sugar balances),
|
|
242
|
+
* so it names that month.
|
|
233
243
|
*/
|
|
234
|
-
periodicity?: "monthly" | "quarterly" | "annual";
|
|
244
|
+
periodicity?: "monthly" | "quarterly" | "semiannual" | "annual";
|
|
235
245
|
/**
|
|
236
246
|
* The newest row is a weekly or monthly bar whose period had not ended when
|
|
237
247
|
* it was served (October's bar on 16 Oct), and the last day it covers so
|
package/src/types/instrument.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ListingDelisting } from "./financials";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* What a ticker is, at the grain that decides which research has data for it:
|
|
3
5
|
* filings, executives and analyst coverage exist for a company's stock,
|
|
@@ -77,4 +79,6 @@ export interface InstrumentSearchResult {
|
|
|
77
79
|
* carries that name. A leftover listing of the merged company (GOGLC on
|
|
78
80
|
* BYMA) is linked to it by search, naming the `successor`. */
|
|
79
81
|
formerIssuer?: { symbol: string; name: string; until: string; successor?: { symbol: string; name: string | null } };
|
|
82
|
+
/** A US listing that no longer trades, found by its exact symbol (TWTR). Untrusted until parsed. */
|
|
83
|
+
delisting?: ListingDelisting;
|
|
80
84
|
}
|
package/src/types/plugin.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { AppTickerRepositoryPort } from "../core/app-service-ports";
|
|
3
|
-
import type { HeadlessPaneDefinition, HeadlessPaneFreshness, HeadlessPaneOptionDef } from "./headless";
|
|
3
|
+
import type { HeadlessPaneContext, HeadlessPaneDefinition, HeadlessPaneFreshness, HeadlessPaneOptionDef } from "./headless";
|
|
4
4
|
|
|
5
5
|
export type {
|
|
6
6
|
HeadlessArgumentExpansion,
|
|
@@ -123,6 +123,12 @@ export interface PaneLock {
|
|
|
123
123
|
token?: string;
|
|
124
124
|
/** The session is signed in and its email is not verified yet. */
|
|
125
125
|
verifyEmail?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Reads data as the report does, so a note can check that a free route it
|
|
128
|
+
* would name has data for the symbol before naming it. Absent where nothing
|
|
129
|
+
* can be read.
|
|
130
|
+
*/
|
|
131
|
+
context?: HeadlessPaneContext;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
export interface PaneDef {
|
|
@@ -195,9 +201,10 @@ export interface PaneDef {
|
|
|
195
201
|
* read without it and where, and how to unlock it. A `headless` pane's report
|
|
196
202
|
* prints it when the server refuses the read (401, 402 or 403). Without it
|
|
197
203
|
* the report prints the wall's own words, or the refusal. Either way it cites
|
|
198
|
-
* no source, since nothing was read.
|
|
204
|
+
* no source, since nothing was read. A free route it names must have data
|
|
205
|
+
* for the symbol (`lock.context` reads it), so the note may resolve later.
|
|
199
206
|
*/
|
|
200
|
-
reportLockNote?(lock: PaneLock): string
|
|
207
|
+
reportLockNote?(lock: PaneLock): string | Promise<string>;
|
|
201
208
|
/**
|
|
202
209
|
* What a rendered-view report needs before it shows anything, such as a
|
|
203
210
|
* sign-in: `gloomberb catalog` lists it under Requires, as it does a
|
|
@@ -880,8 +887,8 @@ export interface AppNotificationRequest {
|
|
|
880
887
|
};
|
|
881
888
|
/**
|
|
882
889
|
* What a built-in notice is about, so the Unread list can keep it after the
|
|
883
|
-
* toast is gone and open it again: `price:<alertId>`, `catalyst:<eventId
|
|
884
|
-
* or `team:<cardId>`. Other values are not kept.
|
|
890
|
+
* toast is gone and open it again: `price:<alertId>`, `catalyst:<eventId>`,
|
|
891
|
+
* `econ:<eventId>` or `team:<cardId>`. Other values are not kept.
|
|
885
892
|
*/
|
|
886
893
|
refId?: string;
|
|
887
894
|
/** Rendered next to `action`. Use for a dismissing counterpart such as snooze. */
|
|
@@ -895,6 +902,13 @@ export interface BrokerInstanceUpdateOptions {
|
|
|
895
902
|
label?: string;
|
|
896
903
|
enabled?: boolean;
|
|
897
904
|
replaceConfig?: boolean;
|
|
905
|
+
/** Keep this connection's data on this device, out of Gloom Cloud sync (`BrokerInstanceConfig.localOnly`). */
|
|
906
|
+
localOnly?: boolean;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
export interface BrokerInstanceCreateOptions {
|
|
910
|
+
/** Keep the new connection's data on this device from the start, before its first import. */
|
|
911
|
+
localOnly?: boolean;
|
|
898
912
|
}
|
|
899
913
|
|
|
900
914
|
export interface PinTickerOptions {
|
|
@@ -906,6 +920,8 @@ export interface PinTickerOptions {
|
|
|
906
920
|
listing?: TickerListingRef;
|
|
907
921
|
/** Select this research tab once the requested ticker has resolved. */
|
|
908
922
|
tabId?: string;
|
|
923
|
+
/** Merge this state into the resolved research pane when selecting `tabId`. */
|
|
924
|
+
tabState?: Record<string, unknown>;
|
|
909
925
|
}
|
|
910
926
|
|
|
911
927
|
export interface GloomPluginContext {
|
|
@@ -937,6 +953,8 @@ export interface GloomPluginContext {
|
|
|
937
953
|
getData(ticker: string): TickerFinancials | null;
|
|
938
954
|
getTicker(ticker: string): TickerRecord | null;
|
|
939
955
|
getConfig(): import("./config").AppConfig;
|
|
956
|
+
/** Resolve a broker registered by another plugin, without connecting it. */
|
|
957
|
+
getBrokerAdapter?(brokerType: string): BrokerAdapter | null;
|
|
940
958
|
getPaneDef(paneId: string): PaneDef | undefined;
|
|
941
959
|
|
|
942
960
|
readonly marketData: DataProvider;
|
|
@@ -949,7 +967,7 @@ export interface GloomPluginContext {
|
|
|
949
967
|
readonly paneSettings: PluginPaneSettingsState;
|
|
950
968
|
readonly teamState: PluginTeamState;
|
|
951
969
|
|
|
952
|
-
createBrokerInstance(brokerType: string, label: string, values: Record<string, unknown
|
|
970
|
+
createBrokerInstance(brokerType: string, label: string, values: Record<string, unknown>, options?: BrokerInstanceCreateOptions): Promise<BrokerInstanceConfig>;
|
|
953
971
|
updateBrokerInstance(instanceId: string, values: Record<string, unknown>, options?: BrokerInstanceUpdateOptions): Promise<void>;
|
|
954
972
|
syncBrokerInstance(instanceId: string): Promise<void>;
|
|
955
973
|
removeBrokerInstance(instanceId: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ManualChartResolution } from "../time-series/resolution";
|
|
2
|
-
import type { PricePoint } from "./financials";
|
|
2
|
+
import type { ListingDelisting, PricePoint } from "./financials";
|
|
3
3
|
|
|
4
4
|
/** Declared by the actual history source, independently of quote session state. */
|
|
5
5
|
export interface HistorySession {
|
|
@@ -42,4 +42,9 @@ export interface PriceHistoryResult {
|
|
|
42
42
|
* current copy, whatever its last bar, and for a source's own answer.
|
|
43
43
|
*/
|
|
44
44
|
savedCopyBehind?: true;
|
|
45
|
+
/**
|
|
46
|
+
* The listing no longer trades: its bars end on `lastTradeDate` and no later
|
|
47
|
+
* session will add one, so a copy ending there is complete.
|
|
48
|
+
*/
|
|
49
|
+
delisting?: ListingDelisting;
|
|
45
50
|
}
|
package/src/types/ticker.ts
CHANGED
|
@@ -8,6 +8,15 @@ export interface TickerPosition {
|
|
|
8
8
|
priceBasis?: PriceBasis;
|
|
9
9
|
currency?: string;
|
|
10
10
|
dateAcquired?: string;
|
|
11
|
+
/**
|
|
12
|
+
* What one unit of the lot's `currency` cost in `costFxCurrency` when it was
|
|
13
|
+
* bought: entered with the position, or the FX close of its purchase date.
|
|
14
|
+
* Valued in that currency, the lot's cost converts at this rate rather than
|
|
15
|
+
* today's, so its P&L carries the currency's move since.
|
|
16
|
+
*/
|
|
17
|
+
costFxRate?: number;
|
|
18
|
+
/** The currency `costFxRate` converts the cost into: the portfolio's when it was entered. */
|
|
19
|
+
costFxCurrency?: string;
|
|
11
20
|
broker: string; // "manual" | future broker plugin IDs
|
|
12
21
|
side?: "long" | "short";
|
|
13
22
|
marketValue?: number;
|