tradeblocks-mcp 3.0.2 → 3.3.1

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 (218) hide show
  1. package/README.md +85 -80
  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-QTTR7AAW.js → chunk-2I3S2ZLT.js} +325 -84
  7. package/dist/chunk-2I3S2ZLT.js.map +1 -0
  8. package/dist/{chunk-4BLCXNQ6.js → chunk-4HZLVUOZ.js} +179 -183
  9. package/dist/chunk-4HZLVUOZ.js.map +1 -0
  10. package/dist/{chunk-XXYOUIZY.js → chunk-NWNSKALN.js} +63 -80
  11. package/dist/chunk-NWNSKALN.js.map +1 -0
  12. package/dist/{chunk-PRAYH3RT.js → chunk-WNTYA7ER.js} +29 -12
  13. package/dist/chunk-WNTYA7ER.js.map +1 -0
  14. package/dist/{chunk-BKQ4PM4Y.js → chunk-YZA4RS76.js} +24 -18
  15. package/dist/chunk-YZA4RS76.js.map +1 -0
  16. package/dist/{chunk-W2PP3LEH.js → chunk-ZTJXC3LS.js} +17 -8
  17. package/dist/chunk-ZTJXC3LS.js.map +1 -0
  18. package/dist/daily-log-processor-MZW2XBZY.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-6U33TQUT.js +16 -0
  22. package/dist/{proto-3HZTCWK4.js → proto-V23GIZG2.js} +2 -2
  23. package/dist/{sync-PO4IPCYV.js → sync-3UBC37VW.js} +7 -7
  24. package/dist/test-exports.js +876 -483
  25. package/dist/test-exports.js.map +1 -1
  26. package/dist/trade-processor-DKDCWGKD.js +9 -0
  27. package/dist/{trades-store-LOL3FQSF.js → trades-store-R3NL25T2.js} +2 -2
  28. package/package.json +2 -6
  29. package/server/{chunk-CSDVJPBB.js → chunk-536NSFED.js} +29 -12
  30. package/server/chunk-536NSFED.js.map +1 -0
  31. package/server/{chunk-WA5AAPCH.js → chunk-A3UKD64A.js} +17 -8
  32. package/server/chunk-A3UKD64A.js.map +1 -0
  33. package/server/{chunk-PNKG7RY7.js → chunk-OMUDNJBJ.js} +63 -80
  34. package/server/chunk-OMUDNJBJ.js.map +1 -0
  35. package/server/{chunk-72GKJE2U.js → chunk-RJDJHZ5Y.js} +934 -335
  36. package/server/chunk-RJDJHZ5Y.js.map +1 -0
  37. package/server/{chunk-NZO6PT64.js → chunk-RM4B2VKS.js} +167 -177
  38. package/server/chunk-RM4B2VKS.js.map +1 -0
  39. package/server/{chunk-5EBXHT6C.js → chunk-SY6GDNVI.js} +24 -18
  40. package/server/chunk-SY6GDNVI.js.map +1 -0
  41. package/server/{chunk-FBNDMCT5.js → chunk-T66KH2XH.js} +13 -11
  42. package/server/chunk-T66KH2XH.js.map +1 -0
  43. package/server/{chunk-NRFXAJF7.js → chunk-W5E7FHC4.js} +24 -52
  44. package/server/chunk-W5E7FHC4.js.map +1 -0
  45. package/server/{config-6IZXEFEX.js → config-DK7KOMNL.js} +1 -1
  46. package/server/config-DK7KOMNL.js.map +1 -0
  47. package/server/daily-log-processor-B2VPU2FQ.js +10 -0
  48. package/server/{daily-logs-store-NU7M4L5C.js → daily-logs-store-YFNXTB7J.js} +2 -2
  49. package/server/http-server.js +2 -5
  50. package/server/index.js +2497 -2029
  51. package/server/index.js.map +1 -1
  52. package/server/iv-solver-worker.js +9 -1
  53. package/server/market-provider-L56RFHAC.js +17 -0
  54. package/server/{proto-DWRZJO4E.js → proto-YZ4TLX2N.js} +2 -2
  55. package/server/{sync-QFI5L7S7.js → sync-CENKDN53.js} +7 -7
  56. package/server/trade-processor-3PI4LHZI.js +10 -0
  57. package/server/{trades-store-VY26MWER.js → trades-store-RTTEYMXH.js} +2 -2
  58. package/src/auth/clients-store.ts +4 -4
  59. package/src/auth/code-store.ts +1 -1
  60. package/src/auth/config.ts +11 -12
  61. package/src/auth/login-page.ts +8 -10
  62. package/src/auth/provider.ts +35 -30
  63. package/src/auth/token.ts +17 -15
  64. package/src/db/backtest-schemas.ts +38 -8
  65. package/src/db/connection.ts +107 -40
  66. package/src/db/data-root.ts +22 -0
  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 +139 -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/index.ts +2 -0
  114. package/src/tools/blocks/paired-comparison.ts +425 -0
  115. package/src/tools/blocks/similarity.ts +316 -283
  116. package/src/tools/edge-decay.ts +124 -197
  117. package/src/tools/exit-analysis.ts +130 -77
  118. package/src/tools/greeks-attribution.ts +84 -35
  119. package/src/tools/guides.ts +4 -6
  120. package/src/tools/imports.ts +11 -14
  121. package/src/tools/market-data.ts +1067 -757
  122. package/src/tools/market-enrichment.ts +3 -3
  123. package/src/tools/market-fetch.ts +148 -67
  124. package/src/tools/market-imports.ts +12 -12
  125. package/src/tools/middleware/sync-middleware.ts +5 -6
  126. package/src/tools/performance.ts +185 -302
  127. package/src/tools/profile-analysis.ts +52 -66
  128. package/src/tools/profiles.ts +106 -69
  129. package/src/tools/regime-advisor.ts +20 -45
  130. package/src/tools/replay.ts +81 -77
  131. package/src/tools/reports/discrepancies.ts +298 -328
  132. package/src/tools/reports/fields.ts +7 -25
  133. package/src/tools/reports/helpers.ts +18 -49
  134. package/src/tools/reports/predictive.ts +27 -70
  135. package/src/tools/reports/slippage-trends.ts +315 -345
  136. package/src/tools/reports/slippage.ts +1 -4
  137. package/src/tools/reports/strategy-matches.ts +399 -441
  138. package/src/tools/schema.ts +43 -40
  139. package/src/tools/shared/filters.ts +3 -9
  140. package/src/tools/snapshot.ts +9 -30
  141. package/src/tools/sql.ts +15 -14
  142. package/src/tools/tickers.ts +1 -4
  143. package/src/utils/batch-exit-analysis.ts +31 -42
  144. package/src/utils/black-scholes.ts +39 -29
  145. package/src/utils/block-loader.ts +69 -83
  146. package/src/utils/calibration-probe.ts +3 -4
  147. package/src/utils/chain-loader.ts +3 -3
  148. package/src/utils/csv-discovery.ts +16 -22
  149. package/src/utils/data-quality.ts +24 -36
  150. package/src/utils/exit-triggers.ts +91 -96
  151. package/src/utils/field-timing.ts +94 -79
  152. package/src/utils/filter-predicates.ts +13 -9
  153. package/src/utils/flatfile-importer.ts +94 -64
  154. package/src/utils/greeks-decomposition.ts +152 -100
  155. package/src/utils/iv-solver-pool.ts +55 -25
  156. package/src/utils/iv-solver-worker.ts +5 -5
  157. package/src/utils/market-enricher.ts +528 -497
  158. package/src/utils/market-importer.ts +31 -12
  159. package/src/utils/market-provider.ts +21 -23
  160. package/src/utils/massive-tier.ts +5 -7
  161. package/src/utils/migrate-option-data-helpers.ts +2 -8
  162. package/src/utils/option-quote-greeks.ts +25 -31
  163. package/src/utils/option-time.ts +4 -8
  164. package/src/utils/output-formatter.ts +1 -4
  165. package/src/utils/provider-capabilities.ts +1 -4
  166. package/src/utils/providers/massive.ts +59 -93
  167. package/src/utils/providers/thetadata/backfill.ts +14 -23
  168. package/src/utils/providers/thetadata/client.ts +12 -8
  169. package/src/utils/providers/thetadata/decode.ts +2 -20
  170. package/src/utils/providers/thetadata/endpoints.ts +32 -40
  171. package/src/utils/providers/thetadata/join.ts +11 -10
  172. package/src/utils/providers/thetadata/proto.ts +12 -10
  173. package/src/utils/providers/thetadata/quote-mid-greeks.ts +5 -5
  174. package/src/utils/providers/thetadata.ts +11 -10
  175. package/src/utils/quote-enricher.ts +4 -4
  176. package/src/utils/quote-parquet-projection.ts +3 -11
  177. package/src/utils/sample-date-selector.ts +3 -5
  178. package/src/utils/schema-metadata.ts +102 -70
  179. package/src/utils/ticker.ts +5 -9
  180. package/src/utils/trade-replay.ts +77 -68
  181. package/dist/chunk-4BLCXNQ6.js.map +0 -1
  182. package/dist/chunk-BKQ4PM4Y.js.map +0 -1
  183. package/dist/chunk-FGZH632F.js.map +0 -1
  184. package/dist/chunk-LDKTV7GW.js.map +0 -1
  185. package/dist/chunk-PRAYH3RT.js.map +0 -1
  186. package/dist/chunk-QTTR7AAW.js.map +0 -1
  187. package/dist/chunk-W2PP3LEH.js.map +0 -1
  188. package/dist/chunk-XXYOUIZY.js.map +0 -1
  189. package/dist/daily-log-processor-6MWJ23JK.js +0 -9
  190. package/dist/market-provider-VDRJUEF2.js +0 -16
  191. package/dist/trade-processor-NHU4VWRX.js +0 -9
  192. package/manifest.json +0 -141
  193. package/server/chunk-5EBXHT6C.js.map +0 -1
  194. package/server/chunk-72GKJE2U.js.map +0 -1
  195. package/server/chunk-CSDVJPBB.js.map +0 -1
  196. package/server/chunk-FBNDMCT5.js.map +0 -1
  197. package/server/chunk-NRFXAJF7.js.map +0 -1
  198. package/server/chunk-NZO6PT64.js.map +0 -1
  199. package/server/chunk-PNKG7RY7.js.map +0 -1
  200. package/server/chunk-WA5AAPCH.js.map +0 -1
  201. package/server/config-6IZXEFEX.js.map +0 -1
  202. package/server/daily-log-processor-Y3PVSVBM.js +0 -10
  203. package/server/market-provider-VOYYVYWT.js +0 -17
  204. package/server/trade-processor-JWVS37KM.js +0 -10
  205. /package/dist/{daily-log-processor-6MWJ23JK.js.map → daily-log-processor-MZW2XBZY.js.map} +0 -0
  206. /package/dist/{daily-logs-store-D3QC2XPV.js.map → daily-logs-store-3C3OTGPK.js.map} +0 -0
  207. /package/dist/{market-provider-VDRJUEF2.js.map → market-provider-6U33TQUT.js.map} +0 -0
  208. /package/dist/{proto-3HZTCWK4.js.map → proto-V23GIZG2.js.map} +0 -0
  209. /package/dist/{sync-PO4IPCYV.js.map → sync-3UBC37VW.js.map} +0 -0
  210. /package/dist/{trade-processor-NHU4VWRX.js.map → trade-processor-DKDCWGKD.js.map} +0 -0
  211. /package/dist/{trades-store-LOL3FQSF.js.map → trades-store-R3NL25T2.js.map} +0 -0
  212. /package/server/{daily-log-processor-Y3PVSVBM.js.map → daily-log-processor-B2VPU2FQ.js.map} +0 -0
  213. /package/server/{daily-logs-store-NU7M4L5C.js.map → daily-logs-store-YFNXTB7J.js.map} +0 -0
  214. /package/server/{market-provider-VOYYVYWT.js.map → market-provider-L56RFHAC.js.map} +0 -0
  215. /package/server/{proto-DWRZJO4E.js.map → proto-YZ4TLX2N.js.map} +0 -0
  216. /package/server/{sync-QFI5L7S7.js.map → sync-CENKDN53.js.map} +0 -0
  217. /package/server/{trade-processor-JWVS37KM.js.map → trade-processor-3PI4LHZI.js.map} +0 -0
  218. /package/server/{trades-store-VY26MWER.js.map → trades-store-RTTEYMXH.js.map} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getSofrRateByKey
