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
package/src/utils/format.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fixedUsdRate } from "./currency-units";
|
|
1
|
+
import { fixedUsdRate, minorUnitSign } from "./currency-units";
|
|
2
2
|
|
|
3
3
|
const currencyFormatters = new Map<string, Intl.NumberFormat>();
|
|
4
4
|
const numberFormatters = new Map<number, Intl.NumberFormat>();
|
|
@@ -47,6 +47,15 @@ function getNumberFormatter(decimals: number): Intl.NumberFormat {
|
|
|
47
47
|
* as a price in it does: USDT101.70.
|
|
48
48
|
*/
|
|
49
49
|
function formatMoney(value: number, currency: string, maximumFractionDigits: number): string {
|
|
50
|
+
// A minor unit is written after the amount: 314.95¢ in US cents, 412.50p in pence.
|
|
51
|
+
const minor = minorUnitSign(currency);
|
|
52
|
+
if (minor) {
|
|
53
|
+
const body = new Intl.NumberFormat("en-US", {
|
|
54
|
+
minimumFractionDigits: Math.min(2, maximumFractionDigits),
|
|
55
|
+
maximumFractionDigits,
|
|
56
|
+
}).format(Math.abs(value));
|
|
57
|
+
return `${value < 0 && /[1-9]/.test(body) ? "-" : ""}${body}${minor}`;
|
|
58
|
+
}
|
|
50
59
|
try {
|
|
51
60
|
return getCurrencyFormatter(currency, maximumFractionDigits).format(value);
|
|
52
61
|
} catch {
|
|
@@ -67,6 +76,27 @@ export function formatCurrency(
|
|
|
67
76
|
return formatMoney(value, currency, maximumFractionDigits);
|
|
68
77
|
}
|
|
69
78
|
|
|
79
|
+
/**
|
|
80
|
+
* An amount with its currency's code after it (259.36 USD, -5.57 CAD), for a
|
|
81
|
+
* report read by someone whose own currency shares the sign: $ alone is the
|
|
82
|
+
* US, Canadian and Australian dollar. The same decimals as `formatCurrency`;
|
|
83
|
+
* a minor unit keeps its sign (314.95¢, 412.50p).
|
|
84
|
+
*/
|
|
85
|
+
export function formatCurrencyCode(
|
|
86
|
+
value: number | undefined,
|
|
87
|
+
currency = "USD",
|
|
88
|
+
maximumFractionDigits: number = currencyPriceDigits(currency),
|
|
89
|
+
): string {
|
|
90
|
+
if (value == null || !Number.isFinite(value)) return "—";
|
|
91
|
+
if (minorUnitSign(currency)) return formatMoney(value, currency, maximumFractionDigits);
|
|
92
|
+
const code = currency.trim().toUpperCase();
|
|
93
|
+
const body = new Intl.NumberFormat("en-US", {
|
|
94
|
+
minimumFractionDigits: Math.min(currencyPriceDigits(code), maximumFractionDigits),
|
|
95
|
+
maximumFractionDigits,
|
|
96
|
+
}).format(Math.abs(value));
|
|
97
|
+
return `${value < 0 && /[1-9]/.test(body) ? "-" : ""}${body} ${code}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
70
100
|
/** Preserve fractional per-share distributions, including split-adjusted history. */
|
|
71
101
|
export function formatDistributionAmount(value: number | undefined, currency = "USD"): string {
|
|
72
102
|
if (value == null || !Number.isFinite(value)) return "—";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { BrokerContractRef } from "../types/instrument";
|
|
1
|
+
import type { BrokerContractRef, TickerListingRef } from "../types/instrument";
|
|
2
|
+
import { canonicalExchange } from "./exchanges";
|
|
3
|
+
import { optionContractIdentity } from "./options";
|
|
2
4
|
|
|
3
5
|
const normalized = (value: string | undefined): string => value?.trim().toUpperCase() ?? "";
|
|
4
6
|
|
|
@@ -33,3 +35,38 @@ export function instrumentIdentityKey(instrument: {
|
|
|
33
35
|
instrument.instrument ? brokerContractIdentityKey(instrument.instrument) : "",
|
|
34
36
|
].join("|");
|
|
35
37
|
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Whether two refs name the same contract however a broker routed or filed it: by conId when both
|
|
41
|
+
* have one; an option by its OCC contract; a share by symbol, currency and terms, where SMART names
|
|
42
|
+
* a route and not a listing and an ETF may be filed as a stock, though two named listings must agree;
|
|
43
|
+
* anything else by its definition. Which broker and profile hold it is the caller's to compare.
|
|
44
|
+
*/
|
|
45
|
+
export function sameBrokerContract(held: BrokerContractRef, contract: BrokerContractRef): boolean {
|
|
46
|
+
if (held.conId !== undefined && contract.conId !== undefined) return held.conId === contract.conId;
|
|
47
|
+
const option = optionContractIdentity(held);
|
|
48
|
+
if (option || optionContractIdentity(contract)) return option === optionContractIdentity(contract)
|
|
49
|
+
&& (held.multiplier === undefined || contract.multiplier === undefined || Number(held.multiplier) === Number(contract.multiplier));
|
|
50
|
+
const stock = (value: BrokerContractRef) => !value.secType || ["STK", "ETF"].includes(value.secType.toUpperCase());
|
|
51
|
+
if (stock(held) && stock(contract)) {
|
|
52
|
+
const venue = (value: BrokerContractRef) => [value.exchange, value.primaryExchange].map(canonicalExchange).find((name) => name && name !== "SMART") ?? "";
|
|
53
|
+
const share = (value: BrokerContractRef) => JSON.stringify([value.symbol.toUpperCase(), (value.localSymbol ?? value.symbol).toUpperCase(), value.currency,
|
|
54
|
+
value.lastTradeDateOrContractMonth, value.right, value.strike, value.multiplier]);
|
|
55
|
+
return share(held) === share(contract) && (!venue(held) || !venue(contract) || venue(held) === venue(contract));
|
|
56
|
+
}
|
|
57
|
+
const key = (value: BrokerContractRef) => JSON.stringify([
|
|
58
|
+
value.symbol.toUpperCase(), canonicalExchange(value.exchange), value.secType, value.currency, value.lastTradeDateOrContractMonth,
|
|
59
|
+
value.right, value.strike, value.multiplier, (value.localSymbol ?? value.symbol).toUpperCase(),
|
|
60
|
+
]);
|
|
61
|
+
return key(held) === key(contract);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Whether a share a broker holds is one of this listing's, for a pane bound to a listing and no
|
|
66
|
+
* broker contract: in the listing's currency, held through a route (SMART) or on its venue.
|
|
67
|
+
*/
|
|
68
|
+
export function heldOnListing(held: BrokerContractRef, listing: TickerListingRef): boolean {
|
|
69
|
+
const share = !optionContractIdentity(held) && (!held.secType || ["STK", "ETF"].includes(held.secType.toUpperCase()));
|
|
70
|
+
if (!share || !listing.currency) return false;
|
|
71
|
+
return sameBrokerContract(held, { ...held, conId: undefined, exchange: listing.exchange, primaryExchange: undefined, currency: listing.currency });
|
|
72
|
+
}
|
package/src/utils/options.ts
CHANGED
|
@@ -27,6 +27,51 @@ export function parseOptionSymbol(symbol: string): { underlying: string; expTs:
|
|
|
27
27
|
return { underlying: underlying!, expTs, strike, side: side as "C" | "P" };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/** An option ticker's contract as a broker writes it ("UBER 260821C00090000") or as OCC does ("AAPL261218C00300000"). */
|
|
31
|
+
export function parseOptionTicker(symbol: string): ReturnType<typeof parseOptionSymbol> {
|
|
32
|
+
const contract = parseOptionContract(symbol);
|
|
33
|
+
if (!contract) return null;
|
|
34
|
+
return { underlying: contract.underlying, expTs: Math.floor(Date.UTC(contract.year, contract.month - 1, contract.day) / 1000),
|
|
35
|
+
strike: contract.strike, side: contract.side };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* One contract of a chain, on the broker that served it: the underlying's
|
|
40
|
+
* broker and profile, with the expiry, side, strike and 100-share deliverable
|
|
41
|
+
* the symbol carries. Null when the underlying is not a broker's or the
|
|
42
|
+
* symbol is not a contract, and the contract then opens by its symbol alone.
|
|
43
|
+
*/
|
|
44
|
+
export function chainOptionContract(contractSymbol: string, underlying: BrokerContractRef | null | undefined, currency: string): BrokerContractRef | null {
|
|
45
|
+
const contract = parseOptionContract(contractSymbol);
|
|
46
|
+
if (!contract || !underlying?.brokerId) return null;
|
|
47
|
+
const pad = (value: number) => String(value).padStart(2, "0");
|
|
48
|
+
return {
|
|
49
|
+
brokerId: underlying.brokerId,
|
|
50
|
+
...(underlying.brokerInstanceId ? { brokerInstanceId: underlying.brokerInstanceId } : {}),
|
|
51
|
+
symbol: contract.underlying,
|
|
52
|
+
localSymbol: contractSymbol.trim().toUpperCase(),
|
|
53
|
+
secType: "OPT",
|
|
54
|
+
currency: currency || underlying.currency || "USD",
|
|
55
|
+
lastTradeDateOrContractMonth: `${contract.year}${pad(contract.month)}${pad(contract.day)}`,
|
|
56
|
+
right: contract.side,
|
|
57
|
+
strike: contract.strike,
|
|
58
|
+
multiplier: "100",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The OCC identity of an option contract, from its symbol or its fields,
|
|
64
|
+
* however a broker writes the date or routes it; null for anything else.
|
|
65
|
+
*/
|
|
66
|
+
export function optionContractIdentity(contract: BrokerContractRef): string | null {
|
|
67
|
+
if (contract.secType?.toUpperCase() !== "OPT" && contract.secType?.toUpperCase() !== "OPTION") return null;
|
|
68
|
+
const parsed = parseOptionContract(contract.localSymbol ?? "") ?? parseOptionContract(contract.symbol);
|
|
69
|
+
if (parsed) return `${parsed.underlying}|${parsed.year}${String(parsed.month).padStart(2, "0")}${String(parsed.day).padStart(2, "0")}|${parsed.side}|${parsed.strike}`;
|
|
70
|
+
const date = contract.lastTradeDateOrContractMonth?.replace(/\D/g, "");
|
|
71
|
+
if (!date || date.length !== 8 || !contract.right || contract.strike === undefined) return null;
|
|
72
|
+
return `${contract.symbol.trim().toUpperCase()}|${date}|${contract.right}|${contract.strike}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
30
75
|
export interface ResolvedOptionsTarget {
|
|
31
76
|
isOptionTicker: boolean;
|
|
32
77
|
parsedOption: ReturnType<typeof parseOptionSymbol>;
|
|
@@ -53,7 +98,7 @@ export function resolveOptionsTarget(ticker: TickerRecord | null | undefined): R
|
|
|
53
98
|
if (!ticker) return null;
|
|
54
99
|
|
|
55
100
|
const isOptionTicker = ticker.metadata.assetCategory === "OPT";
|
|
56
|
-
const parsedOption = isOptionTicker ?
|
|
101
|
+
const parsedOption = isOptionTicker ? parseOptionTicker(ticker.metadata.ticker) : null;
|
|
57
102
|
const effectiveTicker = parsedOption?.underlying ?? ticker.metadata.ticker;
|
|
58
103
|
|
|
59
104
|
if (!effectiveTicker) return null;
|
|
@@ -7,6 +7,7 @@ import { zonedDateTimeParts } from "./zoned-date-time";
|
|
|
7
7
|
import { regularHistorySessionStaleness } from "../market-data/history-session";
|
|
8
8
|
import type { HistorySession } from "../types/price-history";
|
|
9
9
|
import { BAR_INTERVAL_UNIT_MS, parseBarInterval } from "../time-series/resolution";
|
|
10
|
+
import { parseOptionTicker } from "./options";
|
|
10
11
|
|
|
11
12
|
// A venue without session hours here (OTC Markets, Cboe Canada) has no
|
|
12
13
|
// session to hold: its copy is current while the latest bar is this recent.
|
|
@@ -217,6 +218,9 @@ export function isPriceHistoryStaleForCurrentWindow(
|
|
|
217
218
|
// Daily/weekly/monthly labels are period starts, not live observation times.
|
|
218
219
|
// Their cache policy controls refresh; an intraday lag test is inapplicable.
|
|
219
220
|
if (intervalMs != null && intervalMs >= DAY_MS) return false;
|
|
221
|
+
// An option contract can go hours without a trade, so its last bar's age says nothing of
|
|
222
|
+
// its source; judged on it, a contract quiet since the open had no chart at all.
|
|
223
|
+
if (options.symbol && parseOptionTicker(options.symbol)) return false;
|
|
220
224
|
|
|
221
225
|
const latestTime = getPricePointTimestamp(latest);
|
|
222
226
|
if (!Number.isFinite(latestTime)) return false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveCurrencyUnit } from "./currency-units";
|
|
2
|
-
import { formatCompact, formatCurrency, formatNumber } from "./format";
|
|
2
|
+
import { formatCompact, formatCurrency, formatCurrencyCode, formatNumber } from "./format";
|
|
3
3
|
|
|
4
4
|
function perShareDecimals(value: number): number {
|
|
5
5
|
const magnitude = Math.abs(value);
|
|
@@ -17,15 +17,19 @@ export function formatPerShareNumber(value: number | undefined): string {
|
|
|
17
17
|
return formatNumber(value === 0 ? 0 : value, perShareDecimals(value)).replace(/(\.\d{2}.*?)0+$/, "$1");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Keep reported monetary amounts in their own units, independently of a
|
|
22
|
+
* quote. A per-share amount reads with its sign ($6.54), or with `code` its
|
|
23
|
+
* code (6.54 USD) as every other amount does.
|
|
24
|
+
*/
|
|
25
|
+
export function formatReportedMoney(value: number | undefined, currency?: string, perShare = false, code = false): string {
|
|
22
26
|
if (value == null || !Number.isFinite(value)) return "—";
|
|
23
27
|
const amount = perShare ? formatPerShareNumber(value) : formatCompact(value);
|
|
24
28
|
const unit = currency?.trim();
|
|
25
29
|
if (!unit) return `${amount} (ccy?)`;
|
|
26
30
|
// Intl uppercases currency codes: GBp must not become GBP without scaling.
|
|
27
31
|
if (perShare && !usesScientificNotation(value) && /^[a-z]{3}$/i.test(unit) && resolveCurrencyUnit(unit).divisor === 1) {
|
|
28
|
-
return formatCurrency(value === 0 ? 0 : value, unit, perShareDecimals(value));
|
|
32
|
+
return (code ? formatCurrencyCode : formatCurrency)(value === 0 ? 0 : value, unit, perShareDecimals(value));
|
|
29
33
|
}
|
|
30
34
|
return `${amount} ${unit}`;
|
|
31
35
|
}
|