tradeblocks-mcp 4.2.0 → 4.3.0

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 (47) hide show
  1. package/README.md +40 -1
  2. package/dist/{chunk-YRD62LDE.js → chunk-35RVWZGT.js} +4 -1
  3. package/dist/{chunk-4UU7IT2A.js.map → chunk-35RVWZGT.js.map} +1 -1
  4. package/dist/{chunk-4UU7IT2A.js → chunk-ENXBPJ7Y.js} +148 -6
  5. package/dist/chunk-ENXBPJ7Y.js.map +1 -0
  6. package/dist/{chunk-62GCLMQA.js → chunk-TLX7IBCM.js} +3 -6
  7. package/dist/chunk-TLX7IBCM.js.map +1 -0
  8. package/dist/{daily-logs-store-PXB53WEK.js → daily-logs-store-FZRIGYUX.js} +2 -2
  9. package/dist/{daily-logs-store-65YHFJ5F.js → daily-logs-store-MEZ5S3BR.js} +2 -2
  10. package/dist/market/provenance/index.js +1 -4
  11. package/dist/market/provenance/index.js.map +1 -1
  12. package/dist/{sync-JL7OPLCT.js → sync-EW33QZPD.js} +3 -3
  13. package/dist/test-exports.js +320 -279
  14. package/dist/test-exports.js.map +1 -1
  15. package/dist/{trades-store-UGZ62A7N.js → trades-store-3TOLBL2W.js} +2 -2
  16. package/dist/{trades-store-MOFJHRC2.js → trades-store-PNLPRYRJ.js} +2 -2
  17. package/package.json +1 -1
  18. package/server/{chunk-7N6HBOAY.js → chunk-PDSUY2X2.js} +148 -6
  19. package/server/chunk-PDSUY2X2.js.map +1 -0
  20. package/server/{chunk-J4GWE6JR.js → chunk-YIWLVX7Z.js} +3 -6
  21. package/server/chunk-YIWLVX7Z.js.map +1 -0
  22. package/server/{daily-logs-store-YAXASQN4.js → daily-logs-store-LRVO7COL.js} +2 -2
  23. package/server/index.js +993 -801
  24. package/server/index.js.map +1 -1
  25. package/server/{sync-ZV3QEGMO.js → sync-2POG6KA6.js} +3 -3
  26. package/server/{trades-store-MF7YYLCH.js → trades-store-MXUZLSF5.js} +2 -2
  27. package/src/db/dataset-schemas.ts +97 -23
  28. package/src/tools/market-data.ts +327 -245
  29. package/src/tools/profile-analysis.ts +18 -4
  30. package/src/tools/reports/fields.ts +16 -11
  31. package/src/tools/reports/helpers.ts +6 -2
  32. package/src/tools/reports/predictive.ts +15 -4
  33. package/src/tools/shared/field-analysis.ts +57 -14
  34. package/src/tools/shared/filter-objective.ts +73 -0
  35. package/src/utils/trade-analysis-fields.ts +19 -4
  36. package/dist/chunk-62GCLMQA.js.map +0 -1
  37. package/dist/chunk-YRD62LDE.js.map +0 -1
  38. package/server/chunk-7N6HBOAY.js.map +0 -1
  39. package/server/chunk-J4GWE6JR.js.map +0 -1
  40. /package/dist/{daily-logs-store-65YHFJ5F.js.map → daily-logs-store-FZRIGYUX.js.map} +0 -0
  41. /package/dist/{daily-logs-store-PXB53WEK.js.map → daily-logs-store-MEZ5S3BR.js.map} +0 -0
  42. /package/dist/{sync-JL7OPLCT.js.map → sync-EW33QZPD.js.map} +0 -0
  43. /package/dist/{trades-store-MOFJHRC2.js.map → trades-store-3TOLBL2W.js.map} +0 -0
  44. /package/dist/{trades-store-UGZ62A7N.js.map → trades-store-PNLPRYRJ.js.map} +0 -0
  45. /package/server/{daily-logs-store-YAXASQN4.js.map → daily-logs-store-LRVO7COL.js.map} +0 -0
  46. /package/server/{sync-ZV3QEGMO.js.map → sync-2POG6KA6.js.map} +0 -0
  47. /package/server/{trades-store-MF7YYLCH.js.map → trades-store-MXUZLSF5.js.map} +0 -0
