gloomberb 0.16.1 → 0.16.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.
Files changed (574) hide show
  1. package/README.md +2 -1
  2. package/package.json +2 -1
  3. package/src/api-client/beneficial-owners.ts +92 -0
  4. package/src/api-client/data.ts +26 -8
  5. package/src/api-client/errors.ts +12 -0
  6. package/src/api-client/geo.ts +363 -0
  7. package/src/api-client/index.ts +2 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/paths.ts +30 -1
  10. package/src/api-client/perps.ts +37 -0
  11. package/src/api-client/request.ts +5 -2
  12. package/src/api-client/types.ts +2 -0
  13. package/src/brokers/account-cache.ts +24 -0
  14. package/src/cli/commands/command-utils.ts +8 -0
  15. package/src/cli/commands/crypto-hints.ts +75 -0
  16. package/src/cli/commands/market.ts +414 -106
  17. package/src/cli/commands/overview.ts +77 -32
  18. package/src/cli/commands/ticker.ts +101 -43
  19. package/src/cli/desktop-pane-shot.ts +34 -4
  20. package/src/cli/freshness.ts +61 -0
  21. package/src/cli/help.ts +1 -0
  22. package/src/cli/helpers.ts +4 -8
  23. package/src/cli/index.ts +12 -2
  24. package/src/cli/listing-arg.ts +321 -0
  25. package/src/cli/pane-functions/access-gate.ts +42 -0
  26. package/src/cli/pane-functions/catalog.ts +28 -1
  27. package/src/cli/pane-functions/data.ts +3 -1
  28. package/src/cli/pane-functions/dom.ts +20 -2
  29. package/src/cli/pane-functions/freshness.ts +400 -0
  30. package/src/cli/pane-functions/function-help.ts +27 -20
  31. package/src/cli/pane-functions/headless.ts +39 -11
  32. package/src/cli/pane-functions/index.ts +15 -4
  33. package/src/cli/pane-functions/options.ts +3 -0
  34. package/src/cli/pane-functions/report.ts +4 -0
  35. package/src/cli/pane-functions/resolver.ts +35 -7
  36. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  37. package/src/cli/pane-functions/screenshot.ts +7 -3
  38. package/src/cli/result.ts +41 -27
  39. package/src/cli/ticker-resolution.ts +7 -5
  40. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  41. package/src/components/chart/composite/drawing-store.ts +59 -0
  42. package/src/components/chart/composite/legend.tsx +319 -0
  43. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  44. package/src/components/chart/composite/panel-gestures.ts +59 -0
  45. package/src/components/chart/composite/panel-labels.ts +107 -0
  46. package/src/components/chart/composite/panel-surface.tsx +876 -0
  47. package/src/components/chart/composite/tool-catalog.ts +98 -0
  48. package/src/components/chart/composite/toolbar.tsx +186 -0
  49. package/src/components/chart/composite/tools.ts +8 -0
  50. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  51. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  52. package/src/components/command-bar/list/model.ts +5 -0
  53. package/src/components/command-bar/list/view.tsx +16 -3
  54. package/src/components/command-bar/pane-templates/workflow.ts +1 -0
  55. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  56. package/src/components/command-bar/workflow/ops.ts +1 -1
  57. package/src/components/command-bar/workflow/tickers.ts +6 -0
  58. package/src/components/data-table/view.tsx +29 -10
  59. package/src/components/feedback-dialog.tsx +2 -1
  60. package/src/components/form-modal/field-row.tsx +2 -2
  61. package/src/components/layout/detached-pane-shell.tsx +6 -3
  62. package/src/components/layout/pane/content.tsx +23 -10
  63. package/src/components/layout/pane/error-boundary.tsx +103 -0
  64. package/src/components/layout/pane/footer/registration.tsx +68 -23
  65. package/src/components/layout/pane/header.tsx +11 -11
  66. package/src/components/layout/shell/menu.ts +2 -1
  67. package/src/components/layout/shell/pane/actions.ts +2 -1
  68. package/src/components/layout/shell/pane/layers.tsx +14 -3
  69. package/src/components/metric-treemap/heat-surface.tsx +43 -16
  70. package/src/components/metric-treemap/heat-tiles.ts +18 -0
  71. package/src/components/metric-treemap/layout.ts +2 -0
  72. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  73. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  74. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  75. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  76. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  77. package/src/components/ticker/list-table-view.tsx +13 -1
  78. package/src/components/ui/fields.tsx +8 -0
  79. package/src/components/ui/range-track.tsx +10 -3
  80. package/src/components/ui/status.tsx +8 -2
  81. package/src/components/ui/tabs.tsx +7 -4
  82. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  83. package/src/data/config/store/normalize.ts +17 -1
  84. package/src/i18n/es.ts +19 -1
  85. package/src/i18n/ja.ts +19 -1
  86. package/src/i18n/ko.ts +19 -1
  87. package/src/i18n/zh-cn.ts +19 -1
  88. package/src/i18n/zh-tw.ts +19 -1
  89. package/src/market-data/coordinator/chart.ts +1 -1
  90. package/src/market-data/coordinator/quotes.ts +23 -4
  91. package/src/market-data/fx-closes.ts +72 -0
  92. package/src/market-data/market/freshness.ts +78 -6
  93. package/src/market-data/market/session-close-note.ts +57 -0
  94. package/src/market-data/market/status.ts +151 -0
  95. package/src/market-data/published-apac-sessions.ts +66 -0
  96. package/src/market-data/quotes/contributions.ts +2 -0
  97. package/src/market-data/quotes/resolution.ts +2 -0
  98. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  99. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  100. package/src/plugins/builtin/alerts/cli.ts +10 -5
  101. package/src/plugins/builtin/alerts/index.tsx +1 -0
  102. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  103. package/src/plugins/builtin/analytics/risk-client.ts +191 -66
  104. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  105. package/src/plugins/builtin/analytics/risk-headless.ts +19 -13
  106. package/src/plugins/builtin/analytics/risk-model.ts +45 -17
  107. package/src/plugins/builtin/analytics/risk-pane.tsx +1 -0
  108. package/src/plugins/builtin/analytics/risk-test-data.ts +25 -1
  109. package/src/plugins/builtin/attention/headless.ts +6 -4
  110. package/src/plugins/builtin/attention/index.tsx +1 -1
  111. package/src/plugins/builtin/attention/pane.tsx +1 -1
  112. package/src/plugins/builtin/awards/headless.ts +1 -0
  113. package/src/plugins/builtin/awards/pane.tsx +1 -1
  114. package/src/plugins/builtin/backtest/headless.ts +1 -0
  115. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  116. package/src/plugins/builtin/buildout/index.tsx +1 -0
  117. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  118. package/src/plugins/builtin/cds/headless.ts +2 -0
  119. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  120. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  121. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  122. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  123. package/src/plugins/builtin/chat/channels.ts +19 -3
  124. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  125. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  126. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  127. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  128. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  129. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  130. package/src/plugins/builtin/chat/index.tsx +1 -0
  131. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  132. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  133. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  134. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  135. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  136. package/src/plugins/builtin/chat/message/types.ts +14 -2
  137. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  138. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  139. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  140. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  141. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  142. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  143. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  144. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  145. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  146. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  147. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  148. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  149. package/src/plugins/builtin/correlation/compute.ts +59 -16
  150. package/src/plugins/builtin/correlation/geo.ts +34 -0
  151. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  152. package/src/plugins/builtin/correlation/headless.ts +42 -8
  153. package/src/plugins/builtin/correlation/history.ts +2 -0
  154. package/src/plugins/builtin/correlation/index.tsx +68 -14
  155. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  156. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  157. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  158. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  159. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  160. package/src/plugins/builtin/correlation/settings.ts +1 -1
  161. package/src/plugins/builtin/cot/headless.ts +6 -3
  162. package/src/plugins/builtin/cot/index.tsx +3 -3
  163. package/src/plugins/builtin/cot/model.ts +36 -3
  164. package/src/plugins/builtin/cpi/headless.ts +4 -0
  165. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  166. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  167. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  168. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  169. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  170. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  171. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  172. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  173. package/src/plugins/builtin/doe/headless.ts +7 -0
  174. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  175. package/src/plugins/builtin/earnings/headless.ts +5 -0
  176. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  177. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  178. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  179. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  180. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  181. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  182. package/src/plugins/builtin/econ/index.tsx +1 -0
  183. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  184. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  185. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  186. package/src/plugins/builtin/executives/index.tsx +1 -0
  187. package/src/plugins/builtin/exposure/headless.ts +3 -1
  188. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  189. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  190. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  191. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  192. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  193. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  194. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  195. package/src/plugins/builtin/gpu/headless.ts +7 -3
  196. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  197. package/src/plugins/builtin/gpu/model.ts +27 -1
  198. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  199. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  200. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  201. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  202. package/src/plugins/builtin/holders/headless.ts +139 -5
  203. package/src/plugins/builtin/holders/index.tsx +10 -3
  204. package/src/plugins/builtin/holders/pane.tsx +20 -3
  205. package/src/plugins/builtin/holders/report-header.ts +95 -0
  206. package/src/plugins/builtin/holders/table-model.ts +20 -5
  207. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  208. package/src/plugins/builtin/holders/types.ts +2 -1
  209. package/src/plugins/builtin/insider/headless.ts +2 -0
  210. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  211. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  212. package/src/plugins/builtin/jobs/headless.ts +1 -0
  213. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  214. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  215. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  216. package/src/plugins/builtin/market-heatmap/data.ts +2 -0
  217. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  218. package/src/plugins/builtin/market-heatmap/index.tsx +39 -46
  219. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  220. package/src/plugins/builtin/market-heatmap/portfolio.ts +23 -4
  221. package/src/plugins/builtin/market-movers/headless.ts +2 -0
  222. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  223. package/src/plugins/builtin/members/client.ts +20 -3
  224. package/src/plugins/builtin/members/headless.ts +5 -3
  225. package/src/plugins/builtin/members/model.ts +10 -2
  226. package/src/plugins/builtin/members/pane.tsx +13 -6
  227. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  228. package/src/plugins/builtin/mna/headless.ts +1 -0
  229. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  230. package/src/plugins/builtin/news/headless.ts +2 -0
  231. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  232. package/src/plugins/builtin/notes/cli.ts +14 -6
  233. package/src/plugins/builtin/notes/index.tsx +1 -0
  234. package/src/plugins/builtin/openfda/index.tsx +1 -0
  235. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  236. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  237. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  238. package/src/plugins/builtin/pe-band/client.ts +48 -3
  239. package/src/plugins/builtin/pe-band/headless.ts +25 -7
  240. package/src/plugins/builtin/pe-band/model.ts +92 -16
  241. package/src/plugins/builtin/pe-band/pane.tsx +33 -16
  242. package/src/plugins/builtin/perps/client.ts +50 -3
  243. package/src/plugins/builtin/perps/headless.ts +144 -16
  244. package/src/plugins/builtin/perps/index.tsx +6 -6
  245. package/src/plugins/builtin/perps/model.ts +189 -12
  246. package/src/plugins/builtin/perps/pane.tsx +248 -47
  247. package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
  248. package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
  249. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  250. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  251. package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
  252. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  253. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  254. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  255. package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
  256. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  257. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  258. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  259. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  260. package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
  261. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  262. package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
  263. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  264. package/src/plugins/builtin/power/headless.ts +3 -1
  265. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  266. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  267. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  268. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  269. package/src/plugins/builtin/research/events-headless.ts +2 -0
  270. package/src/plugins/builtin/research/headless.ts +2 -0
  271. package/src/plugins/builtin/research/index.tsx +1 -0
  272. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  273. package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
  274. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  275. package/src/plugins/builtin/research-search/index.tsx +1 -0
  276. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  277. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  278. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  279. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  280. package/src/plugins/builtin/scanner/headless.ts +14 -0
  281. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  282. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  283. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  284. package/src/plugins/builtin/sec/forms.ts +12 -0
  285. package/src/plugins/builtin/sec/headless.ts +2 -0
  286. package/src/plugins/builtin/sectors/client.ts +1 -0
  287. package/src/plugins/builtin/sectors/headless.ts +9 -1
  288. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  289. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  290. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  291. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  292. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  293. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  294. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  295. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  296. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  297. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  298. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  299. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  300. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  301. package/src/plugins/builtin/themes/headless.ts +3 -0
  302. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  303. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  304. package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
  305. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  306. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
  307. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
  308. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  309. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  310. package/src/plugins/builtin/volatility/headless.ts +6 -1
  311. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  312. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
  313. package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
  314. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  315. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  316. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  317. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  318. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  319. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  320. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  321. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
  322. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  323. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  324. package/src/plugins/builtin/world-venue-map/index.ts +67 -4
  325. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
  326. package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
  327. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  328. package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
  329. package/src/plugins/builtin/world-venue-map/model.ts +7 -4
  330. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
  331. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  332. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  333. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  334. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  335. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  336. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  337. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  338. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  339. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  340. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  341. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  342. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  343. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  344. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  345. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  346. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  347. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  348. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  349. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  350. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  351. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  352. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  353. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  354. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  355. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  356. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  357. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  358. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  359. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  360. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  361. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  362. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  363. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  364. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  365. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  366. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  367. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  368. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  369. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  370. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  371. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  372. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  373. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  374. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  375. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  376. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  377. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  378. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  379. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  380. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  381. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  382. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  383. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  384. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  385. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  386. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  387. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  388. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  389. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  390. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  391. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  392. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  393. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  394. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  395. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  396. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  397. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  398. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  399. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  400. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  401. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  402. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  403. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  404. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  405. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  406. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  407. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  408. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  409. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  410. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  411. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  412. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  413. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  414. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  415. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  416. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  417. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  418. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
  524. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  525. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  526. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  527. package/src/plugins/loader.ts +13 -1
  528. package/src/plugins/registry/pane-settings.ts +1 -0
  529. package/src/renderers/dom/build-assets.ts +81 -3
  530. package/src/renderers/dom/data-table/row.tsx +2 -0
  531. package/src/renderers/dom/desktop/controls.tsx +7 -3
  532. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  533. package/src/renderers/dom/desktop/popover.tsx +73 -14
  534. package/src/renderers/dom/host/input.tsx +14 -3
  535. package/src/renderers/dom/styles.css +6 -7
  536. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  537. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -0
  538. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  539. package/src/renderers/opentui/host.tsx +5 -0
  540. package/src/sources/gloomberb-cloud/index.ts +25 -4
  541. package/src/sources/gloomberb-cloud/normalizers.ts +27 -3
  542. package/src/sources/provider-router/cached-routes.ts +4 -1
  543. package/src/sources/provider-router/financials.ts +8 -7
  544. package/src/sources/provider-router/history.ts +15 -10
  545. package/src/sources/sec-registrant.ts +75 -0
  546. package/src/state/app/context/index.tsx +24 -8
  547. package/src/state/hooks/quote-streaming.ts +41 -26
  548. package/src/sync/core-contributors.ts +4 -0
  549. package/src/telemetry/crash-reports.ts +4 -1
  550. package/src/test-support/cli-context.ts +10 -2
  551. package/src/theme/heat-colors.ts +266 -84
  552. package/src/time-series/resolve.ts +1 -1
  553. package/src/time-series/use-chart-resolution.ts +1 -1
  554. package/src/types/context-menu.ts +6 -0
  555. package/src/types/data-provider.ts +2 -0
  556. package/src/types/financials.ts +3 -0
  557. package/src/types/headless.ts +79 -2
  558. package/src/types/plugin.ts +20 -1
  559. package/src/types/ticker.ts +15 -0
  560. package/src/ui/host.tsx +14 -0
  561. package/src/updater/index.ts +9 -11
  562. package/src/utils/async-deadline.ts +21 -0
  563. package/src/utils/cli-output.ts +5 -1
  564. package/src/utils/crypto-pair.ts +41 -0
  565. package/src/utils/currency-units.ts +14 -0
  566. package/src/utils/depositary-receipt.ts +26 -0
  567. package/src/utils/exchanges.ts +72 -0
  568. package/src/utils/fire-and-forget.ts +24 -0
  569. package/src/utils/format.ts +13 -0
  570. package/src/utils/price-earnings.ts +70 -3
  571. package/src/utils/price-history.ts +58 -13
  572. package/src/utils/rpc-timeout-error.ts +27 -0
  573. package/src/utils/sec.ts +13 -1
  574. package/src/utils/utc-time.ts +79 -0
