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
|
@@ -3,6 +3,7 @@ import type { Portfolio, TickerRecord } from "../../../../types/ticker";
|
|
|
3
3
|
import { convertCurrency, formatCompactAmount } from "../../../../utils/format";
|
|
4
4
|
import { getCurrencySymbol } from "../../../../market-data/market/format";
|
|
5
5
|
import { getActiveQuoteDisplay } from "../../../../market-data/market/status";
|
|
6
|
+
import { combinedChangeBasisLabel, quoteChangeBasis, type QuoteChangeBasis } from "../../../../market-data/market/change-basis";
|
|
6
7
|
import { isQuoteStaleForCurrentSession } from "../../../../market-data/quotes/freshness";
|
|
7
8
|
import { headlineQuoteDisplay } from "../../../../portfolio/column-values";
|
|
8
9
|
import { isManualPortfolio } from "../../../../portfolio/mutations";
|
|
@@ -45,6 +46,13 @@ export interface PortfolioSummaryTotals {
|
|
|
45
46
|
unrealizedPnlBasis?: PortfolioPositionPnl["basis"];
|
|
46
47
|
dailyPnl: number;
|
|
47
48
|
dailyPnlPct: number;
|
|
49
|
+
/**
|
|
50
|
+
* What Day (or a watchlist's Avg Day) is measured from, as each holding's
|
|
51
|
+
* change line says it: "vs Fri 16 Oct close" when they agree, "vs mixed
|
|
52
|
+
* closes" when they do not (an HKEX listing beside a US one). Absent
|
|
53
|
+
* without a move.
|
|
54
|
+
*/
|
|
55
|
+
dayChangeBasis?: string;
|
|
48
56
|
totalCostBasis: number;
|
|
49
57
|
hasPositions: boolean;
|
|
50
58
|
unrealizedPnl: number;
|
|
@@ -131,6 +139,7 @@ export function calculatePortfolioSummaryTotals(
|
|
|
131
139
|
let hasPositions = false;
|
|
132
140
|
let watchlistChangeSum = 0;
|
|
133
141
|
let watchlistCount = 0;
|
|
142
|
+
const dayBases: Array<QuoteChangeBasis | null> = [];
|
|
134
143
|
const unavailableConversions = new Set<string>();
|
|
135
144
|
let livePriced = true;
|
|
136
145
|
const pricedLots: PricedPortfolioLot[] = [];
|
|
@@ -150,11 +159,12 @@ export function calculatePortfolioSummaryTotals(
|
|
|
150
159
|
const quoteCurrency = quote?.currency || ticker.metadata.currency || "USD";
|
|
151
160
|
|
|
152
161
|
if (!isPortfolio) {
|
|
153
|
-
// The CHG% column's value, so Avg Day is the mean of that column.
|
|
154
|
-
const changePercent = headlineQuoteDisplay(activeQuote, quote)?.changePercent;
|
|
162
|
+
// The CHG% column's value, so Avg Day is the mean of that column; a listing that no longer trades has none.
|
|
163
|
+
const changePercent = quote?.delisting ? undefined : headlineQuoteDisplay(activeQuote, quote)?.changePercent;
|
|
155
164
|
if (changePercent != null) {
|
|
156
165
|
watchlistChangeSum += changePercent;
|
|
157
166
|
watchlistCount++;
|
|
167
|
+
dayBases.push(quoteChangeBasis(quote));
|
|
158
168
|
}
|
|
159
169
|
continue;
|
|
160
170
|
}
|
|
@@ -220,9 +230,18 @@ export function calculatePortfolioSummaryTotals(
|
|
|
220
230
|
totalMktValue += marketValue.gross;
|
|
221
231
|
netMktValue += marketValue.net;
|
|
222
232
|
if (activeQuote && Number.isFinite(grossPriceUnits)) {
|
|
223
|
-
|
|
233
|
+
// A listing that no longer trades does not move: its last session's change is not today's.
|
|
234
|
+
const previousClose = quote?.delisting ? activeQuote.price
|
|
235
|
+
: activeQuote.change != null ? activeQuote.price - activeQuote.change : Number.NaN;
|
|
224
236
|
totalPrevValue += toBaseQuote(grossPriceUnits * previousClose);
|
|
225
237
|
signedDailyPnl += toBaseQuote(totalPriceUnits * (activeQuote.price - previousClose));
|
|
238
|
+
// The move valued: the latest print's from the daily reference, the regular close's from the session before it.
|
|
239
|
+
if (!quote?.delisting) {
|
|
240
|
+
dayBases.push(quoteChangeBasis(quote, {
|
|
241
|
+
session: valuationBasis === "regular-close" ? "regular" : "active",
|
|
242
|
+
terms: futuresTerms?.get(ticker.metadata.ticker),
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
226
245
|
} else {
|
|
227
246
|
// A broker mark is not evidence of an unchanged day.
|
|
228
247
|
signedDailyPnl = Number.NaN;
|
|
@@ -242,6 +261,7 @@ export function calculatePortfolioSummaryTotals(
|
|
|
242
261
|
const unrealizedPnl = signedUnrealizedPnl;
|
|
243
262
|
const unrealizedPnlPct = portfolioPnlPercent(unrealizedPnl, totalCostBasis) ?? Number.NaN;
|
|
244
263
|
const avgWatchlistChange = watchlistCount > 0 ? watchlistChangeSum / watchlistCount : 0;
|
|
264
|
+
const dayChangeBasis = combinedChangeBasisLabel(dayBases, now);
|
|
245
265
|
|
|
246
266
|
return {
|
|
247
267
|
totalMktValue,
|
|
@@ -258,6 +278,7 @@ export function calculatePortfolioSummaryTotals(
|
|
|
258
278
|
: pnlBases.size > 1 ? "mixed" : [...pnlBases][0],
|
|
259
279
|
dailyPnl,
|
|
260
280
|
dailyPnlPct,
|
|
281
|
+
...(dayChangeBasis ? { dayChangeBasis } : {}),
|
|
261
282
|
totalCostBasis,
|
|
262
283
|
hasPositions,
|
|
263
284
|
unrealizedPnl,
|
|
@@ -2,26 +2,17 @@ import { httpFetch } from "../../../utils/http-transport";
|
|
|
2
2
|
import { isoDateOrNull, numericOrNull, recordOrNull, textOrNull } from "../../../utils/guards";
|
|
3
3
|
import {
|
|
4
4
|
boardAsOf,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
buildDealerRows,
|
|
6
|
+
newestSeriesBreak,
|
|
7
|
+
sumSeries,
|
|
8
8
|
type DealerRow,
|
|
9
|
-
type
|
|
9
|
+
type SeriesPoint,
|
|
10
10
|
} from "./model";
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const API = "https://markets.newyorkfed.org/api/pd";
|
|
13
13
|
const FETCH_TIMEOUT_MS = 15_000;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
asOf: string;
|
|
17
|
-
value: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface ParsedSeries {
|
|
21
|
-
keyid: string;
|
|
22
|
-
latest: SeriesPoint | null;
|
|
23
|
-
previous: SeriesPoint | null;
|
|
24
|
-
}
|
|
14
|
+
/** The release is weekly; a series read is kept this long so moving through the board never asks twice. */
|
|
15
|
+
const HISTORY_TTL_MS = 30 * 60_000;
|
|
25
16
|
|
|
26
17
|
export interface DealerBoard {
|
|
27
18
|
seriesBreak: string;
|
|
@@ -30,52 +21,57 @@ export interface DealerBoard {
|
|
|
30
21
|
asOf: string | null;
|
|
31
22
|
}
|
|
32
23
|
|
|
33
|
-
|
|
24
|
+
/** A row's weekly history: the sum of the series behind it, oldest first. */
|
|
25
|
+
export interface DealerHistory {
|
|
26
|
+
rowId: string;
|
|
27
|
+
points: SeriesPoint[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function timeseriesRows(payload: unknown): unknown[] {
|
|
34
31
|
const root = recordOrNull(payload);
|
|
35
32
|
const pd = recordOrNull(root?.pd);
|
|
36
|
-
|
|
37
|
-
const entries: CatalogEntry[] = [];
|
|
38
|
-
for (const raw of rows) {
|
|
39
|
-
const row = recordOrNull(raw);
|
|
40
|
-
if (!row) continue;
|
|
41
|
-
const seriesBreak = textOrNull(row.seriesbreak) ?? textOrNull(row.seriesBreak);
|
|
42
|
-
const keyid = textOrNull(row.keyid) ?? textOrNull(row.keyId);
|
|
43
|
-
if (!seriesBreak || !keyid) continue;
|
|
44
|
-
entries.push({ seriesBreak, keyid, description: textOrNull(row.description) ?? "" });
|
|
45
|
-
}
|
|
46
|
-
return entries;
|
|
33
|
+
return Array.isArray(pd?.timeseries) ? pd.timeseries : Array.isArray(root?.timeseries) ? root.timeseries : [];
|
|
47
34
|
}
|
|
48
35
|
|
|
49
|
-
|
|
50
|
-
function parseSeriesObservations(payload: unknown, fallbackKeyid = ""): ParsedSeries {
|
|
36
|
+
function parseSeriesBreaks(payload: unknown): Array<{ seriesBreak: string; startDate: string }> {
|
|
51
37
|
const root = recordOrNull(payload);
|
|
52
38
|
const pd = recordOrNull(root?.pd);
|
|
53
|
-
const rows = Array.isArray(pd?.
|
|
54
|
-
const
|
|
39
|
+
const rows = Array.isArray(pd?.seriesbreaks) ? pd.seriesbreaks : [];
|
|
40
|
+
const breaks: Array<{ seriesBreak: string; startDate: string }> = [];
|
|
55
41
|
for (const raw of rows) {
|
|
56
42
|
const row = recordOrNull(raw);
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
if (!asOf || value == null) continue;
|
|
61
|
-
points.push({
|
|
62
|
-
asOf,
|
|
63
|
-
value,
|
|
64
|
-
keyid: textOrNull(row.keyid) ?? fallbackKeyid,
|
|
65
|
-
});
|
|
43
|
+
const seriesBreak = textOrNull(row?.seriesbreak) ?? textOrNull(row?.seriesBreak);
|
|
44
|
+
const startDate = isoDateOrNull(row?.startdate) ?? isoDateOrNull(row?.startDate);
|
|
45
|
+
if (seriesBreak && startDate) breaks.push({ seriesBreak, startDate });
|
|
66
46
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
47
|
+
return breaks;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The newest observation of every series that has a figure (the release writes `*` for a suppressed one). */
|
|
51
|
+
function parseLatest(payload: unknown): Map<string, SeriesPoint> {
|
|
52
|
+
const latest = new Map<string, SeriesPoint>();
|
|
53
|
+
for (const raw of timeseriesRows(payload)) {
|
|
54
|
+
const row = recordOrNull(raw);
|
|
55
|
+
const keyid = textOrNull(row?.keyid) ?? textOrNull(row?.keyId);
|
|
56
|
+
const asOf = isoDateOrNull(row?.asofdate) ?? isoDateOrNull(row?.asOfDate);
|
|
57
|
+
const value = numericOrNull(row?.value);
|
|
58
|
+
if (!keyid || !asOf || value == null) continue;
|
|
59
|
+
const known = latest.get(keyid);
|
|
60
|
+
if (!known || asOf > known.asOf) latest.set(keyid, { asOf, value });
|
|
61
|
+
}
|
|
62
|
+
return latest;
|
|
75
63
|
}
|
|
76
64
|
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
/** Every observation of one series, oldest first. */
|
|
66
|
+
function parseSeriesPoints(payload: unknown): SeriesPoint[] {
|
|
67
|
+
const points: SeriesPoint[] = [];
|
|
68
|
+
for (const raw of timeseriesRows(payload)) {
|
|
69
|
+
const row = recordOrNull(raw);
|
|
70
|
+
const asOf = isoDateOrNull(row?.asofdate) ?? isoDateOrNull(row?.asOfDate);
|
|
71
|
+
const value = numericOrNull(row?.value);
|
|
72
|
+
if (asOf && value != null) points.push({ asOf, value });
|
|
73
|
+
}
|
|
74
|
+
return points.sort((a, b) => (a.asOf < b.asOf ? -1 : a.asOf > b.asOf ? 1 : 0));
|
|
79
75
|
}
|
|
80
76
|
|
|
81
77
|
async function readJson(url: string): Promise<unknown> {
|
|
@@ -87,22 +83,101 @@ async function readJson(url: string): Promise<unknown> {
|
|
|
87
83
|
return response.json() as Promise<unknown>;
|
|
88
84
|
}
|
|
89
85
|
|
|
86
|
+
/** The series break changes about every two years; one read serves the session. */
|
|
87
|
+
let seriesBreakRead: Promise<string> | null = null;
|
|
88
|
+
|
|
89
|
+
function currentSeriesBreak(force: boolean): Promise<string> {
|
|
90
|
+
if (!seriesBreakRead || force) {
|
|
91
|
+
const read = readJson(`${API}/list/seriesbreaks.json`).then((payload) => {
|
|
92
|
+
const seriesBreak = newestSeriesBreak(parseSeriesBreaks(payload));
|
|
93
|
+
if (!seriesBreak) throw new Error("No series break was listed.");
|
|
94
|
+
return seriesBreak;
|
|
95
|
+
});
|
|
96
|
+
seriesBreakRead = read;
|
|
97
|
+
// A failed read is not kept, so the next one asks again.
|
|
98
|
+
read.catch(() => { if (seriesBreakRead === read) seriesBreakRead = null; });
|
|
99
|
+
}
|
|
100
|
+
return seriesBreakRead;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The board in two reads: the break the release is in now, and the latest
|
|
105
|
+
* figure of every series in it together with each one's change from the week
|
|
106
|
+
* before. History is not read here; see `loadDealerHistory`.
|
|
107
|
+
*/
|
|
90
108
|
export async function fetchPrimaryDealers(): Promise<DealerBoard> {
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
...selected.positions.map((entry) => ({ entry, tab: "positions" as const })),
|
|
94
|
-
...selected.fails.map((entry) => ({ entry, tab: "fails" as const })),
|
|
95
|
-
];
|
|
96
|
-
if (jobs.length === 0) throw new Error("No position series were listed.");
|
|
97
|
-
const rows = (await Promise.all(jobs.map(async ({ entry, tab }) => {
|
|
98
|
-
const parsed = parseSeriesObservations(await readJson(seriesUrl(entry.seriesBreak, entry.keyid)), entry.keyid);
|
|
99
|
-
return toDealerRow(entry, parsed, tab);
|
|
100
|
-
}))).filter((row) => row.latest != null);
|
|
109
|
+
const seriesBreak = await currentSeriesBreak(false);
|
|
110
|
+
const rows = buildDealerRows(parseLatest(await readJson(`${API}/latest/${encodeURIComponent(seriesBreak)}.json`)));
|
|
101
111
|
if (rows.length === 0) throw new Error("No positions were recognized.");
|
|
102
112
|
return {
|
|
103
|
-
seriesBreak
|
|
113
|
+
seriesBreak,
|
|
104
114
|
positions: rows.filter((row) => row.tab === "positions"),
|
|
105
115
|
fails: rows.filter((row) => row.tab === "fails"),
|
|
106
116
|
asOf: boardAsOf(rows),
|
|
107
117
|
};
|
|
108
118
|
}
|
|
119
|
+
|
|
120
|
+
interface SeriesRead {
|
|
121
|
+
at: number;
|
|
122
|
+
read: Promise<SeriesPoint[]>;
|
|
123
|
+
points: SeriesPoint[] | null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const seriesReads = new Map<string, SeriesRead>();
|
|
127
|
+
|
|
128
|
+
function seriesRead(seriesBreak: string, key: string, force: boolean): Promise<SeriesPoint[]> {
|
|
129
|
+
const id = `${seriesBreak}:${key}`;
|
|
130
|
+
const known = seriesReads.get(id);
|
|
131
|
+
if (known && !force && Date.now() - known.at < HISTORY_TTL_MS) return known.read;
|
|
132
|
+
const url = `${API}/get/${encodeURIComponent(seriesBreak)}/timeseries/${encodeURIComponent(key)}.json`;
|
|
133
|
+
const entry: SeriesRead = {
|
|
134
|
+
at: Date.now(),
|
|
135
|
+
points: null,
|
|
136
|
+
read: readJson(url).then((payload) => {
|
|
137
|
+
entry.points = parseSeriesPoints(payload);
|
|
138
|
+
return entry.points;
|
|
139
|
+
}),
|
|
140
|
+
};
|
|
141
|
+
seriesReads.set(id, entry);
|
|
142
|
+
// A failed read is not kept, so the next one asks again.
|
|
143
|
+
entry.read.catch(() => { if (seriesReads.get(id) === entry) seriesReads.delete(id); });
|
|
144
|
+
return entry.read;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** A row's history, one read per series behind it, each kept for the session. */
|
|
148
|
+
export async function loadDealerHistory(
|
|
149
|
+
seriesBreak: string,
|
|
150
|
+
row: Pick<DealerRow, "id" | "keys">,
|
|
151
|
+
force = false,
|
|
152
|
+
): Promise<DealerHistory> {
|
|
153
|
+
const series = await Promise.all(row.keys.map((key) => seriesRead(seriesBreak, key, force)));
|
|
154
|
+
return { rowId: row.id, points: sumSeries(series) };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** The points of every series behind the row when they are all in hand and fresh. */
|
|
158
|
+
function heldSeries(seriesBreak: string, row: Pick<DealerRow, "keys">): SeriesPoint[][] | null {
|
|
159
|
+
const series: SeriesPoint[][] = [];
|
|
160
|
+
for (const key of row.keys) {
|
|
161
|
+
const known = seriesReads.get(`${seriesBreak}:${key}`);
|
|
162
|
+
if (!known?.points || Date.now() - known.at >= HISTORY_TTL_MS) return null;
|
|
163
|
+
series.push(known.points);
|
|
164
|
+
}
|
|
165
|
+
return series;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Whether the row's history is in hand, so a chart can follow the selection at once. */
|
|
169
|
+
export function hasDealerHistory(seriesBreak: string, row: Pick<DealerRow, "keys">): boolean {
|
|
170
|
+
return heldSeries(seriesBreak, row) != null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** The history when every series behind the row is already in hand, so a chart can draw before any read. */
|
|
174
|
+
export function cachedDealerHistory(seriesBreak: string, row: Pick<DealerRow, "id" | "keys">): DealerHistory | null {
|
|
175
|
+
const series = heldSeries(seriesBreak, row);
|
|
176
|
+
return series ? { rowId: row.id, points: sumSeries(series) } : null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Forgets what was read, for a test or a refresh that must see the release again. */
|
|
180
|
+
export function resetPrimaryDealersCache(): void {
|
|
181
|
+
seriesBreakRead = null;
|
|
182
|
+
seriesReads.clear();
|
|
183
|
+
}
|
|
@@ -5,19 +5,26 @@ import { formatChange, formatLevel, type DealerRow } from "./model";
|
|
|
5
5
|
const level = (value: unknown) => typeof value === "number" ? formatLevel(value) : "—";
|
|
6
6
|
const change = (value: unknown) => typeof value === "number" ? formatChange(value) : "—";
|
|
7
7
|
const text = (value: unknown) => typeof value === "string" && value ? value : "—";
|
|
8
|
+
const group = (value: unknown) => typeof value === "string" ? value : "";
|
|
8
9
|
|
|
9
10
|
const COLUMNS: HeadlessPaneColumn[] = [
|
|
10
11
|
{ key: "position", header: "Position" },
|
|
12
|
+
{ key: "group", header: "Group", format: group },
|
|
11
13
|
{ key: "asOf", header: "As of", format: text },
|
|
12
14
|
{ key: "latest", header: "Latest $mn", align: "right", format: level },
|
|
13
15
|
{ key: "previous", header: "Previous $mn", align: "right", format: level },
|
|
14
16
|
{ key: "change", header: "Change $mn", align: "right", format: change },
|
|
15
17
|
];
|
|
16
18
|
|
|
19
|
+
/** The report's table sets a breakdown in under its total, as the pane does; the export names the total in `group` instead. */
|
|
20
|
+
const TEXT_COLUMNS: HeadlessPaneColumn[] = COLUMNS.filter((column) => column.key !== "group");
|
|
21
|
+
|
|
17
22
|
function reportRow(row: DealerRow) {
|
|
18
23
|
return {
|
|
19
|
-
id: row.
|
|
24
|
+
id: row.id,
|
|
20
25
|
position: row.label,
|
|
26
|
+
group: row.parent,
|
|
27
|
+
series: row.keys.join("+"),
|
|
21
28
|
asOf: row.asOf,
|
|
22
29
|
latest: row.latest,
|
|
23
30
|
previous: row.previous,
|
|
@@ -25,6 +32,24 @@ function reportRow(row: DealerRow) {
|
|
|
25
32
|
};
|
|
26
33
|
}
|
|
27
34
|
|
|
35
|
+
function textRow(row: DealerRow) {
|
|
36
|
+
return { ...reportRow(row), position: `${" ".repeat(row.depth)}${row.label}` };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function section(title: string, rows: readonly DealerRow[]) {
|
|
40
|
+
return {
|
|
41
|
+
title,
|
|
42
|
+
columns: COLUMNS,
|
|
43
|
+
rows: rows.map(reportRow),
|
|
44
|
+
textColumns: TEXT_COLUMNS,
|
|
45
|
+
textRows: rows.map(textRow),
|
|
46
|
+
unit: "USD millions",
|
|
47
|
+
rowSymbolKey: "series",
|
|
48
|
+
rowAsOfKey: "asOf",
|
|
49
|
+
interval: "weekly",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
28
53
|
export const primaryDealersHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
29
54
|
shape: "bundle",
|
|
30
55
|
argument: { kind: "none" },
|
|
@@ -35,8 +60,8 @@ export const primaryDealersHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
35
60
|
aliases: ["PDLR"],
|
|
36
61
|
dataRequirements: ["Weekly primary dealer positions and settlement fails"],
|
|
37
62
|
limitations: [
|
|
38
|
-
"
|
|
39
|
-
"Latest observation and the
|
|
63
|
+
"Net positions in Treasuries (bills, coupons by tenor, TIPS, FRN), agencies, MBS, corporates, munis and ABS; settlement fails in Treasuries, TIPS and MBS",
|
|
64
|
+
"Latest observation and the change from the week before; the weekly history is in the pane",
|
|
40
65
|
],
|
|
41
66
|
},
|
|
42
67
|
async load() {
|
|
@@ -44,8 +69,8 @@ export const primaryDealersHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
44
69
|
return {
|
|
45
70
|
complete: board.positions.length > 0,
|
|
46
71
|
sections: [
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
section("Positions", board.positions),
|
|
73
|
+
section("Fails", board.fails),
|
|
49
74
|
],
|
|
50
75
|
metadata: { asOf: board.asOf, seriesBreak: board.seriesBreak },
|
|
51
76
|
};
|
|
@@ -8,8 +8,9 @@ export const primaryDealersModule: PluginModule = {
|
|
|
8
8
|
id: "primary-dealers-pane",
|
|
9
9
|
paneId: PRIMARY_DEALERS_PANE_ID,
|
|
10
10
|
label: "Primary Dealer Positions",
|
|
11
|
-
description: "Weekly net positions
|
|
12
|
-
|
|
11
|
+
description: "Weekly net positions with history, by sector and Treasury tenor, and settlement fails.",
|
|
12
|
+
// No "muni": a muni search lands on DVD's muni funds alone (known-gaps.test.ts), not on a table of two functions.
|
|
13
|
+
keywords: ["primary", "dealer", "dealers", "positions", "fails", "treasury", "bills", "coupons", "tips", "frn", "mbs", "pdlr"],
|
|
13
14
|
shortcut: { prefix: "PDLR" },
|
|
14
15
|
headless: primaryDealersHeadless,
|
|
15
16
|
createInstance: () => ({ placement: "floating" }),
|