@@ -11,7 +11,7 @@ import {
11
11
  getTradesPage,
12
12
  searchTrades,
13
13
  updateTradesForBlock
14
- } from "./chunk-4UU7IT2A.js";
14
+ } from "./chunk-ENXBPJ7Y.js";
15
15
  import "./chunk-BH6SQOWF.js";
16
16
  import "./chunk-5WRI5ZAA.js";
17
17
  export {
@@ -28,4 +28,4 @@ export {
28
28
  searchTrades,
29
29
  updateTradesForBlock
30
30
  };
31
- //# sourceMappingURL=trades-store-UGZ62A7N.js.map
31
+ //# sourceMappingURL=trades-store-3TOLBL2W.js.map
@@ -11,7 +11,7 @@ import {
11
11
  getTradesPage,
12
12
  searchTrades,
13
13
  updateTradesForBlock
14
- } from "./chunk-YRD62LDE.js";
14
+ } from "./chunk-35RVWZGT.js";
15
15
  import "./chunk-BH6SQOWF.js";
16
16
  export {
17
17
  addTrades,
@@ -27,4 +27,4 @@ export {
27
27
  searchTrades,
28
28
  updateTradesForBlock
29
29
  };
30
- //# sourceMappingURL=trades-store-MOFJHRC2.js.map
30
+ //# sourceMappingURL=trades-store-PNLPRYRJ.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tradeblocks-mcp",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "MCP server for options trade analysis",
5
5
  "author": "David Romeo <davidmromeo@gmail.com>",
6
6
  "type": "module",
@@ -5519,6 +5519,131 @@ async function getTradesPage(blockId, offset, limit) {
5519
5519
  // ../lib/utils/trade-frequency.ts
5520
5520
  var MS_PER_DAY = 1e3 * 60 * 60 * 24;
5521
5521
 
5522
+ // ../lib/calculations/xnys-session-calendar.ts
5523
+ var XNYS_SESSION_CALENDAR_REVISION = "xnys-full-day-2022-2030-v1";
5524
+ var XNYS_SESSION_CALENDAR_SUPPORTED_FROM = "2022-01-01";
5525
+ var XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH = "2030-12-31";
5526
+ var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
5527
+ var MS_PER_DAY2 = 24 * 60 * 60 * 1e3;
5528
+ var SPECIAL_CLOSURES = /* @__PURE__ */ new Set(["2025-01-09"]);
5529
+ function isoDate(date) {
5530
+ return date.toISOString().slice(0, 10);
5531
+ }
5532
+ function utcDate(year, monthIndex, day) {
5533
+ return new Date(Date.UTC(year, monthIndex, day));
5534
+ }
5535
+ function parseSupportedDate(value, label) {
5536
+ if (!ISO_DATE_RE.test(value)) {
5537
+ throw new TypeError(
5538
+ `${label} must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`
5539
+ );
5540
+ }
5541
+ const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
5542
+ if (!Number.isFinite(parsed.getTime()) || isoDate(parsed) !== value) {
5543
+ throw new TypeError(`${label} is not a real calendar date: ${JSON.stringify(value)}`);
5544
+ }
5545
+ if (value < XNYS_SESSION_CALENDAR_SUPPORTED_FROM || value > XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH) {
5546
+ throw new RangeError(
5547
+ `${label} ${JSON.stringify(value)} is outside XNYS calendar revision ${XNYS_SESSION_CALENDAR_REVISION} [${XNYS_SESSION_CALENDAR_SUPPORTED_FROM}, ${XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH}]`
5548
+ );
5549
+ }
5550
+ return parsed;
5551
+ }
5552
+ function nthWeekdayOfMonth(year, monthIndex, weekday, occurrence) {
5553
+ const first = utcDate(year, monthIndex, 1);
5554
+ const offset = (weekday - first.getUTCDay() + 7) % 7;
5555
+ return utcDate(year, monthIndex, 1 + offset + (occurrence - 1) * 7);
5556
+ }
5557
+ function lastWeekdayOfMonth(year, monthIndex, weekday) {
5558
+ const last = utcDate(year, monthIndex + 1, 0);
5559
+ const offset = (last.getUTCDay() - weekday + 7) % 7;
5560
+ return utcDate(year, monthIndex, last.getUTCDate() - offset);
5561
+ }
5562
+ function easterSunday(year) {
5563
+ const a = year % 19;
5564
+ const b = Math.floor(year / 100);
5565
+ const c = year % 100;
5566
+ const d = Math.floor(b / 4);
5567
+ const e = b % 4;
5568
+ const f = Math.floor((b + 8) / 25);
5569
+ const g = Math.floor((b - f + 1) / 3);
5570
+ const h = (19 * a + b - d - g + 15) % 30;
5571
+ const i = Math.floor(c / 4);
5572
+ const k = c % 4;
5573
+ const l = (32 + 2 * e + 2 * i - h - k) % 7;
5574
+ const m = Math.floor((a + 11 * h + 22 * l) / 451);
5575
+ const month = Math.floor((h + l - 7 * m + 114) / 31);
5576
+ const day = (h + l - 7 * m + 114) % 31 + 1;
5577
+ return utcDate(year, month - 1, day);
5578
+ }
5579
+ function addDays(date, days) {
5580
+ return new Date(date.getTime() + days * MS_PER_DAY2);
5581
+ }
5582
+ function observedFixedHoliday(year, monthIndex, day) {
5583
+ const holiday = utcDate(year, monthIndex, day);
5584
+ if (holiday.getUTCDay() === 6) return addDays(holiday, -1);
5585
+ if (holiday.getUTCDay() === 0) return addDays(holiday, 1);
5586
+ return holiday;
5587
+ }
5588
+ function addNewYearsClosure(closures, holidayYear) {
5589
+ const holiday = utcDate(holidayYear, 0, 1);
5590
+ if (holiday.getUTCDay() === 6) {
5591
+ return;
5592
+ }
5593
+ closures.add(isoDate(holiday.getUTCDay() === 0 ? addDays(holiday, 1) : holiday));
5594
+ }
5595
+ function holidayClosures(year) {
5596
+ const closures = /* @__PURE__ */ new Set();
5597
+ const add = (date) => {
5598
+ closures.add(isoDate(date));
5599
+ };
5600
+ addNewYearsClosure(closures, year);
5601
+ addNewYearsClosure(closures, year + 1);
5602
+ add(nthWeekdayOfMonth(year, 0, 1, 3));
5603
+ add(nthWeekdayOfMonth(year, 1, 1, 3));
5604
+ add(addDays(easterSunday(year), -2));
5605
+ add(lastWeekdayOfMonth(year, 4, 1));
5606
+ add(observedFixedHoliday(year, 5, 19));
5607
+ add(observedFixedHoliday(year, 6, 4));
5608
+ add(nthWeekdayOfMonth(year, 8, 1, 1));
5609
+ add(nthWeekdayOfMonth(year, 10, 4, 4));
5610
+ add(observedFixedHoliday(year, 11, 25));
5611
+ for (const date of SPECIAL_CLOSURES) {
5612
+ if (date.startsWith(`${year}-`)) closures.add(date);
5613
+ }
5614
+ return closures;
5615
+ }
5616
+ var CLOSURES_BY_YEAR = /* @__PURE__ */ new Map();
5617
+ function closuresForYear(year) {
5618
+ let closures = CLOSURES_BY_YEAR.get(year);
5619
+ if (!closures) {
5620
+ closures = holidayClosures(year);
5621
+ CLOSURES_BY_YEAR.set(year, closures);
5622
+ }
5623
+ return closures;
5624
+ }
5625
+ function isXnysSessionDate(value) {
5626
+ const date = parseSupportedDate(value, "XNYS session date");
5627
+ const weekday = date.getUTCDay();
5628
+ if (weekday === 0 || weekday === 6) return false;
5629
+ return !closuresForYear(date.getUTCFullYear()).has(value);
5630
+ }
5631
+ function enumerateXnysSessions(from, through) {
5632
+ const first = parseSupportedDate(from, "XNYS session range from");
5633
+ const last = parseSupportedDate(through, "XNYS session range through");
5634
+ if (first.getTime() > last.getTime()) {
5635
+ throw new RangeError(
5636
+ `XNYS session range from ${JSON.stringify(from)} exceeds through ${JSON.stringify(through)}`
5637
+ );
5638
+ }
5639
+ const sessions = [];
5640
+ for (let cursor = first; cursor.getTime() <= last.getTime(); cursor = addDays(cursor, 1)) {
5641
+ const date = isoDate(cursor);
5642
+ if (isXnysSessionDate(date)) sessions.push(date);
5643
+ }
5644
+ return Object.freeze(sessions);
5645
+ }
5646
+
5522
5647
  // ../lib/calculations/static-dataset-matcher.ts
5523
5648
  function validateDatasetTiming(dataset, hasDateOnly) {
5524
5649
  if (dataset.knownBy !== void 0 && !/^([01]\d|2[0-3]):[0-5]\d$/.test(dataset.knownBy)) {
@@ -5555,7 +5680,9 @@ function getDatasetValueAvailableAt(dataset, row, column) {
5555
5680
  return combineDateAndTime(next, "00:00");
5556
5681
  }
5557
5682
  var availabilityIndexes = /* @__PURE__ */ new WeakMap();
5558
- function resolveDatasetColumnAtTime(dataset, rows, column, entryTime) {
5683
+ function resolveDatasetColumnAtTime(dataset, rows, column, entryTime, maxMissedSessions) {
5684
+ if (maxMissedSessions !== void 0 && (!Number.isInteger(maxMissedSessions) || maxMissedSessions < 0))
5685
+ throw new Error("maxMissedSessions must be a nonnegative integer");
5559
5686
  if (!dataset.columns.includes(column)) throw new Error(`Unknown dataset column: ${column}`);
5560
5687
  let rowIndexes = availabilityIndexes.get(dataset);
5561
5688
  if (!rowIndexes) {
@@ -5588,7 +5715,22 @@ function resolveDatasetColumnAtTime(dataset, rows, column, entryTime) {
5588
5715
  }
5589
5716
  if (!left) return null;
5590
5717
  const match = index[left - 1];
5591
- return { value: match.row.values[column], row: match.row, availableAt: new Date(match.time) };
5718
+ const sourceDay = getDateOnly(new Date(match.row.timestamp));
5719
+ const entryDay = getDateOnly(entryTime);
5720
+ let sessionAge = "unsupported";
5721
+ if (dataset.timingMode === "declared" && sourceDay >= XNYS_SESSION_CALENDAR_SUPPORTED_FROM && entryDay <= XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH) {
5722
+ const includeToday = dataset.columnTiming?.[column] === "open" && entryTime >= combineDateAndTime(/* @__PURE__ */ new Date(`${entryDay}T00:00:00Z`), dataset.knownBy ?? "00:00");
5723
+ sessionAge = enumerateXnysSessions(sourceDay, entryDay).filter(
5724
+ (day) => day > sourceDay && (day < entryDay || includeToday)
5725
+ ).length;
5726
+ }
5727
+ return {
5728
+ value: match.row.values[column],
5729
+ row: match.row,
5730
+ availableAt: new Date(match.time),
5731
+ sessionAge,
5732
+ accepted: maxMissedSessions === void 0 || sessionAge !== "unsupported" && sessionAge <= maxMissedSessions
5733
+ };
5592
5734
  }
5593
5735
  function combineDateAndTime(dateOpened, timeOpened) {
5594
5736
  const d = new Date(dateOpened);
@@ -5614,10 +5756,10 @@ function combineDateAndTime(dateOpened, timeOpened) {
5614
5756
  minutes = parseInt(timeParts[1], 10) || 0;
5615
5757
  seconds = timeParts.length > 2 ? parseInt(timeParts[2], 10) || 0 : 0;
5616
5758
  }
5617
- const utcDate = Date.UTC(year, month, day, hours, minutes, seconds, 0);
5618
- const testDate = new Date(utcDate);
5759
+ const utcDate2 = Date.UTC(year, month, day, hours, minutes, seconds, 0);
5760
+ const testDate = new Date(utcDate2);
5619
5761
  const etOffset = getEasternTimeOffset(testDate);
5620
- return new Date(utcDate - etOffset * 60 * 1e3);
5762
+ return new Date(utcDate2 - etOffset * 60 * 1e3);
5621
5763
  }
5622
5764
  function getEasternTimeOffset(date) {
5623
5765
  const formatter = new Intl.DateTimeFormat("en-US", {
@@ -6160,4 +6302,4 @@ export {
6160
6302
  searchTrades,
6161
6303
  getTradesPage
6162
6304
  };
6163
- //# sourceMappingURL=chunk-7N6HBOAY.js.map
6305
+ //# sourceMappingURL=chunk-PDSUY2X2.js.map