@@ -2,23 +2,55 @@ import { saveConfig } from "../../../../data/config/store";
2
2
  import { withConfigData, withMarketData } from "../../../../cli/scoped-context";
3
3
  import { countCollectionTickers } from "../../../../cli/helpers";
4
4
  import { resolveTickerForCli } from "../../../../cli/ticker-resolution";
5
- import { cliStyles, renderStats } from "../../../../utils/cli-output";
5
+ import { takeOption } from "../../../../cli/commands/command-utils";
6
+ import { EXCHANGE_OPTION, loadSavedListing, parseListingArg, requireListingArg, savedListingName } from "../../../../cli/listing-arg";
7
+ import { cliStyles, renderStats, renderTable } from "../../../../utils/cli-output";
6
8
  import { CLI_COMMAND_GROUPS } from "../../../../cli/help";
7
9
  import { formatMarketCostWithCurrency, formatMarketQuantity } from "../../../../market-data/market/format";
10
+ import type { AppConfig } from "../../../../types/config";
8
11
  import type { CliCommandContext, CliCommandDef } from "../../../../types/plugin";
12
+ import type { Portfolio, TickerRecord } from "../../../../types/ticker";
13
+ import type { TickerRepository } from "../../../../data/ticker-repository";
14
+ import { canonicalExchange, parsePublicTickerKey } from "../../../../utils/exchanges";
9
15
  import {
10
16
  addTickerToPortfolio,
11
17
  adoptFirstPositionCurrency,
18
+ clearPortfolioCash,
19
+ clearPortfolioTargetWeights,
12
20
  createManualPortfolio,
13
21
  deleteManualPortfolio,
14
22
  hasOpenPortfolioPositions,
23
+ isManualPortfolio,
15
24
  removeTickerFromPortfolio,
16
25
  resolveManualPositionCurrency,
17
26
  setManualPortfolioPosition,
27
+ setPortfolioCash,
28
+ setPortfolioTargetWeight,
18
29
  } from "../mutations";
