tradeblocks-mcp 3.0.2 → 3.0.3

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 (214) hide show
  1. package/README.md +82 -68
  2. package/dist/{chunk-LDKTV7GW.js → chunk-27S67XW3.js} +24 -52
  3. package/dist/chunk-27S67XW3.js.map +1 -0
  4. package/dist/{chunk-FGZH632F.js → chunk-2E63THNI.js} +13 -11
  5. package/dist/chunk-2E63THNI.js.map +1 -0
  6. package/dist/{chunk-BKQ4PM4Y.js → chunk-6S37CXUA.js} +11 -13
  7. package/dist/chunk-6S37CXUA.js.map +1 -0
  8. package/dist/{chunk-PRAYH3RT.js → chunk-AP7IHUUR.js} +29 -12
  9. package/dist/chunk-AP7IHUUR.js.map +1 -0
  10. package/dist/{chunk-QTTR7AAW.js → chunk-C6LL746C.js} +67 -84
  11. package/dist/{chunk-QTTR7AAW.js.map → chunk-C6LL746C.js.map} +1 -1
  12. package/dist/{chunk-W2PP3LEH.js → chunk-SEUZYQGQ.js} +17 -8
  13. package/dist/chunk-SEUZYQGQ.js.map +1 -0
  14. package/dist/{chunk-4BLCXNQ6.js → chunk-UBUC5A66.js} +105 -114
  15. package/dist/chunk-UBUC5A66.js.map +1 -0
  16. package/dist/{chunk-XXYOUIZY.js → chunk-VDU25Z6X.js} +63 -80
  17. package/dist/chunk-VDU25Z6X.js.map +1 -0
  18. package/dist/daily-log-processor-BY3ISY6K.js +9 -0
  19. package/dist/{daily-logs-store-D3QC2XPV.js → daily-logs-store-3C3OTGPK.js} +2 -2
  20. package/dist/iv-solver-worker.js +9 -1
  21. package/dist/market-provider-H3ARIVZ4.js +16 -0
  22. package/dist/{proto-3HZTCWK4.js → proto-V23GIZG2.js} +2 -2
  23. package/dist/{sync-PO4IPCYV.js → sync-EVLKB3ZJ.js} +7 -7
  24. package/dist/test-exports.js +358 -254
  25. package/dist/test-exports.js.map +1 -1
  26. package/dist/trade-processor-EYA3I3XB.js +9 -0
  27. package/dist/{trades-store-LOL3FQSF.js → trades-store-R3NL25T2.js} +2 -2
  28. package/manifest.json +3 -11
  29. package/package.json +1 -1
  30. package/server/{chunk-NZO6PT64.js → chunk-4P7D7YZP.js} +102 -113
  31. package/server/chunk-4P7D7YZP.js.map +1 -0
  32. package/server/{chunk-72GKJE2U.js → chunk-BOPHW5M6.js} +521 -235
  33. package/server/chunk-BOPHW5M6.js.map +1 -0
  34. package/server/{chunk-WA5AAPCH.js → chunk-GH2552SE.js} +17 -8
  35. package/server/chunk-GH2552SE.js.map +1 -0
  36. package/server/{chunk-5EBXHT6C.js → chunk-OBYKFW2B.js} +11 -13
  37. package/server/chunk-OBYKFW2B.js.map +1 -0
  38. package/server/{chunk-FBNDMCT5.js → chunk-T66KH2XH.js} +13 -11
  39. package/server/chunk-T66KH2XH.js.map +1 -0
  40. package/server/{chunk-NRFXAJF7.js → chunk-W5E7FHC4.js} +24 -52
  41. package/server/chunk-W5E7FHC4.js.map +1 -0
  42. package/server/{chunk-CSDVJPBB.js → chunk-YUCOAJ4Z.js} +29 -12
  43. package/server/chunk-YUCOAJ4Z.js.map +1 -0
  44. package/server/{chunk-PNKG7RY7.js → chunk-ZBJCF4ZG.js} +63 -80
  45. package/server/chunk-ZBJCF4ZG.js.map +1 -0
  46. package/server/{config-6IZXEFEX.js → config-DK7KOMNL.js} +1 -1
  47. package/server/config-DK7KOMNL.js.map +1 -0
  48. package/server/daily-log-processor-ENEUT22A.js +10 -0
  49. package/server/{daily-logs-store-NU7M4L5C.js → daily-logs-store-YFNXTB7J.js} +2 -2
  50. package/server/http-server.js +2 -5
  51. package/server/index.js +1771 -1538
  52. package/server/index.js.map +1 -1
  53. package/server/iv-solver-worker.js +9 -1
  54. package/server/market-provider-B437HKLW.js +17 -0
  55. package/server/{proto-DWRZJO4E.js → proto-YZ4TLX2N.js} +2 -2
  56. package/server/{sync-QFI5L7S7.js → sync-V25UQJA3.js} +7 -7
  57. package/server/trade-processor-L3PIQ5TG.js +10 -0
  58. package/server/{trades-store-VY26MWER.js → trades-store-RTTEYMXH.js} +2 -2
  59. package/src/auth/clients-store.ts +4 -4
  60. package/src/auth/code-store.ts +1 -1
  61. package/src/auth/config.ts +11 -12
  62. package/src/auth/login-page.ts +8 -10
  63. package/src/auth/provider.ts +35 -30
  64. package/src/auth/token.ts +17 -15
  65. package/src/db/backtest-schemas.ts +12 -4
  66. package/src/db/connection.ts +107 -40
  67. package/src/db/index.ts +37 -5
  68. package/src/db/json-adapters.ts +22 -31
  69. package/src/db/json-migration.ts +11 -15
  70. package/src/db/json-store.ts +5 -3
  71. package/src/db/market-datasets.ts +48 -15
  72. package/src/db/market-schemas.ts +11 -5
  73. package/src/db/market-views.ts +119 -32
  74. package/src/db/parquet-writer.ts +7 -7
  75. package/src/db/profile-schemas.ts +39 -22
  76. package/src/db/schemas.ts +2 -2
  77. package/src/http-server.ts +7 -12
  78. package/src/index.ts +8 -9
  79. package/src/market/ingestor/index.ts +1 -4
  80. package/src/market/ingestor/market-ingestor.ts +140 -67
  81. package/src/market/ingestor/types.ts +1 -3
  82. package/src/market/stores/chain-sql.ts +2 -8
  83. package/src/market/stores/chain-store.ts +1 -4
  84. package/src/market/stores/duckdb-chain-store.ts +3 -14
  85. package/src/market/stores/duckdb-enriched-store.ts +3 -13
  86. package/src/market/stores/duckdb-quote-store.ts +10 -27
  87. package/src/market/stores/duckdb-spot-store.ts +4 -20
  88. package/src/market/stores/enriched-sql.ts +3 -9
  89. package/src/market/stores/enriched-store.ts +2 -2
  90. package/src/market/stores/parquet-chain-store.ts +5 -22
  91. package/src/market/stores/parquet-enriched-store.ts +4 -16
  92. package/src/market/stores/parquet-oi-daily-store.ts +3 -14
  93. package/src/market/stores/parquet-quote-store.ts +9 -29
  94. package/src/market/stores/parquet-spot-store.ts +14 -33
  95. package/src/market/stores/quote-store.ts +2 -10
  96. package/src/market/stores/spot-sql.ts +3 -15
  97. package/src/market/stores/spot-store.ts +1 -1
  98. package/src/market/tickers/defaults.json +6 -6
  99. package/src/market/tickers/loader.ts +2 -7
  100. package/src/market/tickers/registry.ts +5 -15
  101. package/src/market/tickers/schemas.ts +2 -6
  102. package/src/models/strategy-profile.ts +39 -39
  103. package/src/sync/block-sync.ts +44 -65
  104. package/src/sync/index.ts +1 -4
  105. package/src/sync/metadata.ts +14 -20
  106. package/src/test-exports.ts +127 -123
  107. package/src/tools/analysis.ts +180 -159
  108. package/src/tools/batch-exit-analysis.ts +100 -59
  109. package/src/tools/blocks/analysis.ts +116 -101
  110. package/src/tools/blocks/comparison.ts +281 -364
  111. package/src/tools/blocks/core.ts +208 -253
  112. package/src/tools/blocks/health.ts +571 -563
  113. package/src/tools/blocks/similarity.ts +316 -283
  114. package/src/tools/edge-decay.ts +124 -197
  115. package/src/tools/exit-analysis.ts +130 -77
  116. package/src/tools/greeks-attribution.ts +84 -35
  117. package/src/tools/guides.ts +4 -6
  118. package/src/tools/imports.ts +9 -12
  119. package/src/tools/market-data.ts +1067 -757
  120. package/src/tools/market-enrichment.ts +3 -3
  121. package/src/tools/market-fetch.ts +148 -67
  122. package/src/tools/market-imports.ts +12 -12
  123. package/src/tools/middleware/sync-middleware.ts +5 -6
  124. package/src/tools/performance.ts +185 -302
  125. package/src/tools/profile-analysis.ts +52 -66
  126. package/src/tools/profiles.ts +106 -69
  127. package/src/tools/regime-advisor.ts +20 -45
  128. package/src/tools/replay.ts +81 -77
  129. package/src/tools/reports/discrepancies.ts +298 -328
  130. package/src/tools/reports/fields.ts +7 -25
  131. package/src/tools/reports/helpers.ts +18 -49
  132. package/src/tools/reports/predictive.ts +27 -70
  133. package/src/tools/reports/slippage-trends.ts +315 -345
  134. package/src/tools/reports/slippage.ts +1 -4
  135. package/src/tools/reports/strategy-matches.ts +399 -441
  136. package/src/tools/schema.ts +43 -40
  137. package/src/tools/shared/filters.ts +3 -9
  138. package/src/tools/snapshot.ts +9 -30
  139. package/src/tools/sql.ts +15 -14
  140. package/src/tools/tickers.ts +1 -4
  141. package/src/utils/batch-exit-analysis.ts +31 -42
  142. package/src/utils/black-scholes.ts +39 -29
  143. package/src/utils/block-loader.ts +68 -82
  144. package/src/utils/calibration-probe.ts +1 -2
  145. package/src/utils/chain-loader.ts +3 -3
  146. package/src/utils/csv-discovery.ts +16 -22
  147. package/src/utils/data-quality.ts +24 -36
  148. package/src/utils/exit-triggers.ts +91 -96
  149. package/src/utils/field-timing.ts +94 -79
  150. package/src/utils/filter-predicates.ts +13 -9
  151. package/src/utils/flatfile-importer.ts +94 -64
  152. package/src/utils/greeks-decomposition.ts +152 -100
  153. package/src/utils/iv-solver-pool.ts +55 -25
  154. package/src/utils/iv-solver-worker.ts +5 -5
  155. package/src/utils/market-enricher.ts +528 -497
  156. package/src/utils/market-importer.ts +31 -12
  157. package/src/utils/market-provider.ts +21 -23
  158. package/src/utils/massive-tier.ts +5 -7
  159. package/src/utils/migrate-option-data-helpers.ts +2 -8
  160. package/src/utils/option-quote-greeks.ts +25 -31
  161. package/src/utils/option-time.ts +4 -8
  162. package/src/utils/output-formatter.ts +1 -4
  163. package/src/utils/provider-capabilities.ts +1 -4
  164. package/src/utils/providers/massive.ts +59 -93
  165. package/src/utils/providers/thetadata/backfill.ts +14 -23
  166. package/src/utils/providers/thetadata/client.ts +12 -8
  167. package/src/utils/providers/thetadata/decode.ts +2 -20
  168. package/src/utils/providers/thetadata/endpoints.ts +32 -40
  169. package/src/utils/providers/thetadata/join.ts +11 -10
  170. package/src/utils/providers/thetadata/proto.ts +12 -10
  171. package/src/utils/providers/thetadata/quote-mid-greeks.ts +5 -5
  172. package/src/utils/providers/thetadata.ts +11 -10
  173. package/src/utils/quote-enricher.ts +4 -4
  174. package/src/utils/quote-parquet-projection.ts +3 -11
  175. package/src/utils/sample-date-selector.ts +3 -5
  176. package/src/utils/schema-metadata.ts +102 -70
  177. package/src/utils/ticker.ts +5 -9
  178. package/src/utils/trade-replay.ts +77 -68
  179. package/dist/chunk-4BLCXNQ6.js.map +0 -1
  180. package/dist/chunk-BKQ4PM4Y.js.map +0 -1
  181. package/dist/chunk-FGZH632F.js.map +0 -1
  182. package/dist/chunk-LDKTV7GW.js.map +0 -1
  183. package/dist/chunk-PRAYH3RT.js.map +0 -1
  184. package/dist/chunk-W2PP3LEH.js.map +0 -1
  185. package/dist/chunk-XXYOUIZY.js.map +0 -1
  186. package/dist/daily-log-processor-6MWJ23JK.js +0 -9
  187. package/dist/market-provider-VDRJUEF2.js +0 -16
  188. package/dist/trade-processor-NHU4VWRX.js +0 -9
  189. package/server/chunk-5EBXHT6C.js.map +0 -1
  190. package/server/chunk-72GKJE2U.js.map +0 -1
  191. package/server/chunk-CSDVJPBB.js.map +0 -1
  192. package/server/chunk-FBNDMCT5.js.map +0 -1
  193. package/server/chunk-NRFXAJF7.js.map +0 -1
  194. package/server/chunk-NZO6PT64.js.map +0 -1
  195. package/server/chunk-PNKG7RY7.js.map +0 -1
  196. package/server/chunk-WA5AAPCH.js.map +0 -1
  197. package/server/config-6IZXEFEX.js.map +0 -1
  198. package/server/daily-log-processor-Y3PVSVBM.js +0 -10
  199. package/server/market-provider-VOYYVYWT.js +0 -17
  200. package/server/trade-processor-JWVS37KM.js +0 -10
  201. /package/dist/{daily-log-processor-6MWJ23JK.js.map → daily-log-processor-BY3ISY6K.js.map} +0 -0
  202. /package/dist/{daily-logs-store-D3QC2XPV.js.map → daily-logs-store-3C3OTGPK.js.map} +0 -0
  203. /package/dist/{market-provider-VDRJUEF2.js.map → market-provider-H3ARIVZ4.js.map} +0 -0
  204. /package/dist/{proto-3HZTCWK4.js.map → proto-V23GIZG2.js.map} +0 -0
  205. /package/dist/{sync-PO4IPCYV.js.map → sync-EVLKB3ZJ.js.map} +0 -0
  206. /package/dist/{trade-processor-NHU4VWRX.js.map → trade-processor-EYA3I3XB.js.map} +0 -0
  207. /package/dist/{trades-store-LOL3FQSF.js.map → trades-store-R3NL25T2.js.map} +0 -0
  208. /package/server/{daily-log-processor-Y3PVSVBM.js.map → daily-log-processor-ENEUT22A.js.map} +0 -0
  209. /package/server/{daily-logs-store-NU7M4L5C.js.map → daily-logs-store-YFNXTB7J.js.map} +0 -0
  210. /package/server/{market-provider-VOYYVYWT.js.map → market-provider-B437HKLW.js.map} +0 -0
  211. /package/server/{proto-DWRZJO4E.js.map → proto-YZ4TLX2N.js.map} +0 -0
  212. /package/server/{sync-QFI5L7S7.js.map → sync-V25UQJA3.js.map} +0 -0
  213. /package/server/{trade-processor-JWVS37KM.js.map → trade-processor-L3PIQ5TG.js.map} +0 -0
  214. /package/server/{trades-store-VY26MWER.js.map → trades-store-RTTEYMXH.js.map} +0 -0
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getSofrRateByKey
4
- } from "./chunk-72GKJE2U.js";
4
+ } from "./chunk-BOPHW5M6.js";
5
5
  import {
6
6
  loadMddsProtoRoot
7
- } from "./chunk-FBNDMCT5.js";
7
+ } from "./chunk-T66KH2XH.js";
8
8
 
