tradeblocks-mcp 4.0.0 → 4.1.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.
- package/README.md +36 -15
- package/dist/{chunk-YQMQ3PI4.js → chunk-4UU7IT2A.js} +112 -1
- package/dist/chunk-4UU7IT2A.js.map +1 -0
- package/dist/{chunk-HQQNVMYF.js → chunk-FQKKA5WL.js} +63 -31
- package/dist/chunk-FQKKA5WL.js.map +1 -0
- package/dist/{chunk-XF3F3S7D.js → chunk-YRD62LDE.js} +1 -1
- package/dist/{chunk-XF3F3S7D.js.map → chunk-YRD62LDE.js.map} +1 -1
- package/dist/{daily-logs-store-LRZBF2UA.js → daily-logs-store-65YHFJ5F.js} +2 -2
- package/dist/{daily-logs-store-UNX5DAT7.js → daily-logs-store-PXB53WEK.js} +2 -2
- package/dist/market/provenance/index.js +30 -10
- package/dist/market/provenance/index.js.map +1 -1
- package/dist/{sync-I2S5TFQS.js → sync-VK2VEYHM.js} +3 -3
- package/dist/test-exports.js +559 -146
- package/dist/test-exports.js.map +1 -1
- package/dist/{trades-store-O4ETTDGU.js → trades-store-MOFJHRC2.js} +2 -2
- package/dist/{trades-store-P6QZQMAD.js → trades-store-UGZ62A7N.js} +2 -2
- package/package.json +2 -2
- package/server/{chunk-3XKPTACI.js → chunk-7N6HBOAY.js} +129 -1
- package/server/chunk-7N6HBOAY.js.map +1 -0
- package/server/{chunk-JI2QLM6W.js → chunk-JSQFHCJO.js} +3406 -2978
- package/server/chunk-JSQFHCJO.js.map +1 -0
- package/server/{daily-logs-store-EMWH6MR4.js → daily-logs-store-YAXASQN4.js} +2 -2
- package/server/index.js +1893 -900
- package/server/index.js.map +1 -1
- package/server/{sync-NNHKLGNZ.js → sync-3W2RJUZ6.js} +3 -3
- package/server/{trades-store-3QYMUVA5.js → trades-store-MF7YYLCH.js} +2 -2
- package/src/db/dataset-schemas.ts +236 -0
- package/src/db/parquet-writer.ts +31 -1
- package/src/index.ts +3 -1
- package/src/market/ingestor/market-ingestor.ts +100 -29
- package/src/market/ingestor/types.ts +3 -0
- package/src/market/stores/parquet-quote-store.ts +19 -2
- package/src/prompts.ts +2 -2
- package/src/tools/analysis.ts +107 -6
- package/src/tools/blocks/analysis.ts +322 -209
- package/src/tools/datasets.ts +147 -0
- package/src/tools/market-data.ts +51 -5
- package/src/tools/market-fetch.ts +8 -6
- package/src/tools/middleware/strict-arguments.ts +1 -1
- package/src/tools/profile-analysis.ts +203 -77
- package/src/tools/reports/fields.ts +8 -3
- package/src/tools/reports/helpers.ts +19 -0
- package/src/tools/reports/predictive.ts +31 -45
- package/src/tools/schema.ts +9 -0
- package/src/tools/shared/field-analysis.ts +171 -0
- package/src/utils/filter-predicates.ts +48 -19
- package/src/utils/market-provider.ts +17 -2
- package/src/utils/providers/massive.ts +151 -31
- package/src/utils/threshold-sweep.ts +35 -0
- package/src/utils/trade-analysis-fields.ts +72 -0
- package/dist/chunk-HQQNVMYF.js.map +0 -1
- package/dist/chunk-YQMQ3PI4.js.map +0 -1
- package/server/chunk-3XKPTACI.js.map +0 -1
- package/server/chunk-JI2QLM6W.js.map +0 -1
- /package/dist/{daily-logs-store-LRZBF2UA.js.map → daily-logs-store-65YHFJ5F.js.map} +0 -0
- /package/dist/{daily-logs-store-UNX5DAT7.js.map → daily-logs-store-PXB53WEK.js.map} +0 -0
- /package/dist/{sync-I2S5TFQS.js.map → sync-VK2VEYHM.js.map} +0 -0
- /package/dist/{trades-store-O4ETTDGU.js.map → trades-store-MOFJHRC2.js.map} +0 -0
- /package/dist/{trades-store-P6QZQMAD.js.map → trades-store-UGZ62A7N.js.map} +0 -0
- /package/server/{daily-logs-store-EMWH6MR4.js.map → daily-logs-store-YAXASQN4.js.map} +0 -0
- /package/server/{sync-NNHKLGNZ.js.map → sync-3W2RJUZ6.js.map} +0 -0
- /package/server/{trades-store-3QYMUVA5.js.map → trades-store-MF7YYLCH.js.map} +0 -0
package/README.md
CHANGED
|
@@ -510,21 +510,35 @@ such as `calculatedAt`, sync times, and market-feed timestamps, remain ISO times
|
|
|
510
510
|
|
|
511
511
|
### Market Data Tools
|
|
512
512
|
|
|
513
|
-
| Tool | Description
|
|
514
|
-
| ---------------------------- |
|
|
515
|
-
| `import_market_csv` | Import market data CSV with column mapping
|
|
516
|
-
| `import_from_database` | Import from external DuckDB databases
|
|
517
|
-
| `import_flat_file` | Import a local Parquet or CSV flat file for a ticker/timespan
|
|
518
|
-
| `fetch_bars` | Fetch daily or intraday OHLCV bars from configured provider
|
|
519
|
-
| `fetch_quotes` | Fetch option minute quotes from configured provider
|
|
520
|
-
| `fetch_chain` | Fetch option chain snapshot for an underlying on a given date
|
|
521
|
-
| `compute_vix_context` | Compute cross-ticker VIX regime fields for a date range
|
|
522
|
-
| `refresh_market_data` | Composite daily refresh: fetch bars, auto-fire VIX context, return coverage report
|
|
523
|
-
| `enrich_market_data` | Compute ~40 derived indicators from raw OHLCV
|
|
524
|
-
| `enrich_trades` | Enrich trades with market
|
|
525
|
-
| `analyze_regime_performance` | Analyze P&L by
|
|
526
|
-
| `suggest_filters` |
|
|
527
|
-
| `calculate_orb` | Opening range breakout analysis from intraday bars
|
|
513
|
+
| Tool | Description |
|
|
514
|
+
| ---------------------------- | ----------------------------------------------------------------------------------- |
|
|
515
|
+
| `import_market_csv` | Import market data CSV with column mapping |
|
|
516
|
+
| `import_from_database` | Import from external DuckDB databases |
|
|
517
|
+
| `import_flat_file` | Import a local Parquet or CSV flat file for a ticker/timespan |
|
|
518
|
+
| `fetch_bars` | Fetch daily or intraday OHLCV bars from configured provider |
|
|
519
|
+
| `fetch_quotes` | Fetch option minute quotes from configured provider |
|
|
520
|
+
| `fetch_chain` | Fetch option chain snapshot for an underlying on a given date |
|
|
521
|
+
| `compute_vix_context` | Compute cross-ticker VIX regime fields for a date range |
|
|
522
|
+
| `refresh_market_data` | Composite daily refresh: fetch bars, auto-fire VIX context, return coverage report |
|
|
523
|
+
| `enrich_market_data` | Compute ~40 derived indicators from raw OHLCV |
|
|
524
|
+
| `enrich_trades` | Enrich trades with causal market/dataset values, provenance and custom fields |
|
|
525
|
+
| `analyze_regime_performance` | Analyze P&L by presets or any registered field (numeric bins or categorical values) |
|
|
526
|
+
| `suggest_filters` | Default market filters or optional fields with generic threshold/exclusion sweeps |
|
|
527
|
+
| `calculate_orb` | Opening range breakout analysis from intraday bars |
|
|
528
|
+
| `import_daily_dataset` | Import or replace a user Static Dataset with per-column timing |
|
|
529
|
+
| `list_daily_datasets` | List user datasets, fields, timing and coverage |
|
|
530
|
+
| `delete_daily_dataset` | Remove a dataset and its registered fields |
|
|
531
|
+
| `list_analysis_fields` | Discover built-in and dataset fields at runtime |
|
|
532
|
+
|
|
533
|
+
Since 4.1.0, user daily datasets use `<dataset>.<column>` field names in profile filters,
|
|
534
|
+
predictive reports, regime analysis and threshold sweeps. `import_daily_dataset` takes
|
|
535
|
+
`name`, exactly one of inline `content` or `csvPath` under the server's data root, and optional
|
|
536
|
+
`ticker`, `columnTiming` and `knownBy` (`HH:mm` ET). Re-import replaces the named dataset
|
|
537
|
+
atomically, without changing market data or requiring provider credentials. Date-only close
|
|
538
|
+
values are available the following calendar day at 00:00 ET; date-only open values require
|
|
539
|
+
`knownBy`; timestamped rows are as-of. Sparse columns carry forward their latest available
|
|
540
|
+
observation without a freshness cutoff. See the [dataset tools reference](../../docs/mcp-tools.md#market-analysis)
|
|
541
|
+
and [4.1.0 behavior changes](../../releases/v4.1.0.md#behavior-changes).
|
|
528
542
|
|
|
529
543
|
### Strategy Profile Tools
|
|
530
544
|
|
|
@@ -538,6 +552,13 @@ such as `calculatedAt`, sync times, and market-feed timestamps, remain ISO times
|
|
|
538
552
|
| `validate_entry_filters` | Test each entry filter's contribution to edge |
|
|
539
553
|
| `portfolio_structure_map` | Regime x structure coverage matrix across strategies |
|
|
540
554
|
|
|
555
|
+
`validate_entry_filters` names unknown market fields with reasons in
|
|
556
|
+
`unresolvable_filters`, warnings, and its summary; they are excluded from ablation
|
|
557
|
+
so known filters remain analyzable. If all market filters are unknown, it returns
|
|
558
|
+
`error: "no_resolvable_filters"`. `analyze_structure_fit` reports the same exclusions
|
|
559
|
+
and keeps its remaining dimensions. Known fields with missing daily values retain
|
|
560
|
+
their existing missing-data treatment.
|
|
561
|
+
|
|
541
562
|
### Import Tools
|
|
542
563
|
|
|
543
564
|
| Tool | Description |
|
|
@@ -5327,6 +5327,115 @@ async function getTradesPage(blockId, offset, limit) {
|
|
|
5327
5327
|
// ../lib/utils/trade-frequency.ts
|
|
5328
5328
|
var MS_PER_DAY = 1e3 * 60 * 60 * 24;
|
|
5329
5329
|
|
|
5330
|
+
// ../lib/calculations/static-dataset-matcher.ts
|
|
5331
|
+
function getDatasetValueAvailableAt(dataset, row, column) {
|
|
5332
|
+
if (!dataset.columns.includes(column)) throw new Error(`Unknown dataset column: ${column}`);
|
|
5333
|
+
if (dataset.timingMode !== "declared") return new Date(row.timestamp);
|
|
5334
|
+
const timing = dataset.columnTiming?.[column];
|
|
5335
|
+
if (timing !== "close" && timing !== "open")
|
|
5336
|
+
throw new Error(`Declare open or close timing for ${column}`);
|
|
5337
|
+
if (!(row.dateOnly ?? dataset.dateOnly)) return new Date(row.timestamp);
|
|
5338
|
+
const day = getDateOnly(new Date(row.timestamp));
|
|
5339
|
+
if (timing === "open") {
|
|
5340
|
+
if (!dataset.knownBy || !/^([01]\d|2[0-3]):[0-5]\d$/.test(dataset.knownBy)) {
|
|
5341
|
+
throw new Error(`Date-only open column ${column} requires a known-by time (ET)`);
|
|
5342
|
+
}
|
|
5343
|
+
return combineDateAndTime(/* @__PURE__ */ new Date(`${day}T00:00:00Z`), dataset.knownBy);
|
|
5344
|
+
}
|
|
5345
|
+
const next = /* @__PURE__ */ new Date(`${day}T00:00:00Z`);
|
|
5346
|
+
next.setUTCDate(next.getUTCDate() + 1);
|
|
5347
|
+
return combineDateAndTime(next, "00:00");
|
|
5348
|
+
}
|
|
5349
|
+
var availabilityIndexes = /* @__PURE__ */ new WeakMap();
|
|
5350
|
+
function resolveDatasetColumnAtTime(dataset, rows, column, entryTime) {
|
|
5351
|
+
if (!dataset.columns.includes(column)) throw new Error(`Unknown dataset column: ${column}`);
|
|
5352
|
+
let rowIndexes = availabilityIndexes.get(dataset);
|
|
5353
|
+
if (!rowIndexes) {
|
|
5354
|
+
rowIndexes = /* @__PURE__ */ new WeakMap();
|
|
5355
|
+
availabilityIndexes.set(dataset, rowIndexes);
|
|
5356
|
+
}
|
|
5357
|
+
let columns = rowIndexes.get(rows);
|
|
5358
|
+
if (!columns) {
|
|
5359
|
+
columns = /* @__PURE__ */ new Map();
|
|
5360
|
+
rowIndexes.set(rows, columns);
|
|
5361
|
+
}
|
|
5362
|
+
let index = columns.get(column);
|
|
5363
|
+
if (!index) {
|
|
5364
|
+
index = rows.filter((row) => {
|
|
5365
|
+
const value = row.values[column];
|
|
5366
|
+
return value !== void 0 && value !== null && (typeof value !== "string" || value.trim() !== "");
|
|
5367
|
+
}).map((row) => ({
|
|
5368
|
+
row,
|
|
5369
|
+
time: getDatasetValueAvailableAt(dataset, row, column).getTime()
|
|
5370
|
+
})).sort((a, b) => a.time - b.time);
|
|
5371
|
+
columns.set(column, index);
|
|
5372
|
+
}
|
|
5373
|
+
let left = 0;
|
|
5374
|
+
let right = index.length;
|
|
5375
|
+
const time = entryTime.getTime();
|
|
5376
|
+
while (left < right) {
|
|
5377
|
+
const mid = Math.floor((left + right) / 2);
|
|
5378
|
+
if (index[mid].time <= time) left = mid + 1;
|
|
5379
|
+
else right = mid;
|
|
5380
|
+
}
|
|
5381
|
+
if (!left) return null;
|
|
5382
|
+
const match = index[left - 1];
|
|
5383
|
+
return { value: match.row.values[column], row: match.row, availableAt: new Date(match.time) };
|
|
5384
|
+
}
|
|
5385
|
+
function combineDateAndTime(dateOpened, timeOpened) {
|
|
5386
|
+
const d = new Date(dateOpened);
|
|
5387
|
+
const isUtcMidnight = d.getUTCHours() === 0 && d.getUTCMinutes() === 0 && d.getUTCSeconds() === 0 && d.getUTCMilliseconds() === 0;
|
|
5388
|
+
let year;
|
|
5389
|
+
let month;
|
|
5390
|
+
let day;
|
|
5391
|
+
if (isUtcMidnight) {
|
|
5392
|
+
year = d.getUTCFullYear();
|
|
5393
|
+
month = d.getUTCMonth();
|
|
5394
|
+
day = d.getUTCDate();
|
|
5395
|
+
} else {
|
|
5396
|
+
year = d.getFullYear();
|
|
5397
|
+
month = d.getMonth();
|
|
5398
|
+
day = d.getDate();
|
|
5399
|
+
}
|
|
5400
|
+
let hours = 0;
|
|
5401
|
+
let minutes = 0;
|
|
5402
|
+
let seconds = 0;
|
|
5403
|
+
const timeParts = timeOpened.split(":");
|
|
5404
|
+
if (timeParts.length >= 2) {
|
|
5405
|
+
hours = parseInt(timeParts[0], 10) || 0;
|
|
5406
|
+
minutes = parseInt(timeParts[1], 10) || 0;
|
|
5407
|
+
seconds = timeParts.length > 2 ? parseInt(timeParts[2], 10) || 0 : 0;
|
|
5408
|
+
}
|
|
5409
|
+
const utcDate = Date.UTC(year, month, day, hours, minutes, seconds, 0);
|
|
5410
|
+
const testDate = new Date(utcDate);
|
|
5411
|
+
const etOffset = getEasternTimeOffset(testDate);
|
|
5412
|
+
return new Date(utcDate - etOffset * 60 * 1e3);
|
|
5413
|
+
}
|
|
5414
|
+
function getEasternTimeOffset(date) {
|
|
5415
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
5416
|
+
timeZone: "America/New_York",
|
|
5417
|
+
timeZoneName: "shortOffset"
|
|
5418
|
+
});
|
|
5419
|
+
const parts = formatter.formatToParts(date);
|
|
5420
|
+
const tzPart = parts.find((p) => p.type === "timeZoneName");
|
|
5421
|
+
if (tzPart) {
|
|
5422
|
+
const match = tzPart.value.match(/GMT([+-]\d+)/);
|
|
5423
|
+
if (match) {
|
|
5424
|
+
return parseInt(match[1], 10) * 60;
|
|
5425
|
+
}
|
|
5426
|
+
}
|
|
5427
|
+
return -300;
|
|
5428
|
+
}
|
|
5429
|
+
function getDateOnly(date) {
|
|
5430
|
+
const formatter = new Intl.DateTimeFormat("en-CA", {
|
|
5431
|
+
timeZone: "America/New_York",
|
|
5432
|
+
year: "numeric",
|
|
5433
|
+
month: "2-digit",
|
|
5434
|
+
day: "2-digit"
|
|
5435
|
+
});
|
|
5436
|
+
return formatter.format(date);
|
|
5437
|
+
}
|
|
5438
|
+
|
|
5330
5439
|
// ../lib/db/index.ts
|
|
5331
5440
|
var DB_NAME = "TradeBlocksDB";
|
|
5332
5441
|
var DB_VERSION = 7;
|
|
@@ -5805,6 +5914,8 @@ export {
|
|
|
5805
5914
|
getNetPl,
|
|
5806
5915
|
rebuildEquityCurve,
|
|
5807
5916
|
formatDateKey,
|
|
5917
|
+
resolveDatasetColumnAtTime,
|
|
5918
|
+
combineDateAndTime,
|
|
5808
5919
|
REPORTING_TRADE_COLUMN_ALIASES,
|
|
5809
5920
|
addDailyLogEntries,
|
|
5810
5921
|
getDailyLogsByBlock,
|
|
@@ -5830,4 +5941,4 @@ export {
|
|
|
5830
5941
|
searchTrades,
|
|
5831
5942
|
getTradesPage
|
|
5832
5943
|
};
|
|
5833
|
-
//# sourceMappingURL=chunk-
|
|
5944
|
+
//# sourceMappingURL=chunk-4UU7IT2A.js.map
|