19
30
  import { renderCollectionOverview, showCollection } from "./render";
20
31
  import { resolvePortfolioTotalsCurrency } from "../summary/totals";
21
- import { parseFiniteNumber, requireManualPortfolio } from "./shared";
32
+ import {
33
+ CASH_SYMBOL,
34
+ describeTargetSum,
35
+ formatAllocationMoney,
36
+ formatAllocationWeight,
37
+ parseTargetWeight,
38
+ } from "../allocation";
39
+ import { findCachedPortfolioAccount } from "../cached-account";
40
+ import {
41
+ describeTicker,
42
+ failPortfolioCommand,
43
+ isCashArgument,
44
+ listingFields,
45
+ parseFiniteNumber,
46
+ PortfolioCliError,
47
+ rejectCashSymbol,
48
+ requireManualPortfolio,
49
+ requirePortfolio,
50
+ } from "./shared";
51
+
52
+ const CASH_USAGE = "Usage: gloomberb portfolio cash set <portfolio> <amount> [currency] | portfolio cash clear <portfolio>";
53
+ const TARGET_USAGE = "Usage: gloomberb portfolio target set <portfolio> <symbol|CASH> <weight%> | target clear <portfolio> [symbol] | target show <portfolio>";
22
54
 
23
55
  async function listCollections(ctx: CliCommandContext) {
24
56
  await withConfigData(ctx, async ({ config, store }) => {
@@ -56,7 +88,7 @@ async function createPortfolioCommand(name: string, ctx: CliCommandContext) {
56
88
  console.log(cliStyles.success(`Created portfolio "${result.portfolio.name}".`));
57
89
  console.log(renderStats([["ID", result.portfolio.id]]));
58
90
  } catch (error) {
59
- ctx.fail(error instanceof Error ? error.message : `Failed to create portfolio "${name}".`);
91
+ failPortfolioCommand(ctx, error, `Failed to create portfolio "${name}".`);
60
92
  }
61
93
  });
62
94
  }
