gloomberb 0.16.4 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -91
- package/package.json +4 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/data.ts +24 -2
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +4 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/types.ts +17 -1
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +15 -1
- package/src/app/pane-runtime/ticker-open-runtime.ts +7 -3
- package/src/architecture/core-builtin-allowlist.json +4 -13
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/cli/commands/crypto-hints.ts +7 -0
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +407 -104
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +93 -20
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +82 -9
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +88 -11
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +59 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +429 -0
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +21 -7
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +417 -56
- package/src/cli/not-a-ticker.ts +12 -5
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +3 -2
- package/src/cli/pane-functions/catalog.ts +35 -5
- package/src/cli/pane-functions/data.ts +12 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +20 -6
- package/src/cli/pane-functions/freshness.ts +363 -43
- package/src/cli/pane-functions/function-help.ts +12 -5
- package/src/cli/pane-functions/headless.ts +45 -17
- package/src/cli/pane-functions/index.ts +63 -10
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +63 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +49 -12
- package/src/cli/pane-functions/screenshot.ts +110 -23
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +4 -1
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +40 -6
- package/src/components/chart/composite/legend.tsx +49 -2
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +3 -0
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/pane/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +24 -1
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +25 -7
- package/src/components/layout/shell/menu.ts +5 -0
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/layers.tsx +192 -45
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +10 -1
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +17 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +2 -0
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +61 -4
- package/src/i18n/ja.ts +61 -4
- package/src/i18n/ko.ts +61 -4
- package/src/i18n/zh-cn.ts +61 -4
- package/src/i18n/zh-tw.ts +61 -4
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +81 -18
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +3 -0
- package/src/market-data/quotes/metadata.ts +7 -24
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +30 -12
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/controller/index.ts +2 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/pane.tsx +4 -2
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/index.tsx +2 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +2 -0
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +1 -1
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +56 -25
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +101 -16
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +17 -8
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +26 -9
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/client.ts +14 -4
- package/src/plugins/builtin/iv-history/headless.ts +7 -4
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +111 -7
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +1 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -11
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +67 -61
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +331 -65
- package/src/plugins/builtin/portfolio-list/cli/render.ts +200 -31
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +24 -0
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +34 -4
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +9 -0
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/headless.ts +1 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +3 -1
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/registry/index.ts +89 -4
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +123 -6
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +62 -0
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +7 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +3 -0
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/styles.css +61 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +17 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +19 -11
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +2 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/sources/gloomberb-cloud/index.ts +7 -7
- package/src/sources/gloomberb-cloud/normalizers.ts +1 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sync/core-contributors.ts +1 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +45 -7
- package/src/tickers/search/ranking.ts +33 -17
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +95 -16
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +6 -0
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +61 -0
- package/src/types/plugin.ts +19 -0
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +18 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +7 -1
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +107 -1
- package/src/utils/format.ts +16 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +51 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import type { DataProvider
|
|
1
|
+
import type { DataProvider } from "../../../types/data-provider";
|
|
2
2
|
import { parseInsiderFiling, type ParsedInsiderFiling } from "./model";
|
|
3
3
|
import { isInsiderForm } from "./insider-data";
|
|
4
|
+
import { filesAsForeignPrivateIssuer } from "./issuer";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
// Recent EDGAR dumps cap at 1,000 mixed forms; older archives are read until
|
|
7
|
+
// this many filings or the company's history ends.
|
|
8
|
+
const SEC_FILING_SCAN_LIMIT = 20_000;
|
|
9
|
+
|
|
10
|
+
export interface InsiderFilingsLoad {
|
|
11
|
+
/** The rows of the company's own Form 4 filings, newest first. */
|
|
12
|
+
parsed: ParsedInsiderFiling[];
|
|
13
|
+
/** Every Form 4 listed was read, none is the company's own, and it reports as a foreign private issuer. */
|
|
14
|
+
foreignPrivateIssuer: boolean;
|
|
15
|
+
/** The SEC lists no filing of any form for the company. */
|
|
16
|
+
noFilings: boolean;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
@@ -18,29 +21,41 @@ function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
|
18
21
|
throw signal.reason instanceof Error ? signal.reason : new Error("Insider filing load was aborted.");
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Reads the company's Form 4 filings newest first, one at a time, until
|
|
26
|
+
* `limit` of them are its own. A form it filed as an owner of another
|
|
27
|
+
* company's shares is read and left out, so a list of only those is read to
|
|
28
|
+
* the end before it can say there are none.
|
|
29
|
+
*/
|
|
21
30
|
export async function loadParsedInsiderFilings(
|
|
22
31
|
provider: DataProvider,
|
|
23
32
|
symbol: string,
|
|
24
33
|
options: { limit: number; exchange?: string; signal?: AbortSignal },
|
|
25
|
-
): Promise<
|
|
34
|
+
): Promise<InsiderFilingsLoad> {
|
|
35
|
+
if (!provider.getSecFilings) throw new Error("Insider filing data unavailable");
|
|
26
36
|
if (!provider.getSecFilingContent) throw new Error("Insider filing content unavailable");
|
|
27
|
-
const filings =
|
|
28
|
-
provider,
|
|
29
|
-
symbol,
|
|
30
|
-
20_000,
|
|
31
|
-
options.exchange,
|
|
32
|
-
)).slice(0, options.limit);
|
|
37
|
+
const filings = await provider.getSecFilings(symbol, SEC_FILING_SCAN_LIMIT, options.exchange ?? "");
|
|
33
38
|
|
|
34
39
|
const parsed: ParsedInsiderFiling[] = [];
|
|
40
|
+
let own = 0;
|
|
35
41
|
for (const filing of filings) {
|
|
42
|
+
if (own >= options.limit) break;
|
|
43
|
+
if (!isInsiderForm(filing.form)) continue;
|
|
36
44
|
throwIfAborted(options.signal);
|
|
45
|
+
let content: string | null;
|
|
37
46
|
try {
|
|
38
|
-
|
|
39
|
-
parsed.push(...parseInsiderFiling(filing, content));
|
|
47
|
+
content = await provider.getSecFilingContent(filing);
|
|
40
48
|
} catch {
|
|
41
49
|
throwIfAborted(options.signal);
|
|
50
|
+
// An unread filing may be the company's own; it stays as a row that says so.
|
|
42
51
|
parsed.push({ filing, transaction: null, isLoading: false });
|
|
52
|
+
own += 1;
|
|
53
|
+
continue;
|
|
43
54
|
}
|
|
55
|
+
const entries = parseInsiderFiling(filing, content);
|
|
56
|
+
if (entries.length === 0) continue;
|
|
57
|
+
parsed.push(...entries);
|
|
58
|
+
own += 1;
|
|
44
59
|
}
|
|
45
|
-
return parsed;
|
|
60
|
+
return { parsed, foreignPrivateIssuer: own === 0 && filesAsForeignPrivateIssuer(filings), noFilings: filings.length === 0 };
|
|
46
61
|
}
|
|
@@ -3,9 +3,11 @@ import type {
|
|
|
3
3
|
HeadlessPaneContext,
|
|
4
4
|
HeadlessPaneDefinition,
|
|
5
5
|
HeadlessPaneLoadArgs,
|
|
6
|
+
HeadlessPaneRow,
|
|
6
7
|
} from "../../../types/plugin";
|
|
7
8
|
import { formatCompact, formatCurrency } from "../../../utils/format";
|
|
8
|
-
import { loadParsedInsiderFilings } from "./client";
|
|
9
|
+
import { loadParsedInsiderFilings, type InsiderFilingsLoad } from "./client";
|
|
10
|
+
import { insiderEmptyNotice } from "./issuer";
|
|
9
11
|
import {
|
|
10
12
|
buildInsiderRows,
|
|
11
13
|
buildInsiderSummary,
|
|
@@ -15,9 +17,12 @@ import {
|
|
|
15
17
|
matchesInsiderTypeFilter,
|
|
16
18
|
type ParsedInsiderFiling,
|
|
17
19
|
} from "./model";
|
|
18
|
-
import { relevantInsiderAmendments } from "./amendments";
|
|
20
|
+
import { isAmendedInsiderFiling, relevantInsiderAmendments } from "./amendments";
|
|
19
21
|
import { formatInsiderName } from "./display";
|
|
20
22
|
import { SEC_FILINGS } from "../shared/report-freshness";
|
|
23
|
+
import { resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
24
|
+
import { noSecReportsNotice } from "../../../utils/sec";
|
|
25
|
+
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
21
26
|
|
|
22
27
|
const INSIDER_COLUMNS: HeadlessPaneColumn[] = [
|
|
23
28
|
{ key: "form", header: "Form" },
|
|
@@ -62,15 +67,23 @@ const INSIDER_COLUMNS: HeadlessPaneColumn[] = [
|
|
|
62
67
|
align: "right",
|
|
63
68
|
format: (value) => value == null ? "-" : `$${formatCompact(Number(value))}`,
|
|
64
69
|
},
|
|
70
|
+
// An amendment's original date, remarks and footnotes, under the amendment's own row.
|
|
71
|
+
{ key: "note", header: "Note", underRow: true, format: (value) => typeof value === "string" ? value : "" },
|
|
65
72
|
];
|
|
66
73
|
|
|
74
|
+
/** What a Form 4/A says about itself, for its last row in the report. */
|
|
75
|
+
function amendmentNote(entry: ParsedInsiderFiling): string {
|
|
76
|
+
const original = entry.disclosure?.originalFilingDate;
|
|
77
|
+
return [original ? `Original filed ${original}` : "", ...buildInsiderDisclosureText(entry).split("\n")].filter(Boolean).join("\n");
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
export interface InsiderHeadlessDependencies {
|
|
68
81
|
loadParsed(
|
|
69
82
|
symbol: string,
|
|
70
83
|
limit: number,
|
|
71
84
|
args: HeadlessPaneLoadArgs,
|
|
72
85
|
ctx: HeadlessPaneContext,
|
|
73
|
-
): Promise<
|
|
86
|
+
): Promise<InsiderFilingsLoad>;
|
|
74
87
|
}
|
|
75
88
|
|
|
76
89
|
const defaultDependencies: InsiderHeadlessDependencies = {
|
|
@@ -80,6 +93,17 @@ const defaultDependencies: InsiderHeadlessDependencies = {
|
|
|
80
93
|
}),
|
|
81
94
|
};
|
|
82
95
|
|
|
96
|
+
/**
|
|
97
|
+
* "CAR Group (ASX) files no SEC reports." for a listing abroad the SEC lists
|
|
98
|
+
* nothing for, as `filings` says it; null for a US listing or a symbol with no
|
|
99
|
+
* venue, whose empty list is only no Form 4.
|
|
100
|
+
*/
|
|
101
|
+
async function noSecReportsEmpty(ctx: HeadlessPaneContext, key: string): Promise<string | null> {
|
|
102
|
+
const listing = await resolveHeadlessIssuerListing(ctx, key);
|
|
103
|
+
if (!listing.exchange) return null;
|
|
104
|
+
return noSecReportsNotice({ symbol: parsePublicTickerKey(key).symbol, exchange: listing.exchange, name: listing.name ?? null });
|
|
105
|
+
}
|
|
106
|
+
|
|
83
107
|
export function createInsiderHeadless(
|
|
84
108
|
dependencies: InsiderHeadlessDependencies = defaultDependencies,
|
|
85
109
|
): HeadlessPaneDefinition<"rows"> {
|
|
@@ -113,7 +137,7 @@ export function createInsiderHeadless(
|
|
|
113
137
|
{
|
|
114
138
|
key: "limit",
|
|
115
139
|
aliases: ["count", "rows"],
|
|
116
|
-
description: "Maximum Form 4 and Form 4/A filings to parse.",
|
|
140
|
+
description: "Maximum of the company's own Form 4 and Form 4/A filings to parse.",
|
|
117
141
|
type: "integer",
|
|
118
142
|
defaultValue: 20,
|
|
119
143
|
minimum: 1,
|
|
@@ -125,7 +149,9 @@ export function createInsiderHeadless(
|
|
|
125
149
|
async load(args, ctx) {
|
|
126
150
|
const symbol = args.symbols[0]!;
|
|
127
151
|
const limit = Number(args.options.limit);
|
|
128
|
-
const parsed = await dependencies.loadParsed(symbol, limit, args, ctx);
|
|
152
|
+
const { parsed, foreignPrivateIssuer, noFilings } = await dependencies.loadParsed(symbol, limit, args, ctx);
|
|
153
|
+
const empty = parsed.length > 0 ? null
|
|
154
|
+
: (noFilings ? await noSecReportsEmpty(ctx, symbol) : null) ?? insiderEmptyNotice(foreignPrivateIssuer);
|
|
129
155
|
const name = String(args.options.name ?? "").trim().toLocaleLowerCase();
|
|
130
156
|
const type = isInsiderTypeFilter(args.options.type) ? args.options.type : "all";
|
|
131
157
|
const owned = name
|
|
@@ -136,8 +162,16 @@ export function createInsiderHeadless(
|
|
|
136
162
|
const incomplete = [...new Set(buildInsiderRows(parsed)
|
|
137
163
|
.filter((row) => row.status !== "parsed" && row.status !== "disclosure")
|
|
138
164
|
.map((row) => row.accessionNumber))];
|
|
165
|
+
// A filing's lines sit together, so its note goes once, under the last of them.
|
|
166
|
+
const rows: HeadlessPaneRow[] = buildInsiderRows(filtered, parsed).map((row, index) => {
|
|
167
|
+
const entry = filtered[index]!;
|
|
168
|
+
const last = filtered[index + 1]?.filing.accessionNumber !== entry.filing.accessionNumber;
|
|
169
|
+
return isAmendedInsiderFiling(entry) && last ? { ...row, note: amendmentNote(entry) || null } : row;
|
|
170
|
+
});
|
|
139
171
|
return {
|
|
140
|
-
rows
|
|
172
|
+
rows,
|
|
173
|
+
// Nothing at all: the company has no Form 4 of its own, which is the whole answer.
|
|
174
|
+
...(empty ? { empty, unavailableSymbols: [] } : {}),
|
|
141
175
|
errors: [
|
|
142
176
|
...incomplete.map((accessionNumber) => `${accessionNumber}: Form 4 transactions are unavailable or incomplete.`),
|
|
143
177
|
...amendments.map((scope) => `${scope.accessionNumber}: Form 4/A is unreconciled; affected transaction totals are unavailable.`),
|
|
@@ -146,11 +180,7 @@ export function createInsiderHeadless(
|
|
|
146
180
|
symbol,
|
|
147
181
|
summary: buildInsiderSummary(owned, Date.now(), parsed),
|
|
148
182
|
amendments,
|
|
149
|
-
|
|
150
|
-
const entry = parsed.find(({ filing }) => filing.accessionNumber === scope.accessionNumber)!;
|
|
151
|
-
return [`Form 4/A ${scope.accessionNumber}${scope.originalFilingDate ? ` | Original filed ${scope.originalFilingDate}` : ""}`,
|
|
152
|
-
buildInsiderDisclosureText(entry)].filter(Boolean).join("\n");
|
|
153
|
-
}),
|
|
183
|
+
foreignPrivateIssuer,
|
|
154
184
|
parsed: new Set(parsed.filter(({ transaction }) => transaction != null).map(({ filing }) => filing.accessionNumber)).size,
|
|
155
185
|
transactions: filtered.filter(({ transaction }) => transaction != null).length,
|
|
156
186
|
requested: limit,
|
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
type StatItem,
|
|
23
23
|
} from "../../../components";
|
|
24
24
|
import { useDebouncedPluginPaneState, usePluginPaneState } from "../../runtime";
|
|
25
|
-
import { mayBeUsEquityTicker } from "../../../utils/sec";
|
|
25
|
+
import { mayBeSecEquityListing, mayBeUsEquityTicker, noSecReportsNotice, nonUsSecListingVenue } from "../../../utils/sec";
|
|
26
|
+
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
26
27
|
import { formatCompact } from "../../../utils/format";
|
|
27
28
|
import { nextHeaderSort } from "../../../utils/sort-values";
|
|
28
29
|
import { formatShortDate } from "../../../utils/datetime-format";
|
|
@@ -48,6 +49,7 @@ import {
|
|
|
48
49
|
import { formatInsiderName } from "./display";
|
|
49
50
|
import { insiderHeadless } from "./headless";
|
|
50
51
|
import { isInsiderForm } from "./insider-data";
|
|
52
|
+
import { filesAsForeignPrivateIssuer, insiderEmptyNotice, isOtherIssuerFiling } from "./issuer";
|
|
51
53
|
import { relevantInsiderAmendments } from "./amendments";
|
|
52
54
|
import { usePaneTickerIdentity } from "../../../state/hooks/pane-ticker";
|
|
53
55
|
import {
|
|
@@ -130,7 +132,9 @@ function InsiderView({ width, height, focused }: { width: number; height: number
|
|
|
130
132
|
[setOpenItemIdState],
|
|
131
133
|
);
|
|
132
134
|
const [sort, setSort] = useState<StackSortPreference<InsiderColumnId>>({ columnId: "date", direction: "desc" });
|
|
133
|
-
const eligibleTicker =
|
|
135
|
+
const eligibleTicker = mayBeSecEquityListing(ticker);
|
|
136
|
+
// A listing abroad is looked up by its company; an empty list means it files nothing with the SEC.
|
|
137
|
+
const abroadVenue = ticker ? nonUsSecListingVenue(ticker.metadata.ticker, ticker.metadata.exchange) : null;
|
|
134
138
|
const instrument = instrumentFromTicker(ticker, ticker?.metadata.ticker ?? null);
|
|
135
139
|
|
|
136
140
|
const filingsEntry = useSecFilingsQuery(
|
|
@@ -185,6 +189,17 @@ function InsiderView({ width, height, focused }: { width: number; height: number
|
|
|
185
189
|
scopeKey: `${ticker?.metadata.ticker ?? "none"}:${ticker?.metadata.exchange ?? ""}`,
|
|
186
190
|
targets: visibleForm4Filings,
|
|
187
191
|
});
|
|
192
|
+
// The list also holds the Form 4s the company filed as an owner of another
|
|
193
|
+
// company's shares, which only their documents tell apart. Until one of its
|
|
194
|
+
// own is read, the pages are read on to the end, so a list of none says so.
|
|
195
|
+
const ownerFilingsShown = useMemo(() => visibleForm4Filings.some((filing) => (
|
|
196
|
+
isOtherIssuerFiling(filing, contentMap.get(filing.accessionNumber))
|
|
197
|
+
)), [contentMap, visibleForm4Filings]);
|
|
198
|
+
const ownFilingShown = useMemo(() => visibleForm4Filings.some((filing) => (
|
|
199
|
+
contentMap.has(filing.accessionNumber) && !isOtherIssuerFiling(filing, contentMap.get(filing.accessionNumber))
|
|
200
|
+
)), [contentMap, visibleForm4Filings]);
|
|
201
|
+
const searchingOwn = !ownFilingShown && pendingCount === 0 && shownCount < form4Filings.length;
|
|
202
|
+
const noOwnFilings = !loading && !ownFilingShown && pendingCount === 0 && shownCount >= form4Filings.length;
|
|
188
203
|
|
|
189
204
|
const allParsed: ParsedFiling[] = useMemo(() => visibleForm4Filings.flatMap((filing) => {
|
|
190
205
|
const hasContent = contentMap.has(filing.accessionNumber);
|
|
@@ -223,13 +238,13 @@ function InsiderView({ width, height, focused }: { width: number; height: number
|
|
|
223
238
|
// load here until it fills a page, back to a year at most.
|
|
224
239
|
const oldestShown = visibleForm4Filings[visibleForm4Filings.length - 1]?.filingDate;
|
|
225
240
|
const oldestShownTime = oldestShown ? new Date(oldestShown).getTime() : Number.NaN;
|
|
226
|
-
const wantsOlderFilings = (typeFilter !== "all" || nameFilter != null)
|
|
241
|
+
const wantsOlderFilings = (typeFilter !== "all" || nameFilter != null || ownerFilingsShown)
|
|
227
242
|
&& shown.length < Math.max(FORM4_PAGE_SIZE, height)
|
|
228
243
|
&& shownCount < Math.min(form4Filings.length, AUTO_FILL_FILING_CAP)
|
|
229
244
|
&& oldestShownTime >= Date.now() - AUTO_FILL_DAYS * DAY_MS;
|
|
230
245
|
useEffect(() => {
|
|
231
|
-
if (wantsOlderFilings && pendingCount === 0) loadNextPage();
|
|
232
|
-
}, [loadNextPage, pendingCount, shownCount, wantsOlderFilings]);
|
|
246
|
+
if (searchingOwn || (wantsOlderFilings && pendingCount === 0)) loadNextPage();
|
|
247
|
+
}, [loadNextPage, pendingCount, searchingOwn, shownCount, wantsOlderFilings]);
|
|
233
248
|
|
|
234
249
|
const summary = useMemo(() => buildInsiderSummaryFigures(parsed, Date.now(), allParsed), [parsed, allParsed]);
|
|
235
250
|
// A page loading in on scroll clears the totals until it is read; the last
|
|
@@ -353,15 +368,17 @@ function InsiderView({ width, height, focused }: { width: number; height: number
|
|
|
353
368
|
if (authWall) return <SignInWall placement="insider-signin" action="view insider transactions" needsVerification={cloudSession.needsVerification} />;
|
|
354
369
|
if (loading && allFilings.length === 0) return <Spinner label="Loading insider filings..." />;
|
|
355
370
|
if (error && allFilings.length === 0) return <EmptyState title="Insider filings unavailable." message={error} />;
|
|
356
|
-
if (
|
|
357
|
-
return renderFilingNotice(
|
|
371
|
+
if (noOwnFilings) {
|
|
372
|
+
return renderFilingNotice(abroadVenue && allFilings.length === 0
|
|
373
|
+
? noSecReportsNotice({ symbol: parsePublicTickerKey(ticker.metadata.ticker).symbol, exchange: abroadVenue, name: ticker.metadata.name ?? null })
|
|
374
|
+
: insiderEmptyNotice(filesAsForeignPrivateIssuer(allFilings)), width);
|
|
358
375
|
}
|
|
359
376
|
|
|
360
377
|
// Until a filing is read there is nothing to say; after that the empty
|
|
361
378
|
// list says how far back the filings it has read go, while older ones load.
|
|
362
379
|
const oldestRead = allParsed.findLast((entry) => !entry.isLoading)?.filing.filingDate;
|
|
363
380
|
const since = oldestRead ? ` since ${formatShortDate(oldestRead, { utc: true })}` : "";
|
|
364
|
-
const emptyTitle = typeCounts.all === 0 && (pendingCount > 0 || wantsOlderFilings)
|
|
381
|
+
const emptyTitle = typeCounts.all === 0 && (pendingCount > 0 || wantsOlderFilings || searchingOwn)
|
|
365
382
|
? "Loading Form 4 transactions..."
|
|
366
383
|
: typeFilter === "trades"
|
|
367
384
|
? `No open-market buys or sells${nameFilter ? " by this insider" : ""}${since}.`
|
|
@@ -458,7 +475,7 @@ export const insiderModule: PluginModule = {
|
|
|
458
475
|
description: "Insider transaction activity for the selected ticker.",
|
|
459
476
|
keywords: ["insider", "form 4", "ownership", "transactions", "ins"],
|
|
460
477
|
shortcut: "INS",
|
|
461
|
-
canCreate: (_context, options) => !options?.ticker ||
|
|
478
|
+
canCreate: (_context, options) => !options?.ticker || mayBeSecEquityListing(options.ticker),
|
|
462
479
|
}),
|
|
463
480
|
headless: insiderHeadless,
|
|
464
481
|
},
|
|
@@ -104,6 +104,16 @@ function disclosureText(xml: string): string {
|
|
|
104
104
|
return decodeHtmlEntities(xml.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1").replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim());
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* The CIK of the company whose shares the form reports, without leading
|
|
109
|
+
* zeros, or null when the document is not a Form 4 or names none.
|
|
110
|
+
*/
|
|
111
|
+
export function parseForm4IssuerCik(xml: string): string | null {
|
|
112
|
+
if (!/<(?:[\w.-]+:)?ownershipDocument(?:\s|>)/i.test(xml)) return null;
|
|
113
|
+
const cik = tagText(tagContent(xml, "issuer") ?? "", "issuerCik").replace(/^0+/, "");
|
|
114
|
+
return /^\d+$/.test(cik) ? cik : null;
|
|
115
|
+
}
|
|
116
|
+
|
|
107
117
|
export function parseForm4Disclosure(xml: string): InsiderFilingDisclosure | null {
|
|
108
118
|
if (!/<(?:[\w.-]+:)?ownershipDocument(?:\s|>)/i.test(xml)) return null;
|
|
109
119
|
const original = tagText(xml, "dateOfOriginalSubmission");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SecFilingItem } from "../../../types/data-provider";
|
|
2
|
+
import { parseForm4IssuerCik } from "./insider-data";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A company's SEC filing list holds every Form 4 it is named on: its insiders'
|
|
6
|
+
* trades in its shares, and the ones it filed itself as an owner of another
|
|
7
|
+
* company's shares (Banco Santander buying Santander Consumer, Sanofi
|
|
8
|
+
* converting Regeneron notes). Only the form's issuer tells them apart, so a
|
|
9
|
+
* filing is the company's own until its document names another issuer.
|
|
10
|
+
*/
|
|
11
|
+
export function isOtherIssuerFiling(filing: SecFilingItem, content: string | null | undefined): boolean {
|
|
12
|
+
if (!content) return false;
|
|
13
|
+
const issuer = parseForm4IssuerCik(content);
|
|
14
|
+
const company = filing.cik.trim().replace(/^0+/, "");
|
|
15
|
+
return issuer != null && /^\d+$/.test(company) && issuer !== company;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const FOREIGN_PRIVATE_ISSUER_FORM = /^(?:20-F|40-F|6-K)(?:\/A)?$/i;
|
|
19
|
+
const DOMESTIC_REPORT_FORM = /^(?:10-KT?|10-QT?|8-K)(?:\/A)?$/i;
|
|
20
|
+
|
|
21
|
+
function newestFiled(filings: readonly SecFilingItem[], form: RegExp): number {
|
|
22
|
+
let newest = Number.NEGATIVE_INFINITY;
|
|
23
|
+
for (const filing of filings) {
|
|
24
|
+
if (!form.test(filing.form.trim())) continue;
|
|
25
|
+
const time = new Date(filing.filingDate).getTime();
|
|
26
|
+
if (Number.isFinite(time) && time > newest) newest = time;
|
|
27
|
+
}
|
|
28
|
+
return newest;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The company reports as a foreign private issuer: its newest report is a
|
|
33
|
+
* 20-F, 40-F or 6-K rather than a 10-K, 10-Q or 8-K. Such an issuer's insiders
|
|
34
|
+
* file no Form 4, so its list holds only the forms it filed as an owner.
|
|
35
|
+
*/
|
|
36
|
+
export function filesAsForeignPrivateIssuer(filings: readonly SecFilingItem[]): boolean {
|
|
37
|
+
const foreign = newestFiled(filings, FOREIGN_PRIVATE_ISSUER_FORM);
|
|
38
|
+
return Number.isFinite(foreign) && foreign > newestFiled(filings, DOMESTIC_REPORT_FORM);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* What the pane, `fn INS` and `insider` say when a company has no Form 4 of
|
|
43
|
+
* its own. Each already names the company above it.
|
|
44
|
+
*/
|
|
45
|
+
export function insiderEmptyNotice(foreignPrivateIssuer: boolean): string {
|
|
46
|
+
return foreignPrivateIssuer
|
|
47
|
+
? "No Form 4 insiders: foreign private issuers file none."
|
|
48
|
+
: "No Form 4 insider filings.";
|
|
49
|
+
}
|
|
@@ -3,6 +3,7 @@ import { formatCompact, formatCurrency } from "../../../utils/format";
|
|
|
3
3
|
import { parseForm4Xml, parseForm4Disclosure, transactionTypeLabel, type InsiderTransaction, type InsiderFilingDisclosure, type InsiderReportingOwner } from "./insider-data";
|
|
4
4
|
import { affectingInsiderAmendments, buildInsiderAmendmentScopes, isAmendedInsiderFiling } from "./amendments";
|
|
5
5
|
import { formatInsiderName, isOpenMarketTrade, shortInsiderRole } from "./display";
|
|
6
|
+
import { isOtherIssuerFiling } from "./issuer";
|
|
6
7
|
|
|
7
8
|
const NINETY_DAYS_MS = 90 * 24 * 60 * 60 * 1000;
|
|
8
9
|
|
|
@@ -13,7 +14,9 @@ export interface ParsedInsiderFiling {
|
|
|
13
14
|
disclosure?: InsiderFilingDisclosure | null;
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
/** The rows of one filing; none for a Form 4 the company filed as an owner of another issuer. */
|
|
16
18
|
export function parseInsiderFiling(filing: SecFilingItem, content: string | null, isLoading = false): ParsedInsiderFiling[] {
|
|
19
|
+
if (isOtherIssuerFiling(filing, content)) return [];
|
|
17
20
|
const transactions = content ? parseForm4Xml(content) : [];
|
|
18
21
|
const disclosure = content ? parseForm4Disclosure(content) : null;
|
|
19
22
|
return transactions.length
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { apiClient } from "../../../api-client";
|
|
2
|
-
import {
|
|
2
|
+
import { listingAbroadVenue, usListingSymbol } from "../../../utils/sec";
|
|
3
3
|
import { getSharedMarketDataCoordinator, MarketDataCoordinator, resolveEntryValue } from "../../../market-data/coordinator";
|
|
4
4
|
import type { ChartRequest, InstrumentRef } from "../../../market-data/request-types";
|
|
5
5
|
import type { QueryEntry } from "../../../market-data/result-types";
|
|
@@ -8,7 +8,7 @@ import type { PricePoint } from "../../../types/financials";
|
|
|
8
8
|
import { realizedVolatility, realizedVolatilityCadenceIssue } from "../shared/volatility";
|
|
9
9
|
|
|
10
10
|
export type IvMethod = "quote-mid" | "trade-close";
|
|
11
|
-
type IvCoverageStatus = "ready" | "backfilling" | "queued" | "unavailable";
|
|
11
|
+
export type IvCoverageStatus = "ready" | "backfilling" | "queued" | "unavailable";
|
|
12
12
|
export interface IvPoint {
|
|
13
13
|
sessionDate: string;
|
|
14
14
|
method: IvMethod;
|
|
@@ -67,7 +67,14 @@ export interface IvHistoryPayload {
|
|
|
67
67
|
}
|
|
68
68
|
export interface IvScreenRow {
|
|
69
69
|
symbol: string;
|
|
70
|
+
/** Has readings, or none yet. All an older server says; `coverageStatus` is exact. */
|
|
70
71
|
status: "ready" | "queued";
|
|
72
|
+
/** Where the symbol's history stands, as in `IvHistoryPayload.status`. Absent from older servers. */
|
|
73
|
+
coverageStatus?: IvCoverageStatus;
|
|
74
|
+
/** When the symbol was queued and how far its backfill has got; null when it is not covered. */
|
|
75
|
+
coverage?: { source: "seed" | "demand"; addedAt: string; backfilledThrough: string | null } | null;
|
|
76
|
+
/** Why it is not covered yet, such as demand coverage being full. */
|
|
77
|
+
warnings?: string[];
|
|
71
78
|
iv30: IvStats | null;
|
|
72
79
|
iv90: IvStats | null;
|
|
73
80
|
iv365?: IvStats | null;
|
|
@@ -88,14 +95,17 @@ export interface StoredSurfacePayload {
|
|
|
88
95
|
export type ImpliedVolatilityApi = Pick<typeof apiClient, "impliedVolatility">;
|
|
89
96
|
const query = (params: Record<string, string>) => new URLSearchParams(params).toString();
|
|
90
97
|
/** Stored IV is keyed by the bare US symbol; a listing key ("SPY:ARCX") drops its exchange. */
|
|
91
|
-
|
|
98
|
+
/** A US listing's symbol; a listing abroad is refused, since its bare symbol's options are another company's. */
|
|
99
|
+
export const ivSymbol = (symbol: string) => usListingSymbol(symbol, "Implied volatility");
|
|
92
100
|
|
|
93
101
|
export function loadIvHistory(symbol: string, options: { signal?: AbortSignal; days?: number } = {}, api: ImpliedVolatilityApi = apiClient) {
|
|
94
102
|
return api.impliedVolatility<IvHistoryPayload>(`history?${query({ symbol: ivSymbol(symbol), days: String(options.days ?? 1100) })}`,
|
|
95
103
|
{ signal: options.signal });
|
|
96
104
|
}
|
|
105
|
+
/** A listing abroad has no row: its bare symbol's options are another company's. */
|
|
97
106
|
export function loadIvScreen(symbols: readonly string[], options: { signal?: AbortSignal } = {}, api: ImpliedVolatilityApi = apiClient) {
|
|
98
|
-
|
|
107
|
+
const us = symbols.filter((symbol) => listingAbroadVenue(symbol) == null).map(ivSymbol);
|
|
108
|
+
return api.impliedVolatility<IvScreenPayload>(`screen?${query({ symbols: us.join(",") })}`, { signal: options.signal });
|
|
99
109
|
}
|
|
100
110
|
export function loadSurfaceDates(symbol: string, options: { signal?: AbortSignal } = {}, api: ImpliedVolatilityApi = apiClient) {
|
|
101
111
|
return api.impliedVolatility<{ version: 1; symbol: string; dates: string[] }>(`surface-dates?${query({ symbol: ivSymbol(symbol) })}`,
|
|
@@ -3,7 +3,7 @@ import { resolveHeadlessInstrument } from "../shared/headless-market-data";
|
|
|
3
3
|
import { createRealizedVolatilityDependencies, loadRealizedVolatilityHistory } from "../realized-vol/client";
|
|
4
4
|
import { createHvDependencies, loadIvHistory, loadIvScreen, loadRealizedVolatilities } from "./client";
|
|
5
5
|
import { formatPoints, formatRank, formatStat, formatVol, readingLabel, sharedDates, VCA_DEFINITIONS, verdictLabel } from "./format";
|
|
6
|
-
import { HV_WINDOWS, type HvWindow, type IvLookback, type IvStatRow, projectIvHistory, projectRichCheap, type RichCheapRow, richCheapDates, VCA_LIMIT, VCA_PRESETS } from "./model";
|
|
6
|
+
import { HV_WINDOWS, type HvWindow, type IvLookback, type IvStatRow, projectIvHistory, projectRichCheap, type RichCheapRow, richCheapDates, screenCoverage, VCA_LIMIT, VCA_PRESETS } from "./model";
|
|
7
7
|
import { vcaUniverse } from "./universe";
|
|
8
8
|
|
|
9
9
|
const METHODOLOGY = "docs/research-data.md#implied-volatility-history";
|
|
@@ -11,6 +11,7 @@ const percent = (value: unknown) => typeof value === "number" ? formatVol(value)
|
|
|
11
11
|
|
|
12
12
|
export const ivHistoryHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
13
13
|
shape: "bundle", argument: { kind: "ticker", description: "US option underlying" },
|
|
14
|
+
usListingsOnly: "Implied volatility history",
|
|
14
15
|
freshness: { status: "not-a-feed", basis: "daily implied volatility", cadence: "daily", observedKey: "date", oldest: null },
|
|
15
16
|
describe: (args) => `HIVG ${args.symbols[0] ?? ""}`,
|
|
16
17
|
discovery: { aliases: ["HIVG"], screenshotReadiness: "live-dom", dataRequirements: ["Cloud stored implied volatility", "Daily price history"],
|
|
@@ -65,6 +66,7 @@ export const ivScreenHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
65
66
|
// Dated by the readings themselves; the response's own date is the day it was fetched.
|
|
66
67
|
freshness: { status: "not-a-feed", basis: "daily implied volatility", cadence: "daily", observedKey: "date" },
|
|
67
68
|
argument: { kind: "symbol-list", optional: true, maximum: VCA_LIMIT, description: "US option underlyings; defaults to index and sector ETFs." },
|
|
69
|
+
usListingsOnly: "Implied volatility",
|
|
68
70
|
options: [{ key: "preset", type: "enum", values: [{ value: "etfs" }, { value: "megacaps" }], defaultValue: "etfs", description: "Preset when no symbols are given" }],
|
|
69
71
|
describe: "Volatility rich/cheap",
|
|
70
72
|
discovery: { aliases: ["VCA"], screenshotReadiness: "live-dom", dataRequirements: ["Cloud stored implied volatility", "Daily price history"],
|
|
@@ -77,7 +79,7 @@ export const ivScreenHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
77
79
|
loadRealizedVolatilities(universe.instruments, 20, { signal: ctx.signal }, createHvDependencies(ctx.marketData)),
|
|
78
80
|
]);
|
|
79
81
|
const rows = projectRichCheap(payload.rows, hv).sort((a, b) => (b.percentile ?? -1) - (a.percentile ?? -1));
|
|
80
|
-
const
|
|
82
|
+
const coverage = screenCoverage(rows);
|
|
81
83
|
const dates = richCheapDates(rows);
|
|
82
84
|
const hasSkew = rows.some((row) => row.skew != null);
|
|
83
85
|
const hasIv1y = rows.some((row) => row.iv1y != null), hasIv1yRank = rows.some((row) => row.iv1yPercentile != null);
|
|
@@ -99,9 +101,10 @@ export const ivScreenHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
99
101
|
{ key: "hv", header: "HV20", format: percent },
|
|
100
102
|
{ key: "ivHv", header: "IV/HV", format: (value: unknown) => typeof value === "number" ? value.toFixed(2) : "--" },
|
|
101
103
|
], rows: rows.map((row) => ({ ...row })) }],
|
|
102
|
-
|
|
104
|
+
// A symbol with no options history is final; only history still to come leaves the screen incomplete.
|
|
105
|
+
complete: !coverage.pending.length && !universe.error, unavailableSymbols: coverage.missing,
|
|
103
106
|
errors: [universe.error].filter((value): value is string => !!value),
|
|
104
|
-
notes: [...
|
|
107
|
+
notes: [...coverage.notes, ...VCA_DEFINITIONS],
|
|
105
108
|
metadata: { presets: VCA_PRESETS, methodology: METHODOLOGY },
|
|
106
109
|
};
|
|
107
110
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PluginModule } from "../plugin-module";
|
|
2
|
+
import { IV_SERIES } from "./series";
|
|
2
3
|
import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface";
|
|
3
4
|
import { ivHistoryHeadless, ivScreenHeadless } from "./headless";
|
|
4
5
|
import { IvHistoryPane } from "./pane";
|
|
@@ -6,6 +7,7 @@ import { IvScreenPane, VCA_SCOPE_OPTIONS } from "./screen-pane";
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
export const ivHistoryModule: PluginModule = {
|
|
10
|
+
series: IV_SERIES,
|
|
9
11
|
panes: [{
|
|
10
12
|
id: "iv-history", name: "Implied Volatility History", icon: "V", component: IvHistoryPane,
|
|
11
13
|
defaultPosition: "right", tickerFollower: true, defaultMode: "floating", defaultFloatingSize: { width: 118, height: 36 },
|