9
9
  // src/utils/providers/massive.ts
10
10
  import { z } from "zod";
@@ -226,7 +226,15 @@ function computeLegGreeks(optionPrice, underlyingPrice, strike, dte, type, riskF
226
226
  const bsType = type === "C" ? "call" : "put";
227
227
  const nullResult = { delta: null, gamma: null, theta: null, vega: null, iv: null };
228
228
  if (dte < BACHELIER_DTE_THRESHOLD) {
229
- const iv2 = solveNormalIV(bsType, optionPrice, underlyingPrice, strike, T, riskFreeRate, dividendYield);
229
+ const iv2 = solveNormalIV(
230
+ bsType,
231
+ optionPrice,
232
+ underlyingPrice,
233
+ strike,
234
+ T,
235
+ riskFreeRate,
236
+ dividendYield
237
+ );
230
238
  if (iv2 === null) return nullResult;
231
239
  return {
232
240
  delta: bachelierDelta(bsType, underlyingPrice, strike, T, riskFreeRate, dividendYield, iv2),
@@ -425,9 +433,7 @@ function etDateTimeToUtcIso(dateStr, timeStr) {
425
433
  function getApiKey() {
426
434
  const key = process.env.MASSIVE_API_KEY;
427
435
  if (!key) {
428
- throw new Error(
429
- "Set MASSIVE_API_KEY environment variable to use Massive.com data import"
430
- );
436
+ throw new Error("Set MASSIVE_API_KEY environment variable to use Massive.com data import");
431
437
  }
432
438
  return key;
433
439
  }
@@ -439,9 +445,7 @@ async function fetchWithRetry(url, headers, maxRetries = 2) {
439
445
  });
440
446
  if (response.status === 429) {
441
447
  if (attempt === maxRetries) {
442
- throw new Error(
443
- "Massive.com rate limit exceeded \u2014 try again in a few minutes"
444
- );
448
+ throw new Error("Massive.com rate limit exceeded \u2014 try again in a few minutes");
445
449
  }
446
450
  const retryAfter = response.headers.get("Retry-After");
447
451
  const backoffMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : Math.pow(2, attempt + 1) * 1e3;
@@ -452,17 +456,7 @@ async function fetchWithRetry(url, headers, maxRetries = 2) {
452
456
  }
453
457
  throw new Error("Massive.com rate limit exceeded after retries");
454
458
  }
455
- var INDEX_TICKERS = /* @__PURE__ */ new Set([
456
- "SPX",
457
- "NDX",
458
- "RUT",
459
- "DJX",
460
- "VIX",
461
- "VIX9D",
462
- "VIX3M",
463
- "OEX",
464
- "XSP"
465
- ]);
459
+ var INDEX_TICKERS = /* @__PURE__ */ new Set(["SPX", "NDX", "RUT", "DJX", "VIX", "VIX9D", "VIX3M", "OEX", "XSP"]);
466
460
  function detectSnapshotAssetClass(ticker) {
467
461
  return INDEX_TICKERS.has(ticker.toUpperCase()) ? "index" : "stock";
468
462
  }
@@ -574,14 +568,7 @@ var MassiveProvider = class {
574
568
  }
575
569
  async fetchBars(options) {
576
570
  const apiKey = getApiKey();
577
- const {
578
- ticker,
579
- from,
580
- to,
581
- timespan = "day",
582
- multiplier = 1,
583
- assetClass = "stock"
584
- } = options;
571
+ const { ticker, from, to, timespan = "day", multiplier = 1, assetClass = "stock" } = options;
585
572
  const apiTicker = toMassiveTicker(ticker, assetClass);
586
573
  const storageTicker = fromMassiveTicker(apiTicker);
587
574
  const headers = { Authorization: `Bearer ${apiKey}` };
@@ -598,14 +585,10 @@ var MassiveProvider = class {
598
585
  }
599
586
  const response = await fetchWithRetry(url, headers);
600
587
  if (response.status === 401) {
601
- throw new Error(
602
- "MASSIVE_API_KEY rejected by Massive.com \u2014 check your key"
603
- );
588
+ throw new Error("MASSIVE_API_KEY rejected by Massive.com \u2014 check your key");
604
589
  }
605
590
  if (!response.ok) {
606
- throw new Error(
607
- `Massive.com API error: HTTP ${response.status} ${response.statusText}`
608
- );
591
+ throw new Error(`Massive.com API error: HTTP ${response.status} ${response.statusText}`);
609
592
  }
610
593
  const json = await response.json();
611
594
  const parsed = MassiveAggregateResponseSchema.safeParse(json);
@@ -633,9 +616,7 @@ var MassiveProvider = class {
633
616
  const nextUrlObj = new URL(data.next_url);
634
617
  const cursor = nextUrlObj.searchParams.get("cursor") ?? data.next_url;
635
618
  if (seenCursors.has(cursor)) {
636
- throw new Error(
637
- `Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`
638
- );
619
+ throw new Error(`Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`);
639
620
  }
640
621
  seenCursors.add(cursor);
641
622
  url = data.next_url;
@@ -848,9 +829,7 @@ var MassiveProvider = class {
848
829
  try {
849
830
  mkdir(dirname(outputPath), { recursive: true });
850
831
  await conn.run(sql);
851
- const countResult = await conn.runAndReadAll(
852
- `SELECT count(*) AS cnt FROM '${outputPath}'`
853
- );
832
+ const countResult = await conn.runAndReadAll(`SELECT count(*) AS cnt FROM '${outputPath}'`);
854
833
  const rowCount = Number(countResult.getRows()[0][0]);
855
834
  return { rowCount, skipped: false };
856
835
  } finally {
@@ -901,14 +880,10 @@ var MassiveProvider = class {
901
880
  }
902
881
  const response = await fetchWithRetry(url, headers);
903
882
  if (response.status === 401) {
904
- throw new Error(
905
- "MASSIVE_API_KEY rejected by Massive.com \u2014 check your key"
906
- );
883
+ throw new Error("MASSIVE_API_KEY rejected by Massive.com \u2014 check your key");
907
884
  }
908
885
  if (!response.ok) {
909
- throw new Error(
910
- `Massive.com API error: HTTP ${response.status} ${response.statusText}`
911
- );
886
+ throw new Error(`Massive.com API error: HTTP ${response.status} ${response.statusText}`);
912
887
  }
913
888
  const json = await response.json();
914
889
  const parsed = MassiveSnapshotResponseSchema.safeParse(json);
@@ -919,9 +894,7 @@ var MassiveProvider = class {
919
894
  const data = parsed.data;
920
895
  if (data.results.length > 0 && underlyingPrice === 0) {
921
896
  underlyingPrice = data.results[0].underlying_asset.price;
922
- underlyingTicker = fromMassiveTicker(
923
- data.results[0].underlying_asset.ticker
924
- );
897
+ underlyingTicker = fromMassiveTicker(data.results[0].underlying_asset.ticker);
925
898
  }
926
899
  for (const contract of data.results) {
927
900
  allContracts.push(mapContract(contract));
@@ -930,9 +903,7 @@ var MassiveProvider = class {
930
903
  const nextUrlObj = new URL(data.next_url);
931
904
  const cursor = nextUrlObj.searchParams.get("cursor") ?? data.next_url;
932
905
  if (seenCursors.has(cursor)) {
933
- throw new Error(
934
- `Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`
935
- );
906
+ throw new Error(`Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`);
936
907
  }
937
908
  seenCursors.add(cursor);
938
909
  url = data.next_url;
@@ -1386,7 +1357,7 @@ var ThetaMddsClient = class {
1386
1357
  fetchImpl;
1387
1358
  loadGrpcPackage;
1388
1359
  constructor(env = process.env, fetchImpl = fetch, loadGrpcPackage = async () => {
1389
- const { loadMddsGrpcPackage } = await import("./proto-DWRZJO4E.js");
1360
+ const { loadMddsGrpcPackage } = await import("./proto-YZ4TLX2N.js");
1390
1361
  return loadMddsGrpcPackage();
1391
1362
  }) {
1392
1363
  this.env = env;
@@ -2210,41 +2181,55 @@ var IvSolverPool = class {
2210
2181
  iv: new Float64Array(cols.count),
2211
2182
  ok: new Uint8Array(cols.count)
2212
2183
  };
2213
- const base = Math.floor(cols.count / shardCount);
2214
- const remainder = cols.count % shardCount;
2215
- const shardPromises = [];
2216
- let cursor = 0;
2217
- for (let s = 0; s < shardCount; s++) {
2218
- const size = base + (s < remainder ? 1 : 0);
2219
- const lo = cursor;
2220
- const hi = cursor + size;
2221
- cursor = hi;
2222
- if (size === 0) continue;
2223
- const request = shardRequest(cols, this.nextRequestId++, lo, hi);
2224
- shardPromises.push(
2225
- this.runOnWorker(request).then((reply) => {
2226
- out.delta.set(reply.delta, lo);
2227
- out.gamma.set(reply.gamma, lo);
2228
- out.theta.set(reply.theta, lo);
2229
- out.vega.set(reply.vega, lo);
2230
- out.iv.set(reply.iv, lo);
2231
- out.ok.set(reply.ok, lo);
2232
- })
2233
- );
2184
+ this.refPool();
2185
+ try {
2186
+ const base = Math.floor(cols.count / shardCount);
2187
+ const remainder = cols.count % shardCount;
2188
+ const shardPromises = [];
2189
+ let cursor = 0;
2190
+ for (let s = 0; s < shardCount; s++) {
2191
+ const size = base + (s < remainder ? 1 : 0);
2192
+ const lo = cursor;
2193
+ const hi = cursor + size;
2194
+ cursor = hi;
2195
+ if (size === 0) continue;
2196
+ const request = shardRequest(cols, this.nextRequestId++, lo, hi);
2197
+ shardPromises.push(
2198
+ this.runOnWorker(request).then((reply) => {
2199
+ out.delta.set(reply.delta, lo);
2200
+ out.gamma.set(reply.gamma, lo);
2201
+ out.theta.set(reply.theta, lo);
2202
+ out.vega.set(reply.vega, lo);
2203
+ out.iv.set(reply.iv, lo);
2204
+ out.ok.set(reply.ok, lo);
2205
+ })
2206
+ );
2207
+ }
2208
+ await Promise.all(shardPromises);
2209
+ return out;
2210
+ } finally {
2211
+ this.unrefPool();
2234
2212
  }
2235
- await Promise.all(shardPromises);
2236
- return out;
2237
2213
  }
2238
2214
  ensureWorkers(target) {
2239
2215
  while (this.pool.length < target) {
2240
2216
  const worker = new Worker(this.workerUrl);
2241
2217
  worker.setMaxListeners(0);
2218
+ worker.unref();
2242
2219
  worker.on("error", (err) => {
2243
2220
  throw err;
2244
2221
  });
2245
2222
  this.pool.push({ worker, busy: false });
2246
2223
  }
2247
2224
  }
2225
+ /** Keep the event loop alive while a solve is in flight. */
2226
+ refPool() {
2227
+ for (const { worker } of this.pool) worker.ref();
2228
+ }
2229
+ /** Release the event loop once a solve completes so idle workers don't pin it. */
2230
+ unrefPool() {
2231
+ for (const { worker } of this.pool) worker.unref();
2232
+ }
2248
2233
  runOnWorker(request) {
2249
2234
  return new Promise((resolve, reject) => {
2250
2235
  const slot = this.acquire();
@@ -3033,9 +3018,7 @@ function getProvider() {
3033
3018
  _cached = new ThetaDataProvider();
3034
3019
  break;
3035
3020
  default:
3036
- throw new Error(
3037
- `Unknown MARKET_DATA_PROVIDER: "${name}". Supported: massive, thetadata`
3038
- );
3021
+ throw new Error(`Unknown MARKET_DATA_PROVIDER: "${name}". Supported: massive, thetadata`);
3039
3022
  }
3040
3023
  return _cached;
3041
3024
  }
@@ -3058,4 +3041,4 @@ export {
3058
3041
  getProvider,
3059
3042
  _resetProvider
3060
3043
  };
3061
- //# sourceMappingURL=chunk-PNKG7RY7.js.map
3044
+ //# sourceMappingURL=chunk-ZBJCF4ZG.js.map