@@ -76,47 +108,72 @@ async function deletePortfolioCommand(name: string, ctx: CliCommandContext) {
76
108
  ["Removed Positions", String(result.removedPositionCount)],
77
109
  ]));
78
110
  } catch (error) {
79
- ctx.fail(error instanceof Error ? error.message : `Failed to delete portfolio "${name}".`);
111
+ failPortfolioCommand(ctx, error, `Failed to delete portfolio "${name}".`);
80
112
  }
81
113
  });
82
114
  }
83
115
 
84
- async function addTickerToPortfolioCommand(portfolioName: string, symbol: string, ctx: CliCommandContext) {
116
+ async function addTickerToPortfolioCommand(portfolioName: string, symbol: string, exchange: string | undefined, ctx: CliCommandContext) {
85
117
  await withMarketData(ctx, async ({ config, store, dataProvider }) => {
86
118
  try {
87
119
  const portfolio = requireManualPortfolio(config, portfolioName);
88
- const ticker = await resolveTickerForCli(symbol, store, dataProvider);
120
+ rejectCashSymbol(symbol, exchange, portfolio.name);
121
+ const ticker = await resolveTickerForCli(symbol, store, dataProvider, exchange);
89
122
  const result = addTickerToPortfolio(ticker, portfolio.id);
123
+ // Name the listing that was stored: SAN:EPA is not the SAN that a bare SAN means.
124
+ const saved = savedListingName(ticker);
125
+ const data = { changed: result.changed, ...listingFields(saved), portfolio: portfolio.name };
90
126
  if (!result.changed) {
91
- console.log(cliStyles.warning(`${ticker.metadata.ticker} is already in "${portfolio.name}".`));
127
+ ctx.printResult({ data }, { text: () => cliStyles.warning(`${saved.label} is already in "${portfolio.name}".`) });
92
128
  return;
93
129
  }
94
130
  await store.saveTicker(result.ticker);
95
- console.log(cliStyles.success(`Added ${result.ticker.metadata.ticker} to "${portfolio.name}".`));
96
- if (result.ticker.metadata.name) {
97
- console.log(renderStats([["Name", result.ticker.metadata.name]]));
98
- }
131
+ ctx.printResult({ data }, { text: () => cliStyles.success(`Added ${saved.label} to "${portfolio.name}".`) });
99
132
  } catch (error) {
100
- ctx.fail(error instanceof Error ? error.message : `Failed to add ${symbol} to "${portfolioName}".`);
133
+ failPortfolioCommand(ctx, error, `Failed to add ${symbol} to "${portfolioName}".`);
101
134
  }
102
135
  });
103
136
  }
104
137
 
105
- async function removeTickerFromPortfolioCommand(portfolioName: string, symbol: string, ctx: CliCommandContext) {
106
- await withConfigData(ctx, async ({ config, store }) => {
107
- const normalized = symbol.trim().toUpperCase();
138
+ /** A target or a removal drops the symbol's target with it, so none outlives its holding. */
139
+ function withoutTarget(config: AppConfig, portfolio: Portfolio, symbol: string): AppConfig | null {
140
+ const { config: next, removed } = clearPortfolioTargetWeights(config, portfolio.id, symbol);
141
+ return removed.length > 0 ? next : null;
142
+ }
108
143
 
144
+ async function removeTickerFromPortfolioCommand(portfolioName: string, symbol: string, exchange: string | undefined, ctx: CliCommandContext) {
145
+ // SAN:EPA and SAN --exchange EPA name the stored listing, which a bare SAN may hold under another venue.
146
+ const listing = await requireListingArg(symbol, exchange, ctx);
147
+ await withConfigData(ctx, async ({ config, store }) => {
109
148
  try {
110
149
  const portfolio = requireManualPortfolio(config, portfolioName);
111
- const ticker = await store.loadTicker(normalized);
112
- if (!ticker) ctx.fail(`Ticker "${normalized}" was not found in your local data.`);
150
+ const ticker = await loadSavedListing(store, listing);
151
+ if (!ticker) ctx.fail(`Ticker "${listing.key}" was not found in your local data.`);
152
+ const saved = savedListingName(ticker);
113
153
  const result = removeTickerFromPortfolio(ticker, portfolio.id);
114
- if (!result.changed) ctx.fail(`${normalized} is not in "${portfolio.name}".`);
154
+ if (!result.changed) ctx.fail(`${saved.key} is not in "${portfolio.name}".`);
115
155
  await store.saveTicker(result.ticker);
116
- console.log(cliStyles.success(`Removed ${normalized} from "${portfolio.name}".`));
117
- console.log(renderStats([["Removed Positions", String(result.removedPositionCount)]]));
156
+ const nextConfig = withoutTarget(config, portfolio, ticker.metadata.ticker);
157
+ if (nextConfig) await saveConfig(nextConfig);
158
+ ctx.printResult({
159
+ data: {
160
+ changed: true,
161
+ ...listingFields(saved),
162
+ portfolio: portfolio.name,
163
+ removedPositions: result.removedPositionCount,
164
+ removedTarget: nextConfig != null,
165
+ },
166
+ }, {
167
+ text: () => [
168
+ cliStyles.success(`Removed ${saved.label} from "${portfolio.name}".`),
169
+ renderStats([
170
+ ["Removed Positions", String(result.removedPositionCount)],
171
+ ...(nextConfig ? [["Removed Target", "yes"] as [string, string]] : []),
172
+ ]),
173
+ ].join("\n"),
174
+ });
118
175
  } catch (error) {
119
- ctx.fail(error instanceof Error ? error.message : `Failed to remove ${symbol} from "${portfolioName}".`);
176
+ failPortfolioCommand(ctx, error, `Failed to remove ${symbol} from "${portfolioName}".`);
120
177
  }
121
178
  });
122
179
  }
@@ -127,14 +184,16 @@ async function setPositionCommand(
127
184
  sharesValue: string,
128
185
  avgCostValue: string,
129
186
  rawCurrency: string | undefined,
187
+ exchange: string | undefined,
130
188
  ctx: CliCommandContext,
131
189
  ) {
132
190
  await withMarketData(ctx, async ({ config, store, dataProvider }) => {
133
191
  try {
134
192
  const portfolio = requireManualPortfolio(config, portfolioName);
193
+ rejectCashSymbol(symbol, exchange, portfolio.name);
135
194
  const shares = parseFiniteNumber(sharesValue, "Shares");
136
195
  const avgCost = parseFiniteNumber(avgCostValue, "Average cost");
137
- const ticker = await resolveTickerForCli(symbol, store, dataProvider);
196
+ const ticker = await resolveTickerForCli(symbol, store, dataProvider, exchange);
138
197
  const currency = resolveManualPositionCurrency(rawCurrency, ticker, portfolio, config.baseCurrency);
139
198
  const result = setManualPortfolioPosition(ticker, portfolio.id, {
140
199
  shares,
@@ -145,21 +204,219 @@ async function setPositionCommand(
145
204
  await store.saveTicker(result.ticker);
146
205
  const adopted = firstPosition ? adoptFirstPositionCurrency(config, portfolio.id, currency) : null;
147
206
  if (adopted) await saveConfig(adopted);
148
- console.log(cliStyles.success(`Set position for ${result.ticker.metadata.ticker} in "${portfolio.name}".`));
207
+ console.log(cliStyles.success(`Set position for ${describeTicker(result.ticker)} in "${portfolio.name}".`));
149
208
  console.log(renderStats([
150
209
  ["Shares", formatMarketQuantity(shares, { assetCategory: result.ticker.metadata.assetCategory })],
151
210
  ["Average Cost", formatMarketCostWithCurrency(avgCost, currency, { assetCategory: result.ticker.metadata.assetCategory })],
152
211
  ["Currency", currency],
153
212
  ]));
154
213
  } catch (error) {
155
- ctx.fail(error instanceof Error ? error.message : `Failed to set position for ${symbol} in "${portfolioName}".`);
214
+ failPortfolioCommand(ctx, error, `Failed to set position for ${symbol} in "${portfolioName}".`);
215
+ }
216
+ });
217
+ }
218
+
219
+ const CURRENCY_CODE = /^[A-Za-z]{3}$/;
220
+
221
+ /** `<portfolio...> <amount> [currency]`: a portfolio name may have spaces, the amount and currency do not. */
222
+ function parseCashArgs(rest: string[]): { name: string; amount: string; currency?: string } | null {
223
+ const last = rest.at(-1);
224
+ const beforeLast = rest.at(-2);
225
+ if (rest.length >= 3 && last && CURRENCY_CODE.test(last) && beforeLast && Number.isFinite(parseCashAmount(beforeLast))) {
226
+ return { name: rest.slice(0, -2).join(" "), amount: beforeLast, currency: last.toUpperCase() };
227
+ }
228
+ if (rest.length >= 2 && last) return { name: rest.slice(0, -1).join(" "), amount: last };
229
+ return null;
230
+ }
231
+
232
+ /** 500000, 500,000 and 500_000 are the same amount. */
233
+ function parseCashAmount(raw: string): number {
234
+ const text = raw.trim().replace(/[,_]/g, "");
235
+ return text ? Number(text) : Number.NaN;
236
+ }
237
+
238
+ async function setCashCommand(rest: string[], ctx: CliCommandContext) {
239
+ const parsed = parseCashArgs(rest);
240
+ if (!parsed?.name) ctx.fail(CASH_USAGE);
241
+ await withConfigData(ctx, async ({ config, persistence }) => {
242
+ try {
243
+ const portfolio = requirePortfolio(config, parsed.name);
244
+ const amount = parseCashAmount(parsed.amount);
245
+ if (!Number.isFinite(amount)) throw new Error("Cash amount must be a valid number.");
246
+ const currency = parsed.currency ?? resolvePortfolioTotalsCurrency(portfolio, config.baseCurrency);
247
+ await saveConfig(setPortfolioCash(config, portfolio.id, { amount, currency }));
248
+ console.log(cliStyles.success(`Set cash in "${portfolio.name}" to ${formatAllocationMoney(amount, currency)}.`));
249
+ const account = findCachedPortfolioAccount(config, portfolio, persistence.resources);
250
+ if (account && Number.isFinite(account.totalCashValue)) {
251
+ console.log(cliStyles.warning(
252
+ `The broker account reports its own cash, ${formatAllocationMoney(account.totalCashValue, account.currency || currency)}; reports show that balance instead.`,
253
+ ));
254
+ }
255
+ } catch (error) {
256
+ failPortfolioCommand(ctx, error, `Failed to set cash in "${parsed.name}".`);
257
+ }
258
+ });
259
+ }
260
+
261
+ async function clearCashCommand(name: string, ctx: CliCommandContext) {
262
+ await withConfigData(ctx, async ({ config }) => {
263
+ try {
264
+ const portfolio = requirePortfolio(config, name);
265
+ const result = clearPortfolioCash(config, portfolio.id);
266
+ if (!result.changed) {
267
+ console.log(cliStyles.warning(`"${portfolio.name}" has no cash recorded.`));
268
+ return;
269
+ }
270
+ await saveConfig(result.config);
271
+ console.log(cliStyles.success(`Cleared the cash in "${portfolio.name}".`));
272
+ } catch (error) {
273
+ failPortfolioCommand(ctx, error, `Failed to clear the cash in "${name}".`);
274
+ }
275
+ });
276
+ }
277
+
278
+ function printTargetSumNote(config: AppConfig, portfolioId: string, tickers: readonly TickerRecord[]) {
279
+ const portfolio = config.portfolios.find((entry) => entry.id === portfolioId);
280
+ const listed = new Set([CASH_SYMBOL, ...tickers.filter((ticker) => ticker.metadata.portfolios.includes(portfolioId)).map((ticker) => ticker.metadata.ticker)]);
281
+ let sum: number | null = null;
282
+ for (const [symbol, weight] of Object.entries(portfolio?.targetWeights ?? {})) {
283
+ if (listed.has(symbol)) sum = (sum ?? 0) + weight;
284
+ }
285
+ const note = describeTargetSum(sum);
286
+ if (note) console.log(cliStyles.muted(note));
287
+ }
288
+
289
+ /** The portfolio's own ticker for a symbol, without a search when it is already listed. */
290
+ async function findListedTicker(store: TickerRepository, portfolio: Portfolio, symbol: string, exchange?: string): Promise<TickerRecord | null> {
291
+ const listing = parseListingArg(symbol, exchange);
292
+ const typed = symbol.trim().toUpperCase();
293
+ const listed = (await store.loadAllTickers()).filter((ticker) => ticker.metadata.portfolios.includes(portfolio.id));
294
+ // The key as saved (VTI:XMEX), else the same listing under another spelling of its venue (VTI:BMV).
295
+ return listed.find((ticker) => [typed, listing.key].includes(ticker.metadata.ticker.toUpperCase()))
296
+ ?? listed.find((ticker) => {
297
+ const saved = parsePublicTickerKey(ticker.metadata.ticker);
298
+ return saved.symbol === listing.symbol
299
+ && (!listing.exchange || canonicalExchange(saved.exchange ?? ticker.metadata.exchange) === listing.exchange);
300
+ })
301
+ ?? null;
302
+ }
303
+
304
+ async function setTargetCommand(rest: string[], exchange: string | undefined, ctx: CliCommandContext) {
305
+ const rawWeight = rest.at(-1);
306
+ const symbol = rest.at(-2);
307
+ const name = rest.slice(0, -2).join(" ");
308
+ if (!name || !symbol || !rawWeight) ctx.fail(TARGET_USAGE);
309
+ await withMarketData(ctx, async ({ config, store, dataProvider }) => {
310
+ try {
311
+ const portfolio = requirePortfolio(config, name);
312
+ const weight = parseTargetWeight(rawWeight);
313
+ if (isCashArgument(symbol, exchange)) {
314
+ const next = setPortfolioTargetWeight(config, portfolio.id, CASH_SYMBOL, weight);
315
+ await saveConfig(next);
316
+ console.log(cliStyles.success(`Set the cash target in "${portfolio.name}" to ${formatAllocationWeight(weight)}.`));
317
+ printTargetSumNote(next, portfolio.id, await store.loadAllTickers());
318
+ return;
319
+ }
320
+ let ticker = await findListedTicker(store, portfolio, symbol, exchange);
321
+ let added = false;
322
+ if (!ticker) {
323
+ const resolved = await resolveTickerForCli(symbol, store, dataProvider, exchange);
324
+ if (!resolved.metadata.portfolios.includes(portfolio.id)) {
325
+ if (!isManualPortfolio(portfolio)) {
326
+ throw new PortfolioCliError(
327
+ `${describeTicker(resolved)} is not in "${portfolio.name}".`,
328
+ "A broker portfolio lists what the broker holds; set targets on its holdings.",
329
+ );
330
+ }
331
+ const membership = addTickerToPortfolio(resolved, portfolio.id);
332
+ await store.saveTicker(membership.ticker);
333
+ added = true;
334
+ ticker = membership.ticker;
335
+ } else {
336
+ ticker = resolved;
337
+ }
338
+ }
339
+ const next = setPortfolioTargetWeight(config, portfolio.id, ticker.metadata.ticker, weight);
340
+ await saveConfig(next);
341
+ if (added) console.log(cliStyles.success(`Added ${describeTicker(ticker)} to "${portfolio.name}".`));
342
+ console.log(cliStyles.success(`Set the target for ${describeTicker(ticker)} in "${portfolio.name}" to ${formatAllocationWeight(weight)}.`));
343
+ printTargetSumNote(next, portfolio.id, await store.loadAllTickers());
344
+ } catch (error) {
345
+ failPortfolioCommand(ctx, error, `Failed to set the target for ${symbol} in "${name}".`);
346
+ }
347
+ });
348
+ }
349
+
350
+ async function clearTargetCommand(rest: string[], exchange: string | undefined, ctx: CliCommandContext) {
351
+ if (rest.length === 0) ctx.fail(TARGET_USAGE);
352
+ await withConfigData(ctx, async ({ config, store }) => {
353
+ try {
354
+ // The whole argument naming a portfolio clears every target; otherwise the last word is the symbol.
355
+ const whole = config.portfolios.some((entry) => [entry.id, entry.name].some((value) => value.toLowerCase() === rest.join(" ").trim().toLowerCase()));
356
+ const portfolio = requirePortfolio(config, whole ? rest.join(" ") : rest.slice(0, -1).join(" "));
357
+ const rawSymbol = whole ? undefined : rest.at(-1);
358
+ const symbol = rawSymbol == null ? undefined
359
+ : isCashArgument(rawSymbol, exchange) ? CASH_SYMBOL
360
+ : (await findListedTicker(store, portfolio, rawSymbol, exchange))?.metadata.ticker ?? parseListingArg(rawSymbol, exchange).key;
361
+ const { config: next, removed } = clearPortfolioTargetWeights(config, portfolio.id, symbol);
362
+ if (removed.length === 0) {
363
+ console.log(cliStyles.warning(symbol ? `"${portfolio.name}" has no target for ${symbol}.` : `"${portfolio.name}" has no targets.`));
364
+ return;
365
+ }
366
+ await saveConfig(next);
367
+ if (symbol) {
368
+ const ticker = symbol === CASH_SYMBOL ? null : await store.loadTicker(symbol);
369
+ console.log(cliStyles.success(`Cleared the ${symbol === CASH_SYMBOL ? "cash target" : `target for ${ticker ? describeTicker(ticker) : symbol}`} in "${portfolio.name}".`));
370
+ } else {
371
+ console.log(cliStyles.success(`Cleared ${removed.length} target${removed.length === 1 ? "" : "s"} in "${portfolio.name}".`));
372
+ }
373
+ } catch (error) {
374
+ failPortfolioCommand(ctx, error, `Failed to clear targets in "${rest.join(" ")}".`);
375
+ }
376
+ });
377
+ }
378
+
379
+ async function showTargetsCommand(name: string, ctx: CliCommandContext) {
380
+ await withConfigData(ctx, async ({ config, store }) => {
381
+ try {
382
+ const portfolio = requirePortfolio(config, name);
383
+ const tickers = await store.loadAllTickers();
384
+ const bySymbol = new Map(tickers.map((ticker) => [ticker.metadata.ticker, ticker]));
385
+ const rows = Object.entries(portfolio.targetWeights ?? {})
386
+ .sort(([left], [right]) => (left === CASH_SYMBOL ? 1 : right === CASH_SYMBOL ? -1 : left.localeCompare(right)))
387
+ .map(([symbol, targetWeight]) => {
388
+ const ticker = bySymbol.get(symbol);
389
+ return {
390
+ symbol,
391
+ name: symbol === CASH_SYMBOL ? "Cash" : ticker?.metadata.name ?? null,
392
+ targetWeight,
393
+ listed: symbol === CASH_SYMBOL || !!ticker?.metadata.portfolios.includes(portfolio.id),
394
+ };
395
+ });
396
+ if (ctx.cliOptions.format !== "text") {
397
+ ctx.printResult({ data: rows, metadata: { portfolioId: portfolio.id, portfolioName: portfolio.name } });
398
+ return;
399
+ }
400
+ console.log(cliStyles.bold(`${portfolio.name} targets`));
401
+ if (rows.length === 0) {
402
+ console.log(cliStyles.muted(`No targets. Set one with: gloomberb portfolio target set "${portfolio.name}" <symbol|CASH> <weight%>`));
403
+ return;
404
+ }
405
+ console.log("");
406
+ console.log(renderTable(
407
+ [{ header: "Ticker" }, { header: "Name" }, { header: "Target", align: "right" }],
408
+ rows.map((row) => [row.symbol, row.listed ? row.name ?? "" : cliStyles.muted("not in this portfolio"), formatAllocationWeight(row.targetWeight)]),
409
+ ));
410
+ printTargetSumNote(config, portfolio.id, tickers);
411
+ } catch (error) {
412
+ failPortfolioCommand(ctx, error, `Failed to show targets for "${name}".`);
156
413
  }
157
414
  });
158
415
  }
159
416
 
160
417
  export const portfolioCliCommand: CliCommandDef = {
161
418
  name: "portfolio",
162
- description: "Show holdings and P&L, and manage manual portfolios",
419
+ description: "Show holdings, value, weights and P&L; manage manual portfolios, cash and targets",
163
420
  help: {
164
421
  group: CLI_COMMAND_GROUPS.portfolios,
165
422
  usage: [
@@ -170,15 +427,27 @@ export const portfolioCliCommand: CliCommandDef = {
170
427
  "portfolio add <portfolio> <symbol>",
171
428
  "portfolio remove <portfolio> <symbol>",
172
429
  "portfolio position set <portfolio> <symbol> <shares> <avg-cost> [currency]",
430
+ "portfolio cash set <portfolio> <amount> [currency]",
431
+ "portfolio cash clear <portfolio>",
432
+ "portfolio target set <portfolio> <symbol|CASH> <weight%>",
433
+ "portfolio target clear <portfolio> [symbol|CASH]",
434
+ "portfolio target show <portfolio>",
173
435
  ],
436
+ options: [EXCHANGE_OPTION],
174
437
  examples: [
175
438
  "portfolio show Research",
176
439
  "portfolio add Research ASML",
440
+ "portfolio add Research ASML:AMS",
177
441
  "portfolio position set Research ASML 10 800 EUR",
442
+ "portfolio cash set Research 25000 USD",
443
+ "portfolio target set Research ASML 12.5%",
444
+ "portfolio target set Research CASH 10",
178
445
  "portfolio show Research --csv",
179
446
  ],
180
447
  },
181
- execute: async (args, ctx) => {
448
+ execute: async (rawArgs, ctx) => {
449
+ const args = [...rawArgs];
450
+ const exchange = takeOption(args, "--exchange");
182
451
  const action = args[0];
183
452
 
184
453
  if (!action || action === "list") {
@@ -211,7 +480,7 @@ export const portfolioCliCommand: CliCommandDef = {
211
480
  const symbol = args.at(-1);
212
481
  const name = args.slice(1, -1).join(" ");
213
482
  if (!name || !symbol) ctx.fail("Usage: gloomberb portfolio add <portfolio> <ticker>");
214
- await addTickerToPortfolioCommand(name!, symbol!, ctx);
483
+ await addTickerToPortfolioCommand(name!, symbol!, exchange, ctx);
215
484
  return;
216
485
  }
217
486
 
@@ -219,7 +488,7 @@ export const portfolioCliCommand: CliCommandDef = {
219
488
  const symbol = args.at(-1);
220
489
  const name = args.slice(1, -1).join(" ");
221
490
  if (!name || !symbol) ctx.fail("Usage: gloomberb portfolio remove <portfolio> <ticker>");
222
- await removeTickerFromPortfolioCommand(name!, symbol!, ctx);
491
+ await removeTickerFromPortfolioCommand(name!, symbol!, exchange, ctx);
223
492
  return;
224
493
  }
225
494
 
@@ -233,10 +502,40 @@ export const portfolioCliCommand: CliCommandDef = {
233
502
  if (rest.length < 4) {
234
503
  ctx.fail("Usage: gloomberb portfolio position set <portfolio> <ticker> <shares> <avg-cost> [currency]");
235
504
  }
236
- await setPositionCommand(rest[0]!, rest[1]!, rest[2]!, rest[3]!, currency, ctx);
505
+ await setPositionCommand(rest[0]!, rest[1]!, rest[2]!, rest[3]!, currency, exchange, ctx);
237
506
  return;
238
507
  }
239
508
 
509
+ if (action === "cash") {
510
+ const [, subaction, ...rest] = args;
511
+ if (subaction === "set") {
512
+ await setCashCommand(rest, ctx);
513
+ return;
514
+ }
515
+ if (subaction === "clear" && rest.length > 0) {
516
+ await clearCashCommand(rest.join(" "), ctx);
517
+ return;
518
+ }
519
+ ctx.fail(CASH_USAGE);
520
+ }
521
+
522
+ if (action === "target" || action === "targets") {
523
+ const [, subaction, ...rest] = args;
524
+ if (subaction === "set") {
525
+ await setTargetCommand(rest, exchange, ctx);
526
+ return;
527
+ }
528
+ if (subaction === "clear") {
529
+ await clearTargetCommand(rest, exchange, ctx);
530
+ return;
531
+ }
532
+ if ((subaction === "show" || subaction === "list") && rest.length > 0) {
533
+ await showTargetsCommand(rest.join(" "), ctx);
534
+ return;
535
+ }
536
+ ctx.fail(TARGET_USAGE);
537
+ }
538
+
240
539
  await showCollection(args.join(" "), ctx);
241
540
  },
242
541
  };