@tradejs/node 3.1.29-beta.261 → 3.1.29-beta.263
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/dist/backtest.js +189 -75
- package/dist/backtest.mjs +3 -3
- package/dist/{chunk-ZZQLTUTP.mjs → chunk-GHSLOJLE.mjs} +195 -69
- package/dist/chunk-JQOLTLEY.mjs +0 -0
- package/dist/{chunk-WGL7XJ3W.mjs → chunk-SKY2HNZU.mjs} +1 -1
- package/dist/{chunk-3BBXGZ7M.mjs → chunk-YR55Q355.mjs} +11 -11
- package/dist/chunk-ZUMUI37V.mjs +0 -0
- package/dist/connectors.mjs +1 -0
- package/dist/diagnostics.d.mts +182 -0
- package/dist/diagnostics.d.ts +182 -0
- package/dist/diagnostics.js +9060 -0
- package/dist/diagnostics.mjs +867 -0
- package/dist/jev.d.mts +64 -69
- package/dist/jev.d.ts +64 -69
- package/dist/jev.js +193 -75
- package/dist/jev.mjs +6 -2
- package/dist/{jevTraining-JYXUVAZG.mjs → jevTraining-J4Y4VCM4.mjs} +1 -1
- package/dist/mcp.d.mts +203 -0
- package/dist/mcp.d.ts +203 -0
- package/dist/mcp.js +9257 -0
- package/dist/mcp.mjs +584 -0
- package/dist/registry.js +189 -75
- package/dist/registry.mjs +4 -3
- package/dist/runtimeDashboard.js +189 -75
- package/dist/runtimeDashboard.mjs +7 -7
- package/dist/runtimeStrategies.js +189 -75
- package/dist/runtimeStrategies.mjs +3 -3
- package/dist/strategies.js +189 -75
- package/dist/strategies.mjs +3 -3
- package/package.json +17 -6
|
@@ -36,7 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
|
|
38
38
|
// src/jevInput.ts
|
|
39
|
-
var import_data, import_jev, object, at, finite, fact, buildJevInput,
|
|
39
|
+
var import_data, import_jev, object, at, finite, fact, buildJevInput, JEV_COMPONENT_QUESTIONS, JEV_SIGNAL_STRENGTH_QUESTION, JEV_QUESTIONS, questionsForJevInput, groupJevFields, stateForJevInput;
|
|
40
40
|
var init_jevInput = __esm({
|
|
41
41
|
"src/jevInput.ts"() {
|
|
42
42
|
"use strict";
|
|
@@ -120,6 +120,35 @@ var init_jevInput = __esm({
|
|
|
120
120
|
const stop = finite(signal.prices.stopLossPrice);
|
|
121
121
|
const target = finite(signal.prices.takeProfitPrice);
|
|
122
122
|
const atr = baseProblem ? null : finite(at(base, "raw", "volatility", "atr"));
|
|
123
|
+
if (!baseProblem) {
|
|
124
|
+
const open = finite(at(base, "candle", "open"));
|
|
125
|
+
const close = finite(at(base, "candle", "close"));
|
|
126
|
+
const high = finite(at(base, "candle", "high"));
|
|
127
|
+
const low = finite(at(base, "candle", "low"));
|
|
128
|
+
const sign = signal.direction === "LONG" ? 1 : -1;
|
|
129
|
+
const candleFact = {
|
|
130
|
+
knownAt: baseKnownAt,
|
|
131
|
+
scope: "target",
|
|
132
|
+
source: "baseContext.candle"
|
|
133
|
+
};
|
|
134
|
+
if (open != null && close != null && atr != null && atr > 0)
|
|
135
|
+
put("entry.directionalBodyAtr", sign * (close - open) / atr, {
|
|
136
|
+
...candleFact,
|
|
137
|
+
unit: "ATR"
|
|
138
|
+
});
|
|
139
|
+
if (high != null && low != null && close != null && high > low && close >= low && close <= high) {
|
|
140
|
+
put(
|
|
141
|
+
"entry.directionalCloseLocation",
|
|
142
|
+
signal.direction === "LONG" ? (close - low) / (high - low) : (high - close) / (high - low),
|
|
143
|
+
{ ...candleFact, unit: "ratio" }
|
|
144
|
+
);
|
|
145
|
+
if (atr != null && atr > 0)
|
|
146
|
+
put("entry.rangeAtr", (high - low) / atr, {
|
|
147
|
+
...candleFact,
|
|
148
|
+
unit: "ATR"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
123
152
|
if (price == null || stop == null || target == null)
|
|
124
153
|
throw new Error("Invalid Jev signal prices");
|
|
125
154
|
put(
|
|
@@ -206,33 +235,30 @@ var init_jevInput = __esm({
|
|
|
206
235
|
);
|
|
207
236
|
const questions = import_jev.JEV_DIMENSIONS.filter((dimension) => {
|
|
208
237
|
switch (dimension) {
|
|
238
|
+
case "signalStrength":
|
|
239
|
+
return has("signal.validLevels");
|
|
209
240
|
case "trend":
|
|
210
241
|
return has("market.trendBias");
|
|
211
242
|
case "swing":
|
|
212
|
-
return has("
|
|
243
|
+
return has("setup.retracementRatio");
|
|
213
244
|
case "participation":
|
|
214
|
-
return has("market.volumeRel20")
|
|
245
|
+
return has("market.volumeRel20");
|
|
215
246
|
case "setupParticipation":
|
|
216
247
|
return setupKeys.some(
|
|
217
248
|
(key) => /volume|delta|flow|liquidity|turnover/i.test(key)
|
|
218
249
|
);
|
|
219
250
|
case "extension":
|
|
220
|
-
return has("
|
|
251
|
+
return has("setup.breakoutDistanceAtr");
|
|
221
252
|
case "confirmation":
|
|
222
|
-
return
|
|
223
|
-
(key) => /stage|confirm|retest|accept/i.test(key)
|
|
224
|
-
);
|
|
253
|
+
return has("entry.directionalBodyAtr") && has("entry.directionalCloseLocation");
|
|
225
254
|
case "setupStrength":
|
|
226
|
-
return setupKeys.some(
|
|
227
|
-
(key) => key !== "setup.version" && !/volume|delta|flow|liquidity|turnover|stage|confirm|retest|accept|breakoutDistance/i.test(
|
|
228
|
-
key
|
|
229
|
-
)
|
|
230
|
-
);
|
|
255
|
+
return setupKeys.some((key) => /efficiencyRatio$/i.test(key));
|
|
231
256
|
case "geometry":
|
|
232
257
|
return geometryStatus !== "invalid" && Object.keys(features).some((key) => key.startsWith("geometry."));
|
|
233
258
|
}
|
|
234
259
|
});
|
|
235
260
|
return {
|
|
261
|
+
questionSet: import_jev.JEV_QUESTION_SET,
|
|
236
262
|
schema: "tradejs-jev-input/v4",
|
|
237
263
|
strategy: signal.strategy,
|
|
238
264
|
symbol: signal.symbol,
|
|
@@ -246,68 +272,155 @@ var init_jevInput = __esm({
|
|
|
246
272
|
geometryStatus
|
|
247
273
|
};
|
|
248
274
|
};
|
|
249
|
-
|
|
250
|
-
`${subject} is clearly contradicted by the supplied facts.`,
|
|
251
|
-
`${subject} has a material conflict.`,
|
|
252
|
-
`${subject} is uncertain from the supplied facts.`,
|
|
253
|
-
`${subject} has adequate support.`,
|
|
254
|
-
`${subject} has strong support without a material conflict.`
|
|
255
|
-
];
|
|
256
|
-
JEV_QUESTIONS = {
|
|
275
|
+
JEV_COMPONENT_QUESTIONS = {
|
|
257
276
|
trend: {
|
|
258
277
|
type: "score",
|
|
259
|
-
instructions: "
|
|
260
|
-
criteria:
|
|
278
|
+
instructions: "Rate agreement of market.trendBias and market.swingBias with signal.direction: bull supports LONG, bear supports SHORT; neutral/unknown is inconclusive. No profit prediction.",
|
|
279
|
+
criteria: [
|
|
280
|
+
"Both oppose.",
|
|
281
|
+
"One opposes; other inconclusive.",
|
|
282
|
+
"Biases conflict, or both inconclusive.",
|
|
283
|
+
"One supports; other inconclusive.",
|
|
284
|
+
"Both support."
|
|
285
|
+
]
|
|
261
286
|
},
|
|
262
287
|
swing: {
|
|
263
288
|
type: "score",
|
|
264
|
-
instructions: "
|
|
265
|
-
criteria:
|
|
289
|
+
instructions: "Rate shallow correction using only setup.retracementRatio (correction / preceding impulse). Missing is inconclusive, not favorable.",
|
|
290
|
+
criteria: [
|
|
291
|
+
"Exceeds impulse (>1).",
|
|
292
|
+
"Deep (>0.65 to 1).",
|
|
293
|
+
"Moderate (>0.4 to 0.65), or missing.",
|
|
294
|
+
"Contained (>0.2 to 0.4).",
|
|
295
|
+
"Shallow (0 to 0.2)."
|
|
296
|
+
]
|
|
266
297
|
},
|
|
267
298
|
participation: {
|
|
268
299
|
type: "score",
|
|
269
|
-
instructions: "
|
|
270
|
-
criteria:
|
|
300
|
+
instructions: "Rate activity using only market.volumeRel20 (candle volume / trailing 20-candle mean). Not directional flow; ignore setup volume.",
|
|
301
|
+
criteria: [
|
|
302
|
+
"Very low (<0.5).",
|
|
303
|
+
"Below ordinary (0.5 to <0.8).",
|
|
304
|
+
"Ordinary (0.8 to <1.2), or missing.",
|
|
305
|
+
"Elevated (1.2 to <2).",
|
|
306
|
+
"Strong expansion (>=2)."
|
|
307
|
+
]
|
|
271
308
|
},
|
|
272
309
|
setupParticipation: {
|
|
273
310
|
type: "score",
|
|
274
|
-
instructions: "
|
|
275
|
-
criteria:
|
|
311
|
+
instructions: "Rate consolidation volume contraction using a supplied setup consolidation / preceding impulse volume ratio, e.g. setup.flagToPoleVolumeRatio. Smaller means stronger contraction. Ignore current volume and directional flow; unrelated setup semantics are inconclusive.",
|
|
312
|
+
criteria: [
|
|
313
|
+
"Exceeds impulse (>1.2).",
|
|
314
|
+
"No contraction (>0.9 to 1.2).",
|
|
315
|
+
"Mild (>0.7 to 0.9), or inconclusive.",
|
|
316
|
+
"Clear (>0.4 to 0.7).",
|
|
317
|
+
"Strong (0 to 0.4)."
|
|
318
|
+
]
|
|
276
319
|
},
|
|
277
320
|
extension: {
|
|
278
321
|
type: "score",
|
|
279
|
-
instructions: "
|
|
280
|
-
criteria:
|
|
322
|
+
instructions: "Rate absence of entry extension using only setup.breakoutDistanceAtr (distance past setup boundary in ATR). Stop/target distances are not extension.",
|
|
323
|
+
criteria: [
|
|
324
|
+
"Extreme (>2 ATR).",
|
|
325
|
+
"Large (>1 to 2 ATR).",
|
|
326
|
+
"Moderate (>0.5 to 1 ATR), or missing.",
|
|
327
|
+
"Small (>0.2 to 0.5 ATR).",
|
|
328
|
+
"Near boundary (0 to 0.2 ATR)."
|
|
329
|
+
]
|
|
281
330
|
},
|
|
282
331
|
confirmation: {
|
|
283
332
|
type: "score",
|
|
284
|
-
instructions: "
|
|
285
|
-
criteria:
|
|
333
|
+
instructions: "Rate closed entry candle conviction using entry.directionalBodyAtr (signed toward signal.direction) and entry.directionalCloseLocation (1=favorable extreme). Stage names alone prove neither conviction nor breakout retention.",
|
|
334
|
+
criteria: [
|
|
335
|
+
"Opposing body AND unfavorable-quarter close.",
|
|
336
|
+
"Opposing body OR unfavorable-half close.",
|
|
337
|
+
"Small body (<0.2 ATR), mixed or missing evidence.",
|
|
338
|
+
"Supporting body (>=0.2 ATR) AND favorable-half close.",
|
|
339
|
+
"Strong supporting body (>=0.5 ATR) AND favorable-quarter close."
|
|
340
|
+
]
|
|
286
341
|
},
|
|
287
342
|
setupStrength: {
|
|
288
343
|
type: "score",
|
|
289
|
-
instructions: "
|
|
290
|
-
criteria:
|
|
344
|
+
instructions: "Rate impulse persistence using only supplied setup efficiency (absolute net move / sum of absolute bar moves), e.g. setup.poleEfficiencyRatio. Exclude size, volume, correction and geometry.",
|
|
345
|
+
criteria: [
|
|
346
|
+
"Highly choppy (<0.2).",
|
|
347
|
+
"Weak (0.2 to <0.4).",
|
|
348
|
+
"Mixed (0.4 to <0.6), or missing.",
|
|
349
|
+
"Clear (0.6 to <0.8).",
|
|
350
|
+
"Highly persistent (0.8 to 1)."
|
|
351
|
+
]
|
|
291
352
|
},
|
|
292
353
|
geometry: {
|
|
293
354
|
type: "score",
|
|
294
|
-
instructions: "
|
|
295
|
-
criteria:
|
|
355
|
+
instructions: "Rate fitted consolidation boundaries jointly: geometry.upperR2 and lowerR2 (1=best fit), slopeDivergenceRatio (0=parallel). Use the weaker fit; exclude depth, width, volume and profit. Missing equivalent geometry is inconclusive.",
|
|
356
|
+
criteria: [
|
|
357
|
+
"Fit <0.5 OR divergence >0.5.",
|
|
358
|
+
"Fit <0.7 OR divergence >0.3.",
|
|
359
|
+
"Fit <0.85 OR divergence >0.15, or missing.",
|
|
360
|
+
"Both fits >=0.85 AND divergence <=0.15.",
|
|
361
|
+
"Both fits >=0.95 AND divergence <=0.05."
|
|
362
|
+
]
|
|
296
363
|
}
|
|
297
364
|
};
|
|
298
|
-
|
|
365
|
+
JEV_SIGNAL_STRENGTH_QUESTION = {
|
|
366
|
+
type: "score",
|
|
367
|
+
instructions: "Rate overall support for entry now from signal-time facts: direction, market, setup, candle, placement, relevant geometry and stop/target plan. No other Jev answers, future prices or outcomes. Essential missing facts and conflicts weaken support; optional missing geometry alone does not disqualify. Invalid signal.validLevels cannot rate strong. Not win probability or execution permission. Criteria 1\u201310 map to API indices 0\u20139.",
|
|
368
|
+
criteria: [
|
|
369
|
+
"1: Invalid levels or decisive contrary evidence.",
|
|
370
|
+
"2: Severe directional/setup conflicts; poor support.",
|
|
371
|
+
"3: Substantial weaknesses outweigh support.",
|
|
372
|
+
"4: Some support; material weakness makes entry unattractive.",
|
|
373
|
+
"5: Balanced conflicts or essential evidence missing.",
|
|
374
|
+
"6: Modest coherent support; reasonable but limited evidence.",
|
|
375
|
+
"7: Convincing support from several facts; remaining weakness.",
|
|
376
|
+
"8: Strong coherent support, suitable placement/plan; no material conflict.",
|
|
377
|
+
"9: Very strong independent support; well-defined entry/stop/target plan.",
|
|
378
|
+
"10: Exceptional coherent support and plan; no visible material weakness, profit uncertain."
|
|
379
|
+
]
|
|
380
|
+
};
|
|
381
|
+
JEV_QUESTIONS = {
|
|
382
|
+
...JEV_COMPONENT_QUESTIONS,
|
|
383
|
+
signalStrength: JEV_SIGNAL_STRENGTH_QUESTION
|
|
384
|
+
};
|
|
385
|
+
questionsForJevInput = (input) => {
|
|
386
|
+
if (input.questionSet !== import_jev.JEV_QUESTION_SET)
|
|
387
|
+
throw new Error(
|
|
388
|
+
"Unsupported Jev recording question set; rerun the backtest with --jev"
|
|
389
|
+
);
|
|
390
|
+
return Object.fromEntries(
|
|
391
|
+
input.questions.map((key) => {
|
|
392
|
+
const question = JEV_QUESTIONS[key];
|
|
393
|
+
if (!question) throw new Error("Unknown Jev question");
|
|
394
|
+
return [key, question];
|
|
395
|
+
})
|
|
396
|
+
);
|
|
397
|
+
};
|
|
398
|
+
groupJevFields = (entries) => {
|
|
399
|
+
const groups = /* @__PURE__ */ new Map();
|
|
400
|
+
const flat = [];
|
|
401
|
+
for (const [key, value] of entries) {
|
|
402
|
+
const separator = key.indexOf(".");
|
|
403
|
+
if (separator < 0) {
|
|
404
|
+
flat.push([key, value]);
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const namespace = key.slice(0, separator);
|
|
408
|
+
const group = groups.get(namespace) ?? [];
|
|
409
|
+
group.push([key.slice(separator + 1), value]);
|
|
410
|
+
groups.set(namespace, group);
|
|
411
|
+
}
|
|
412
|
+
return Object.fromEntries([
|
|
413
|
+
...flat,
|
|
414
|
+
...Array.from(groups, ([key, fields]) => [key, Object.fromEntries(fields)])
|
|
415
|
+
]);
|
|
416
|
+
};
|
|
299
417
|
stateForJevInput = (input) => ({
|
|
300
|
-
schema: input.schema,
|
|
301
418
|
strategy: input.strategy,
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
missing: input.missing,
|
|
419
|
+
facts: groupJevFields(Object.entries(input.features)),
|
|
420
|
+
missing: groupJevFields(Object.entries(input.missing)),
|
|
305
421
|
geometryStatus: input.geometryStatus,
|
|
306
|
-
units:
|
|
422
|
+
units: groupJevFields(
|
|
307
423
|
Object.entries(input.provenance).filter(([, detail]) => detail.unit != null).map(([key, detail]) => [key, detail.unit])
|
|
308
|
-
),
|
|
309
|
-
sources: Object.fromEntries(
|
|
310
|
-
Object.entries(input.provenance).filter(([, detail]) => detail.source != null).map(([key, detail]) => [key, detail.source])
|
|
311
424
|
)
|
|
312
425
|
});
|
|
313
426
|
}
|
|
@@ -341,7 +454,7 @@ var init_jevTraining = __esm({
|
|
|
341
454
|
);
|
|
342
455
|
for (const row of rows) {
|
|
343
456
|
const record = row?.record;
|
|
344
|
-
if (row?.schema !== "tradejs-jev-study/v4" || !row.signalId || record?.schema !== "tradejs-jev-record/v4" || record.input?.schema !== "tradejs-jev-input/v4" || !Number.isFinite(record.input.timestamp) || record.inputHash !== (0, import_jev3.jevHash)(record.input) || record.questionsHash !== (0, import_jev3.jevHash)(questionsForJevInput(record.input)) || record.id !== (0, import_jev3.jevHash)({
|
|
457
|
+
if (row?.schema !== "tradejs-jev-study/v4" || !row.signalId || record?.schema !== "tradejs-jev-record/v4" || record.input?.schema !== "tradejs-jev-input/v4" || record.input.questionSet !== import_jev2.JEV_QUESTION_SET || !Number.isFinite(record.input.timestamp) || record.inputHash !== (0, import_jev3.jevHash)(record.input) || record.questionsHash !== (0, import_jev3.jevHash)(questionsForJevInput(record.input)) || record.id !== (0, import_jev3.jevHash)({
|
|
345
458
|
inputHash: record.inputHash,
|
|
346
459
|
questionsHash: record.questionsHash,
|
|
347
460
|
provider: record.provider
|
|
@@ -349,7 +462,7 @@ var init_jevTraining = __esm({
|
|
|
349
462
|
throw new Error("Invalid Jev study provenance");
|
|
350
463
|
(0, import_jev3.validateJevResponse)(record.response, record.input.questions);
|
|
351
464
|
for (const dimension of import_jev2.JEV_DIMENSIONS) {
|
|
352
|
-
const expected = record.input.questions.includes(dimension) ? record.response.answers[dimension].score /
|
|
465
|
+
const expected = record.input.questions.includes(dimension) ? record.response.answers[dimension].score / (0, import_jev3.jevScoreMaximum)(dimension) : null;
|
|
353
466
|
if (record.scores[dimension] !== expected)
|
|
354
467
|
throw new Error("Jev study scores do not match the teacher response");
|
|
355
468
|
}
|
|
@@ -432,10 +545,12 @@ var init_jevTraining = __esm({
|
|
|
432
545
|
};
|
|
433
546
|
validateJevGateModel = (value) => {
|
|
434
547
|
const model = value;
|
|
435
|
-
if (model?.schema !== "tradejs-jev-gate/v2" || model.inputSchema !== "tradejs-jev-input/v4" || typeof model.strategy !== "string" || !model.strategy || !model.teacherModel || !model.trees || model.
|
|
548
|
+
if (model?.schema !== "tradejs-jev-gate/v2" || model.inputSchema !== "tradejs-jev-input/v4" || typeof model.strategy !== "string" || !model.strategy || !model.teacherModel || !model.trees || model.questionSet !== import_jev2.JEV_QUESTION_SET || import_jev2.JEV_DIMENSIONS.some((dimension) => !(dimension in model.trees)) || Object.keys(model.trees).some(
|
|
549
|
+
(dimension) => !import_jev2.JEV_DIMENSIONS.includes(dimension)
|
|
550
|
+
) || model.questionsHash !== (0, import_jev3.jevHash)(JEV_QUESTIONS) || !model.training || !/^[a-f0-9]{64}$/.test(model.training.datasetHash))
|
|
436
551
|
throw new Error("Invalid local Jev gate");
|
|
437
552
|
const { trainEnd, validationEnd, testEnd } = model.training;
|
|
438
|
-
if (![trainEnd, validationEnd, testEnd].every(Number.isFinite) || !(trainEnd
|
|
553
|
+
if (![trainEnd, validationEnd, testEnd].every(Number.isFinite) || model.training.split !== "outer-60-40" || !(trainEnd === validationEnd && trainEnd < testEnd))
|
|
439
554
|
throw new Error("Invalid local Jev gate partitions");
|
|
440
555
|
const check = (tree, depth) => {
|
|
441
556
|
if (!tree || depth > 8) throw new Error("Invalid local Jev tree");
|
|
@@ -571,13 +686,10 @@ var init_jevTraining = __esm({
|
|
|
571
686
|
];
|
|
572
687
|
if (rows.length < 30 || timestamps.length < 10)
|
|
573
688
|
throw new Error("Need at least 30 distinct samples across 10 signal times");
|
|
574
|
-
const trainEnd = timestamps[Math.floor(timestamps.length * 0.
|
|
575
|
-
const validationEnd =
|
|
689
|
+
const trainEnd = timestamps[timestamps.length - Math.max(1, Math.floor(timestamps.length * 0.4)) - 1];
|
|
690
|
+
const validationEnd = trainEnd;
|
|
576
691
|
const train = rows.filter((row) => row.record.input.timestamp <= trainEnd);
|
|
577
|
-
const
|
|
578
|
-
(row) => row.record.input.timestamp > trainEnd && row.record.input.timestamp <= validationEnd
|
|
579
|
-
);
|
|
580
|
-
const test = rows.filter((row) => row.record.input.timestamp > validationEnd);
|
|
692
|
+
const test = rows.filter((row) => row.record.input.timestamp > trainEnd);
|
|
581
693
|
const fit = (samples) => Object.fromEntries(
|
|
582
694
|
import_jev2.JEV_DIMENSIONS.map((key) => {
|
|
583
695
|
const eligible = samples.filter(
|
|
@@ -594,10 +706,12 @@ var init_jevTraining = __esm({
|
|
|
594
706
|
schema: "tradejs-jev-gate/v2",
|
|
595
707
|
inputSchema: "tradejs-jev-input/v4",
|
|
596
708
|
strategy: first.input.strategy,
|
|
709
|
+
questionSet: import_jev2.JEV_QUESTION_SET,
|
|
597
710
|
questionsHash: (0, import_jev3.jevHash)(JEV_QUESTIONS),
|
|
598
711
|
teacherModel: first.response.model,
|
|
599
712
|
trees: fit(train),
|
|
600
713
|
training: {
|
|
714
|
+
split: "outer-60-40",
|
|
601
715
|
datasetHash: (0, import_jev3.jevHash)(
|
|
602
716
|
rows.map((row) => ({
|
|
603
717
|
id: row.record.id,
|
|
@@ -612,18 +726,20 @@ var init_jevTraining = __esm({
|
|
|
612
726
|
}
|
|
613
727
|
};
|
|
614
728
|
validateJevGateModel(model);
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
729
|
+
const developmentTimes = timestamps.filter(
|
|
730
|
+
(timestamp) => timestamp <= trainEnd
|
|
731
|
+
);
|
|
732
|
+
const walkForward = [0.25, 0.5, 0.75].map((fraction) => {
|
|
733
|
+
const trainThrough = developmentTimes[Math.max(0, Math.floor(developmentTimes.length * fraction) - 1)];
|
|
734
|
+
const testThrough = developmentTimes[Math.min(
|
|
735
|
+
developmentTimes.length - 1,
|
|
736
|
+
Math.floor(developmentTimes.length * (fraction + 0.25)) - 1
|
|
621
737
|
)];
|
|
622
|
-
const fitting =
|
|
738
|
+
const fitting = train.filter(
|
|
623
739
|
(row) => row.record.input.timestamp <= trainThrough
|
|
624
740
|
);
|
|
625
|
-
const evaluation =
|
|
626
|
-
(row) => row.record.input.timestamp >
|
|
741
|
+
const evaluation = train.filter(
|
|
742
|
+
(row) => row.record.input.timestamp > trainThrough && row.record.input.timestamp <= testThrough
|
|
627
743
|
);
|
|
628
744
|
const fold = {
|
|
629
745
|
...model,
|
|
@@ -631,13 +747,13 @@ var init_jevTraining = __esm({
|
|
|
631
747
|
training: {
|
|
632
748
|
...model.training,
|
|
633
749
|
trainEnd: trainThrough,
|
|
634
|
-
validationEnd:
|
|
750
|
+
validationEnd: trainThrough,
|
|
635
751
|
testEnd: testThrough
|
|
636
752
|
}
|
|
637
753
|
};
|
|
638
754
|
return {
|
|
639
755
|
trainThrough,
|
|
640
|
-
validationThrough,
|
|
756
|
+
validationThrough: trainThrough,
|
|
641
757
|
testThrough,
|
|
642
758
|
trainRows: fitting.length,
|
|
643
759
|
test: compareJevGate(fold, evaluation)
|
|
@@ -647,7 +763,8 @@ var init_jevTraining = __esm({
|
|
|
647
763
|
model,
|
|
648
764
|
report: {
|
|
649
765
|
train: compareJevGate(model, train),
|
|
650
|
-
|
|
766
|
+
partitionScheme: "outer-60-40",
|
|
767
|
+
stabilityRole: "independently fitted folds inside development only",
|
|
651
768
|
test: compareJevGate(model, test),
|
|
652
769
|
walkForward,
|
|
653
770
|
promotion: "research-only; validate a sequential backtest and prospective signals before runtime admission"
|
|
@@ -715,6 +832,7 @@ var evaluateJevInput = async ({
|
|
|
715
832
|
const questions = questionsForJevInput(input);
|
|
716
833
|
const questionsHash = (0, import_jev5.jevHash)(questions);
|
|
717
834
|
const base = {
|
|
835
|
+
questionSet: import_jev4.JEV_QUESTION_SET,
|
|
718
836
|
schema: "tradejs-signal-assessment/v5",
|
|
719
837
|
source: config.source,
|
|
720
838
|
mode: config.mode,
|
|
@@ -771,7 +889,7 @@ var evaluateJevInput = async ({
|
|
|
771
889
|
throw new Error("Jev recording identity mismatch");
|
|
772
890
|
(0, import_jev5.validateJevResponse)(existing.response, input.questions);
|
|
773
891
|
for (const key of import_jev4.JEV_DIMENSIONS) {
|
|
774
|
-
const expected = input.questions.includes(key) ? existing.response.answers[key].score /
|
|
892
|
+
const expected = input.questions.includes(key) ? existing.response.answers[key].score / (0, import_jev5.jevScoreMaximum)(key) : null;
|
|
775
893
|
if (existing.scores[key] !== expected)
|
|
776
894
|
throw new Error("Jev recording scores do not match the response");
|
|
777
895
|
}
|
|
@@ -819,7 +937,7 @@ var evaluateJevInput = async ({
|
|
|
819
937
|
const scores = Object.fromEntries(
|
|
820
938
|
import_jev4.JEV_DIMENSIONS.map((key) => [
|
|
821
939
|
key,
|
|
822
|
-
input.questions.includes(key) ? response.answers[key].score /
|
|
940
|
+
input.questions.includes(key) ? response.answers[key].score / (0, import_jev5.jevScoreMaximum)(key) : null
|
|
823
941
|
])
|
|
824
942
|
);
|
|
825
943
|
const value = {
|
|
@@ -886,6 +1004,7 @@ var assessSignalWithJev = async ({
|
|
|
886
1004
|
} catch (error) {
|
|
887
1005
|
if (strict) throw error;
|
|
888
1006
|
assessment = {
|
|
1007
|
+
questionSet: import_jev4.JEV_QUESTION_SET,
|
|
889
1008
|
schema: "tradejs-signal-assessment/v5",
|
|
890
1009
|
source: config.source,
|
|
891
1010
|
mode: config.mode,
|
|
@@ -902,12 +1021,7 @@ var assessSignalWithJev = async ({
|
|
|
902
1021
|
signal.assessment = assessment;
|
|
903
1022
|
signal.additionalIndicators = {
|
|
904
1023
|
...signal.additionalIndicators,
|
|
905
|
-
jev:
|
|
906
|
-
schema: "tradejs-jev-features/v2",
|
|
907
|
-
status: assessment.status,
|
|
908
|
-
scores: assessment.scores,
|
|
909
|
-
confidence: assessment.confidence
|
|
910
|
-
}
|
|
1024
|
+
jev: (0, import_jev4.jevAssessmentFeatures)(assessment)
|
|
911
1025
|
};
|
|
912
1026
|
const identity = {
|
|
913
1027
|
signalId: signal.signalId,
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
resolveRuntimeComposition,
|
|
10
10
|
verifyRuntimeDeclaration
|
|
11
11
|
} from "./chunk-BO42QWAB.mjs";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-SKY2HNZU.mjs";
|
|
13
13
|
import "./chunk-UL5Z46JL.mjs";
|
|
14
14
|
import "./chunk-LZDXRXIU.mjs";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-YR55Q355.mjs";
|
|
16
|
+
import "./chunk-GHSLOJLE.mjs";
|
|
17
17
|
import "./chunk-Y6FXYEAI.mjs";
|
|
18
18
|
export {
|
|
19
19
|
RUNTIME_PACKAGE_MANIFEST_SCHEMA,
|