3
- } from "./chunk-QTTR7AAW.js";
3
+ } from "./chunk-2I3S2ZLT.js";
4
4
  import {
5
5
  loadMddsProtoRoot
6
- } from "./chunk-FGZH632F.js";
6
+ } from "./chunk-2E63THNI.js";
7
7
 
8
8
  // src/utils/providers/massive.ts
9
9
  import { z } from "zod";
@@ -225,7 +225,15 @@ function computeLegGreeks(optionPrice, underlyingPrice, strike, dte, type, riskF
225
225
  const bsType = type === "C" ? "call" : "put";
226
226
  const nullResult = { delta: null, gamma: null, theta: null, vega: null, iv: null };
227
227
  if (dte < BACHELIER_DTE_THRESHOLD) {
228
- const iv2 = solveNormalIV(bsType, optionPrice, underlyingPrice, strike, T, riskFreeRate, dividendYield);
228
+ const iv2 = solveNormalIV(
229
+ bsType,
230
+ optionPrice,
231
+ underlyingPrice,
232
+ strike,
233
+ T,
234
+ riskFreeRate,
235
+ dividendYield
236
+ );
229
237
  if (iv2 === null) return nullResult;
230
238
  return {
231
239
  delta: bachelierDelta(bsType, underlyingPrice, strike, T, riskFreeRate, dividendYield, iv2),
@@ -424,9 +432,7 @@ function etDateTimeToUtcIso(dateStr, timeStr) {
424
432
  function getApiKey() {
425
433
  const key = process.env.MASSIVE_API_KEY;
426
434
  if (!key) {
427
- throw new Error(
428
- "Set MASSIVE_API_KEY environment variable to use Massive.com data import"
429
- );
435
+ throw new Error("Set MASSIVE_API_KEY environment variable to use Massive.com data import");
430
436
  }
431
437
  return key;
432
438
  }
@@ -438,9 +444,7 @@ async function fetchWithRetry(url, headers, maxRetries = 2) {
438
444
  });
439
445
  if (response.status === 429) {
440
446
  if (attempt === maxRetries) {
441
- throw new Error(
442
- "Massive.com rate limit exceeded \u2014 try again in a few minutes"
443
- );
447
+ throw new Error("Massive.com rate limit exceeded \u2014 try again in a few minutes");
444
448
  }
445
449
  const retryAfter = response.headers.get("Retry-After");
446
450
  const backoffMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : Math.pow(2, attempt + 1) * 1e3;
@@ -451,17 +455,7 @@ async function fetchWithRetry(url, headers, maxRetries = 2) {
451
455
  }
452
456
  throw new Error("Massive.com rate limit exceeded after retries");
453
457
  }
454
- var INDEX_TICKERS = /* @__PURE__ */ new Set([
455
- "SPX",
456
- "NDX",
457
- "RUT",
458
- "DJX",
459
- "VIX",
460
- "VIX9D",
461
- "VIX3M",
462
- "OEX",
463
- "XSP"
464
- ]);
458
+ var INDEX_TICKERS = /* @__PURE__ */ new Set(["SPX", "NDX", "RUT", "DJX", "VIX", "VIX9D", "VIX3M", "OEX", "XSP"]);
465
459
  function detectSnapshotAssetClass(ticker) {
466
460
  return INDEX_TICKERS.has(ticker.toUpperCase()) ? "index" : "stock";
467
461
  }
@@ -573,14 +567,7 @@ var MassiveProvider = class {
573
567
  }
574
568
  async fetchBars(options) {
575
569
  const apiKey = getApiKey();
576
- const {
577
- ticker,
578
- from,
579
- to,
580
- timespan = "day",
581
- multiplier = 1,
582
- assetClass = "stock"
583
- } = options;
570
+ const { ticker, from, to, timespan = "day", multiplier = 1, assetClass = "stock" } = options;
584
571
  const apiTicker = toMassiveTicker(ticker, assetClass);
585
572
  const storageTicker = fromMassiveTicker(apiTicker);
586
573
  const headers = { Authorization: `Bearer ${apiKey}` };
@@ -597,14 +584,10 @@ var MassiveProvider = class {
597
584
  }
598
585
  const response = await fetchWithRetry(url, headers);
599
586
  if (response.status === 401) {
600
- throw new Error(
601
- "MASSIVE_API_KEY rejected by Massive.com \u2014 check your key"
602
- );
587
+ throw new Error("MASSIVE_API_KEY rejected by Massive.com \u2014 check your key");
603
588
  }
604
589
  if (!response.ok) {
605
- throw new Error(
606
- `Massive.com API error: HTTP ${response.status} ${response.statusText}`
607
- );
590
+ throw new Error(`Massive.com API error: HTTP ${response.status} ${response.statusText}`);
608
591
  }
609
592
  const json = await response.json();
610
593
  const parsed = MassiveAggregateResponseSchema.safeParse(json);
@@ -632,9 +615,7 @@ var MassiveProvider = class {
632
615
  const nextUrlObj = new URL(data.next_url);
633
616
  const cursor = nextUrlObj.searchParams.get("cursor") ?? data.next_url;
634
617
  if (seenCursors.has(cursor)) {
635
- throw new Error(
636
- `Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`
637
- );
618
+ throw new Error(`Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`);
638
619
  }
639
620
  seenCursors.add(cursor);
640
621
  url = data.next_url;
@@ -847,9 +828,7 @@ var MassiveProvider = class {
847
828
  try {
848
829
  mkdir(dirname(outputPath), { recursive: true });
849
830
  await conn.run(sql);
850
- const countResult = await conn.runAndReadAll(
851
- `SELECT count(*) AS cnt FROM '${outputPath}'`
852
- );
831
+ const countResult = await conn.runAndReadAll(`SELECT count(*) AS cnt FROM '${outputPath}'`);
853
832
  const rowCount = Number(countResult.getRows()[0][0]);
854
833
  return { rowCount, skipped: false };
855
834
  } finally {
@@ -900,14 +879,10 @@ var MassiveProvider = class {
900
879
  }
901
880
  const response = await fetchWithRetry(url, headers);
902
881
  if (response.status === 401) {
903
- throw new Error(
904
- "MASSIVE_API_KEY rejected by Massive.com \u2014 check your key"
905
- );
882
+ throw new Error("MASSIVE_API_KEY rejected by Massive.com \u2014 check your key");
906
883
  }
907
884
  if (!response.ok) {
908
- throw new Error(
909
- `Massive.com API error: HTTP ${response.status} ${response.statusText}`
910
- );
885
+ throw new Error(`Massive.com API error: HTTP ${response.status} ${response.statusText}`);
911
886
  }
912
887
  const json = await response.json();
913
888
  const parsed = MassiveSnapshotResponseSchema.safeParse(json);
@@ -918,9 +893,7 @@ var MassiveProvider = class {
918
893
  const data = parsed.data;
919
894
  if (data.results.length > 0 && underlyingPrice === 0) {
920
895
  underlyingPrice = data.results[0].underlying_asset.price;
921
- underlyingTicker = fromMassiveTicker(
922
- data.results[0].underlying_asset.ticker
923
- );
896
+ underlyingTicker = fromMassiveTicker(data.results[0].underlying_asset.ticker);
924
897
  }
925
898
  for (const contract of data.results) {
926
899
  allContracts.push(mapContract(contract));
@@ -929,9 +902,7 @@ var MassiveProvider = class {
929
902
  const nextUrlObj = new URL(data.next_url);
930
903
  const cursor = nextUrlObj.searchParams.get("cursor") ?? data.next_url;
931
904
  if (seenCursors.has(cursor)) {
932
- throw new Error(
933
- `Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`
934
- );
905
+ throw new Error(`Pagination loop detected \u2014 cursor repeated: ${cursor.slice(0, 50)}...`);
935
906
  }
936
907
  seenCursors.add(cursor);
937
908
  url = data.next_url;
@@ -1385,7 +1356,7 @@ var ThetaMddsClient = class {
1385
1356
  fetchImpl;
1386
1357
  loadGrpcPackage;
1387
1358
  constructor(env = process.env, fetchImpl = fetch, loadGrpcPackage = async () => {
1388
- const { loadMddsGrpcPackage } = await import("./proto-3HZTCWK4.js");
1359
+ const { loadMddsGrpcPackage } = await import("./proto-V23GIZG2.js");
1389
1360
  return loadMddsGrpcPackage();
1390
1361
  }) {
1391
1362
  this.env = env;
@@ -2295,41 +2266,55 @@ var IvSolverPool = class {
2295
2266
  iv: new Float64Array(cols.count),
2296
2267
  ok: new Uint8Array(cols.count)
2297
2268
  };
2298
- const base = Math.floor(cols.count / shardCount);
2299
- const remainder = cols.count % shardCount;
2300
- const shardPromises = [];
2301
- let cursor = 0;
2302
- for (let s = 0; s < shardCount; s++) {
2303
- const size = base + (s < remainder ? 1 : 0);
2304
- const lo = cursor;
2305
- const hi = cursor + size;
2306
- cursor = hi;
2307
- if (size === 0) continue;
2308
- const request = shardRequest(cols, this.nextRequestId++, lo, hi);
2309
- shardPromises.push(
2310
- this.runOnWorker(request).then((reply) => {
2311
- out.delta.set(reply.delta, lo);
2312
- out.gamma.set(reply.gamma, lo);
2313
- out.theta.set(reply.theta, lo);
2314
- out.vega.set(reply.vega, lo);
2315
- out.iv.set(reply.iv, lo);
2316
- out.ok.set(reply.ok, lo);
2317
- })
2318
- );
2269
+ this.refPool();
2270
+ try {
2271
+ const base = Math.floor(cols.count / shardCount);
2272
+ const remainder = cols.count % shardCount;
2273
+ const shardPromises = [];
2274
+ let cursor = 0;
2275
+ for (let s = 0; s < shardCount; s++) {
2276
+ const size = base + (s < remainder ? 1 : 0);
2277
+ const lo = cursor;
2278
+ const hi = cursor + size;
2279
+ cursor = hi;
2280
+ if (size === 0) continue;
2281
+ const request = shardRequest(cols, this.nextRequestId++, lo, hi);
2282
+ shardPromises.push(
2283
+ this.runOnWorker(request).then((reply) => {
2284
+ out.delta.set(reply.delta, lo);
2285
+ out.gamma.set(reply.gamma, lo);
2286
+ out.theta.set(reply.theta, lo);
2287
+ out.vega.set(reply.vega, lo);
2288
+ out.iv.set(reply.iv, lo);
2289
+ out.ok.set(reply.ok, lo);
2290
+ })
2291
+ );
2292
+ }
2293
+ await Promise.all(shardPromises);
2294
+ return out;
2295
+ } finally {
2296
+ this.unrefPool();
2319
2297
  }
2320
- await Promise.all(shardPromises);
2321
- return out;
2322
2298
  }
2323
2299
  ensureWorkers(target) {
2324
2300
  while (this.pool.length < target) {
2325
2301
  const worker = new Worker(this.workerUrl);
2326
2302
  worker.setMaxListeners(0);
2303
+ worker.unref();
2327
2304
  worker.on("error", (err) => {
2328
2305
  throw err;
2329
2306
  });
2330
2307
  this.pool.push({ worker, busy: false });
2331
2308
  }
2332
2309
  }
2310
+ /** Keep the event loop alive while a solve is in flight. */
2311
+ refPool() {
2312
+ for (const { worker } of this.pool) worker.ref();
2313
+ }
2314
+ /** Release the event loop once a solve completes so idle workers don't pin it. */
2315
+ unrefPool() {
2316
+ for (const { worker } of this.pool) worker.unref();
2317
+ }
2333
2318
  runOnWorker(request) {
2334
2319
  return new Promise((resolve, reject) => {
2335
2320
  const slot = this.acquire();
@@ -3219,9 +3204,7 @@ function getProvider() {
3219
3204
  _cached = new ThetaDataProvider();
3220
3205
  break;
3221
3206
  default:
3222
- throw new Error(
3223
- `Unknown MARKET_DATA_PROVIDER: "${name}". Supported: massive, thetadata`
3224
- );
3207
+ throw new Error(`Unknown MARKET_DATA_PROVIDER: "${name}". Supported: massive, thetadata`);
3225
3208
  }
3226
3209
  return _cached;
3227
3210
  }
@@ -3305,4 +3288,4 @@ export {
3305
3288
  getProvider,
3306
3289
  _resetProvider
3307
3290
  };
3308
- //# sourceMappingURL=chunk-XXYOUIZY.js.map
3291
+ //# sourceMappingURL=chunk-NWNSKALN.js.map