@tradejs/cli 2.0.0 → 2.0.2
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/cli.js +384 -122
- package/dist/lib/aiTrainCharts.js +49 -2
- package/dist/lib/aiTrainMetrics.js +49 -2
- package/dist/lib/aiTrainResearch.js +58 -4
- package/dist/lib/derivativesContextBackfill.js +262 -107
- package/dist/lib/marketContextPrepare.js +256 -107
- package/dist/scripts/aiPocketSearch.js +49 -2
- package/dist/scripts/aiTrain.js +76 -4
- package/dist/scripts/backtest.js +256 -107
- package/dist/scripts/derivativesIngest.js +11 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +38 -4
- package/dist/scripts/replay.js +256 -107
- package/dist/scripts/replayRunner.js +256 -107
- package/dist/scripts/runtimeParity.js +256 -107
- package/dist/scripts/signals.js +256 -107
- package/dist/scripts/signalsDaemon.js +256 -107
- package/package.json +9 -9
|
@@ -34,6 +34,7 @@ var divideOrNull = (num, denom) => {
|
|
|
34
34
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
35
35
|
var DAYS_PER_WEEK = 7;
|
|
36
36
|
var DAYS_PER_MONTH = 30.4375;
|
|
37
|
+
var DAYS_PER_YEAR = 365;
|
|
37
38
|
var getEvaluationPeriodDays = (evaluations) => {
|
|
38
39
|
let minTimestamp = null;
|
|
39
40
|
let maxTimestamp = null;
|
|
@@ -55,6 +56,40 @@ var getEvaluationPeriodDays = (evaluations) => {
|
|
|
55
56
|
return Math.max((maxTimestamp - minTimestamp) / DAY_MS, 1);
|
|
56
57
|
};
|
|
57
58
|
var qualitySortKey = (quality) => quality == null ? Number.POSITIVE_INFINITY : quality;
|
|
59
|
+
var calculateTradePnlRiskRatios = ({
|
|
60
|
+
profits,
|
|
61
|
+
totalProfit,
|
|
62
|
+
maxDrawdown,
|
|
63
|
+
periodDays
|
|
64
|
+
}) => {
|
|
65
|
+
if (!profits.length || periodDays == null || periodDays <= 0) {
|
|
66
|
+
return {
|
|
67
|
+
sharpeRatio: null,
|
|
68
|
+
sortinoRatio: null,
|
|
69
|
+
calmarRatio: null
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const meanProfit = totalProfit / profits.length;
|
|
73
|
+
const variance = profits.reduce((sum, profit) => {
|
|
74
|
+
const diff = profit - meanProfit;
|
|
75
|
+
return sum + diff * diff;
|
|
76
|
+
}, 0) / profits.length;
|
|
77
|
+
const stdDev = Math.sqrt(variance);
|
|
78
|
+
const downsideDeviation = Math.sqrt(
|
|
79
|
+
profits.reduce(
|
|
80
|
+
(sum, profit) => profit < 0 ? sum + profit * profit : sum,
|
|
81
|
+
0
|
|
82
|
+
) / profits.length
|
|
83
|
+
);
|
|
84
|
+
const annualizationScale = Math.sqrt(
|
|
85
|
+
profits.length / periodDays * DAYS_PER_YEAR
|
|
86
|
+
);
|
|
87
|
+
return {
|
|
88
|
+
sharpeRatio: stdDev > 0 && annualizationScale > 0 ? meanProfit / stdDev * annualizationScale : null,
|
|
89
|
+
sortinoRatio: downsideDeviation > 0 && annualizationScale > 0 ? meanProfit / downsideDeviation * annualizationScale : null,
|
|
90
|
+
calmarRatio: maxDrawdown > 0 ? totalProfit / periodDays * DAYS_PER_YEAR / maxDrawdown : null
|
|
91
|
+
};
|
|
92
|
+
};
|
|
58
93
|
var emptyRiskSummary = () => ({
|
|
59
94
|
trades: 0,
|
|
60
95
|
totalProfit: 0,
|
|
@@ -70,12 +105,15 @@ var emptyRiskSummary = () => ({
|
|
|
70
105
|
maxDrawdown: 0,
|
|
71
106
|
maxDrawdownPctOfGrossProfit: null,
|
|
72
107
|
maxDrawdownPctOfTotalProfit: null,
|
|
108
|
+
sharpeRatio: null,
|
|
109
|
+
sortinoRatio: null,
|
|
110
|
+
calmarRatio: null,
|
|
73
111
|
recoveryFactor: null,
|
|
74
112
|
ulcerIndex: null,
|
|
75
113
|
maxConsecutiveWins: 0,
|
|
76
114
|
maxConsecutiveLosses: 0
|
|
77
115
|
});
|
|
78
|
-
var summarizeApprovedRisk = (evaluations) => {
|
|
116
|
+
var summarizeApprovedRisk = (evaluations, periodDays = getEvaluationPeriodDays(evaluations)) => {
|
|
79
117
|
const approvedEvaluations = evaluations.filter((evaluation) => evaluation.aiApproved).sort((left, right) => {
|
|
80
118
|
const leftTimestamp = typeof left.timestamp === "number" && Number.isFinite(left.timestamp) ? left.timestamp : Number.POSITIVE_INFINITY;
|
|
81
119
|
const rightTimestamp = typeof right.timestamp === "number" && Number.isFinite(right.timestamp) ? right.timestamp : Number.POSITIVE_INFINITY;
|
|
@@ -98,8 +136,10 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
98
136
|
let currentLossStreak = 0;
|
|
99
137
|
let maxConsecutiveWins = 0;
|
|
100
138
|
let maxConsecutiveLosses = 0;
|
|
139
|
+
const approvedProfits = [];
|
|
101
140
|
for (const evaluation of approvedEvaluations) {
|
|
102
141
|
const profit = evaluation.profit;
|
|
142
|
+
approvedProfits.push(profit);
|
|
103
143
|
if (profit > 0) {
|
|
104
144
|
grossProfit += profit;
|
|
105
145
|
wins += 1;
|
|
@@ -127,6 +167,12 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
127
167
|
const totalProfit = grossProfit - grossLoss;
|
|
128
168
|
const avgWin = divideOrNull(grossProfit, wins);
|
|
129
169
|
const avgLoss = divideOrNull(grossLoss, losses);
|
|
170
|
+
const riskRatios = calculateTradePnlRiskRatios({
|
|
171
|
+
profits: approvedProfits,
|
|
172
|
+
totalProfit,
|
|
173
|
+
maxDrawdown,
|
|
174
|
+
periodDays
|
|
175
|
+
});
|
|
130
176
|
return {
|
|
131
177
|
trades: approvedEvaluations.length,
|
|
132
178
|
totalProfit,
|
|
@@ -142,6 +188,7 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
142
188
|
maxDrawdown,
|
|
143
189
|
maxDrawdownPctOfGrossProfit: grossProfit > 0 ? maxDrawdown / grossProfit : null,
|
|
144
190
|
maxDrawdownPctOfTotalProfit: totalProfit > 0 ? maxDrawdown / totalProfit : null,
|
|
191
|
+
...riskRatios,
|
|
145
192
|
recoveryFactor: maxDrawdown > 0 ? totalProfit / maxDrawdown : null,
|
|
146
193
|
ulcerIndex: Math.sqrt(drawdownSquares / approvedEvaluations.length),
|
|
147
194
|
maxConsecutiveWins,
|
|
@@ -240,7 +287,7 @@ var summarizeAiTrainEvaluations = (evaluations) => {
|
|
|
240
287
|
avgApprovedTradesPerDay,
|
|
241
288
|
avgApprovedTradesPerWeek,
|
|
242
289
|
expectancyDelta,
|
|
243
|
-
approvedRisk: summarizeApprovedRisk(evaluations),
|
|
290
|
+
approvedRisk: summarizeApprovedRisk(evaluations, periodDays),
|
|
244
291
|
qualityBuckets: [...bucketMap.values()].sort(
|
|
245
292
|
(a, b) => qualitySortKey(a.quality) - qualitySortKey(b.quality)
|
|
246
293
|
)
|
|
@@ -35,6 +35,7 @@ var divideOrNull = (num, denom) => {
|
|
|
35
35
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
36
36
|
var DAYS_PER_WEEK = 7;
|
|
37
37
|
var DAYS_PER_MONTH = 30.4375;
|
|
38
|
+
var DAYS_PER_YEAR = 365;
|
|
38
39
|
var getEvaluationPeriodDays = (evaluations) => {
|
|
39
40
|
let minTimestamp = null;
|
|
40
41
|
let maxTimestamp = null;
|
|
@@ -56,6 +57,40 @@ var getEvaluationPeriodDays = (evaluations) => {
|
|
|
56
57
|
return Math.max((maxTimestamp - minTimestamp) / DAY_MS, 1);
|
|
57
58
|
};
|
|
58
59
|
var qualitySortKey = (quality) => quality == null ? Number.POSITIVE_INFINITY : quality;
|
|
60
|
+
var calculateTradePnlRiskRatios = ({
|
|
61
|
+
profits,
|
|
62
|
+
totalProfit,
|
|
63
|
+
maxDrawdown,
|
|
64
|
+
periodDays
|
|
65
|
+
}) => {
|
|
66
|
+
if (!profits.length || periodDays == null || periodDays <= 0) {
|
|
67
|
+
return {
|
|
68
|
+
sharpeRatio: null,
|
|
69
|
+
sortinoRatio: null,
|
|
70
|
+
calmarRatio: null
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const meanProfit = totalProfit / profits.length;
|
|
74
|
+
const variance = profits.reduce((sum, profit) => {
|
|
75
|
+
const diff = profit - meanProfit;
|
|
76
|
+
return sum + diff * diff;
|
|
77
|
+
}, 0) / profits.length;
|
|
78
|
+
const stdDev = Math.sqrt(variance);
|
|
79
|
+
const downsideDeviation = Math.sqrt(
|
|
80
|
+
profits.reduce(
|
|
81
|
+
(sum, profit) => profit < 0 ? sum + profit * profit : sum,
|
|
82
|
+
0
|
|
83
|
+
) / profits.length
|
|
84
|
+
);
|
|
85
|
+
const annualizationScale = Math.sqrt(
|
|
86
|
+
profits.length / periodDays * DAYS_PER_YEAR
|
|
87
|
+
);
|
|
88
|
+
return {
|
|
89
|
+
sharpeRatio: stdDev > 0 && annualizationScale > 0 ? meanProfit / stdDev * annualizationScale : null,
|
|
90
|
+
sortinoRatio: downsideDeviation > 0 && annualizationScale > 0 ? meanProfit / downsideDeviation * annualizationScale : null,
|
|
91
|
+
calmarRatio: maxDrawdown > 0 ? totalProfit / periodDays * DAYS_PER_YEAR / maxDrawdown : null
|
|
92
|
+
};
|
|
93
|
+
};
|
|
59
94
|
var emptyRiskSummary = () => ({
|
|
60
95
|
trades: 0,
|
|
61
96
|
totalProfit: 0,
|
|
@@ -71,12 +106,15 @@ var emptyRiskSummary = () => ({
|
|
|
71
106
|
maxDrawdown: 0,
|
|
72
107
|
maxDrawdownPctOfGrossProfit: null,
|
|
73
108
|
maxDrawdownPctOfTotalProfit: null,
|
|
109
|
+
sharpeRatio: null,
|
|
110
|
+
sortinoRatio: null,
|
|
111
|
+
calmarRatio: null,
|
|
74
112
|
recoveryFactor: null,
|
|
75
113
|
ulcerIndex: null,
|
|
76
114
|
maxConsecutiveWins: 0,
|
|
77
115
|
maxConsecutiveLosses: 0
|
|
78
116
|
});
|
|
79
|
-
var summarizeApprovedRisk = (evaluations) => {
|
|
117
|
+
var summarizeApprovedRisk = (evaluations, periodDays = getEvaluationPeriodDays(evaluations)) => {
|
|
80
118
|
const approvedEvaluations = evaluations.filter((evaluation) => evaluation.aiApproved).sort((left, right) => {
|
|
81
119
|
const leftTimestamp = typeof left.timestamp === "number" && Number.isFinite(left.timestamp) ? left.timestamp : Number.POSITIVE_INFINITY;
|
|
82
120
|
const rightTimestamp = typeof right.timestamp === "number" && Number.isFinite(right.timestamp) ? right.timestamp : Number.POSITIVE_INFINITY;
|
|
@@ -99,8 +137,10 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
99
137
|
let currentLossStreak = 0;
|
|
100
138
|
let maxConsecutiveWins = 0;
|
|
101
139
|
let maxConsecutiveLosses = 0;
|
|
140
|
+
const approvedProfits = [];
|
|
102
141
|
for (const evaluation of approvedEvaluations) {
|
|
103
142
|
const profit = evaluation.profit;
|
|
143
|
+
approvedProfits.push(profit);
|
|
104
144
|
if (profit > 0) {
|
|
105
145
|
grossProfit += profit;
|
|
106
146
|
wins += 1;
|
|
@@ -128,6 +168,12 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
128
168
|
const totalProfit = grossProfit - grossLoss;
|
|
129
169
|
const avgWin = divideOrNull(grossProfit, wins);
|
|
130
170
|
const avgLoss = divideOrNull(grossLoss, losses);
|
|
171
|
+
const riskRatios = calculateTradePnlRiskRatios({
|
|
172
|
+
profits: approvedProfits,
|
|
173
|
+
totalProfit,
|
|
174
|
+
maxDrawdown,
|
|
175
|
+
periodDays
|
|
176
|
+
});
|
|
131
177
|
return {
|
|
132
178
|
trades: approvedEvaluations.length,
|
|
133
179
|
totalProfit,
|
|
@@ -143,6 +189,7 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
143
189
|
maxDrawdown,
|
|
144
190
|
maxDrawdownPctOfGrossProfit: grossProfit > 0 ? maxDrawdown / grossProfit : null,
|
|
145
191
|
maxDrawdownPctOfTotalProfit: totalProfit > 0 ? maxDrawdown / totalProfit : null,
|
|
192
|
+
...riskRatios,
|
|
146
193
|
recoveryFactor: maxDrawdown > 0 ? totalProfit / maxDrawdown : null,
|
|
147
194
|
ulcerIndex: Math.sqrt(drawdownSquares / approvedEvaluations.length),
|
|
148
195
|
maxConsecutiveWins,
|
|
@@ -241,7 +288,7 @@ var summarizeAiTrainEvaluations = (evaluations) => {
|
|
|
241
288
|
avgApprovedTradesPerDay,
|
|
242
289
|
avgApprovedTradesPerWeek,
|
|
243
290
|
expectancyDelta,
|
|
244
|
-
approvedRisk: summarizeApprovedRisk(evaluations),
|
|
291
|
+
approvedRisk: summarizeApprovedRisk(evaluations, periodDays),
|
|
245
292
|
qualityBuckets: [...bucketMap.values()].sort(
|
|
246
293
|
(a, b) => qualitySortKey(a.quality) - qualitySortKey(b.quality)
|
|
247
294
|
)
|
|
@@ -52,6 +52,7 @@ var divideOrNull = (num, denom) => {
|
|
|
52
52
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
53
53
|
var DAYS_PER_WEEK = 7;
|
|
54
54
|
var DAYS_PER_MONTH = 30.4375;
|
|
55
|
+
var DAYS_PER_YEAR = 365;
|
|
55
56
|
var getEvaluationPeriodDays = (evaluations) => {
|
|
56
57
|
let minTimestamp = null;
|
|
57
58
|
let maxTimestamp = null;
|
|
@@ -73,6 +74,40 @@ var getEvaluationPeriodDays = (evaluations) => {
|
|
|
73
74
|
return Math.max((maxTimestamp - minTimestamp) / DAY_MS, 1);
|
|
74
75
|
};
|
|
75
76
|
var qualitySortKey = (quality) => quality == null ? Number.POSITIVE_INFINITY : quality;
|
|
77
|
+
var calculateTradePnlRiskRatios = ({
|
|
78
|
+
profits,
|
|
79
|
+
totalProfit,
|
|
80
|
+
maxDrawdown,
|
|
81
|
+
periodDays
|
|
82
|
+
}) => {
|
|
83
|
+
if (!profits.length || periodDays == null || periodDays <= 0) {
|
|
84
|
+
return {
|
|
85
|
+
sharpeRatio: null,
|
|
86
|
+
sortinoRatio: null,
|
|
87
|
+
calmarRatio: null
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const meanProfit = totalProfit / profits.length;
|
|
91
|
+
const variance = profits.reduce((sum, profit) => {
|
|
92
|
+
const diff = profit - meanProfit;
|
|
93
|
+
return sum + diff * diff;
|
|
94
|
+
}, 0) / profits.length;
|
|
95
|
+
const stdDev = Math.sqrt(variance);
|
|
96
|
+
const downsideDeviation = Math.sqrt(
|
|
97
|
+
profits.reduce(
|
|
98
|
+
(sum, profit) => profit < 0 ? sum + profit * profit : sum,
|
|
99
|
+
0
|
|
100
|
+
) / profits.length
|
|
101
|
+
);
|
|
102
|
+
const annualizationScale = Math.sqrt(
|
|
103
|
+
profits.length / periodDays * DAYS_PER_YEAR
|
|
104
|
+
);
|
|
105
|
+
return {
|
|
106
|
+
sharpeRatio: stdDev > 0 && annualizationScale > 0 ? meanProfit / stdDev * annualizationScale : null,
|
|
107
|
+
sortinoRatio: downsideDeviation > 0 && annualizationScale > 0 ? meanProfit / downsideDeviation * annualizationScale : null,
|
|
108
|
+
calmarRatio: maxDrawdown > 0 ? totalProfit / periodDays * DAYS_PER_YEAR / maxDrawdown : null
|
|
109
|
+
};
|
|
110
|
+
};
|
|
76
111
|
var emptyRiskSummary = () => ({
|
|
77
112
|
trades: 0,
|
|
78
113
|
totalProfit: 0,
|
|
@@ -88,12 +123,15 @@ var emptyRiskSummary = () => ({
|
|
|
88
123
|
maxDrawdown: 0,
|
|
89
124
|
maxDrawdownPctOfGrossProfit: null,
|
|
90
125
|
maxDrawdownPctOfTotalProfit: null,
|
|
126
|
+
sharpeRatio: null,
|
|
127
|
+
sortinoRatio: null,
|
|
128
|
+
calmarRatio: null,
|
|
91
129
|
recoveryFactor: null,
|
|
92
130
|
ulcerIndex: null,
|
|
93
131
|
maxConsecutiveWins: 0,
|
|
94
132
|
maxConsecutiveLosses: 0
|
|
95
133
|
});
|
|
96
|
-
var summarizeApprovedRisk = (evaluations) => {
|
|
134
|
+
var summarizeApprovedRisk = (evaluations, periodDays = getEvaluationPeriodDays(evaluations)) => {
|
|
97
135
|
const approvedEvaluations = evaluations.filter((evaluation) => evaluation.aiApproved).sort((left, right) => {
|
|
98
136
|
const leftTimestamp = typeof left.timestamp === "number" && Number.isFinite(left.timestamp) ? left.timestamp : Number.POSITIVE_INFINITY;
|
|
99
137
|
const rightTimestamp = typeof right.timestamp === "number" && Number.isFinite(right.timestamp) ? right.timestamp : Number.POSITIVE_INFINITY;
|
|
@@ -116,8 +154,10 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
116
154
|
let currentLossStreak = 0;
|
|
117
155
|
let maxConsecutiveWins = 0;
|
|
118
156
|
let maxConsecutiveLosses = 0;
|
|
157
|
+
const approvedProfits = [];
|
|
119
158
|
for (const evaluation of approvedEvaluations) {
|
|
120
159
|
const profit = evaluation.profit;
|
|
160
|
+
approvedProfits.push(profit);
|
|
121
161
|
if (profit > 0) {
|
|
122
162
|
grossProfit += profit;
|
|
123
163
|
wins += 1;
|
|
@@ -145,6 +185,12 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
145
185
|
const totalProfit = grossProfit - grossLoss;
|
|
146
186
|
const avgWin = divideOrNull(grossProfit, wins);
|
|
147
187
|
const avgLoss = divideOrNull(grossLoss, losses);
|
|
188
|
+
const riskRatios = calculateTradePnlRiskRatios({
|
|
189
|
+
profits: approvedProfits,
|
|
190
|
+
totalProfit,
|
|
191
|
+
maxDrawdown,
|
|
192
|
+
periodDays
|
|
193
|
+
});
|
|
148
194
|
return {
|
|
149
195
|
trades: approvedEvaluations.length,
|
|
150
196
|
totalProfit,
|
|
@@ -160,6 +206,7 @@ var summarizeApprovedRisk = (evaluations) => {
|
|
|
160
206
|
maxDrawdown,
|
|
161
207
|
maxDrawdownPctOfGrossProfit: grossProfit > 0 ? maxDrawdown / grossProfit : null,
|
|
162
208
|
maxDrawdownPctOfTotalProfit: totalProfit > 0 ? maxDrawdown / totalProfit : null,
|
|
209
|
+
...riskRatios,
|
|
163
210
|
recoveryFactor: maxDrawdown > 0 ? totalProfit / maxDrawdown : null,
|
|
164
211
|
ulcerIndex: Math.sqrt(drawdownSquares / approvedEvaluations.length),
|
|
165
212
|
maxConsecutiveWins,
|
|
@@ -258,7 +305,7 @@ var summarizeAiTrainEvaluations = (evaluations) => {
|
|
|
258
305
|
avgApprovedTradesPerDay,
|
|
259
306
|
avgApprovedTradesPerWeek,
|
|
260
307
|
expectancyDelta,
|
|
261
|
-
approvedRisk: summarizeApprovedRisk(evaluations),
|
|
308
|
+
approvedRisk: summarizeApprovedRisk(evaluations, periodDays),
|
|
262
309
|
qualityBuckets: [...bucketMap.values()].sort(
|
|
263
310
|
(a, b) => qualitySortKey(a.quality) - qualitySortKey(b.quality)
|
|
264
311
|
)
|
|
@@ -273,7 +320,6 @@ var RESEARCH_CONTEXT_ENV_KEYS = [
|
|
|
273
320
|
"INTERVAL",
|
|
274
321
|
"DERIVATIVES_CONTEXT_ENABLED",
|
|
275
322
|
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
276
|
-
"DERIVATIVES_CONTEXT_INTERVALS",
|
|
277
323
|
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
278
324
|
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
279
325
|
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|
|
@@ -287,6 +333,12 @@ var RESEARCH_CONTEXT_ENV_KEYS = [
|
|
|
287
333
|
"COINMARKETCAP_CONTEXT_BACKFILL_MAX_DAYS",
|
|
288
334
|
"COINMARKETCAP_CONTEXT_BACKFILL_WARMUP_DAYS"
|
|
289
335
|
];
|
|
336
|
+
var DERIVATIVES_CONTEXT_DATA_MODEL = {
|
|
337
|
+
derivativesSourceIntervals: "15m",
|
|
338
|
+
derivativesDerivedIntervals: "1h",
|
|
339
|
+
derivativesHourlyFallback: "stored-1h",
|
|
340
|
+
derivativesDataModelVersion: 2
|
|
341
|
+
};
|
|
290
342
|
var normalizeForStableJson = (value) => {
|
|
291
343
|
if (Array.isArray(value)) {
|
|
292
344
|
return value.map(normalizeForStableJson);
|
|
@@ -399,6 +451,7 @@ var resolveGateFingerprint = async (projectRoot, strategyName, gitSha) => {
|
|
|
399
451
|
const relativeCandidates = [
|
|
400
452
|
`packages/strategies/src/${strategyName}/adapters/ai.ts`,
|
|
401
453
|
`packages/strategies/src/${strategyName}/guardrails.ts`,
|
|
454
|
+
`packages/strategies/src/${strategyName}/pockets.ts`,
|
|
402
455
|
`packages/strategies/src/${strategyName}/config.ts`,
|
|
403
456
|
"packages/node/src/ai.ts"
|
|
404
457
|
];
|
|
@@ -445,7 +498,8 @@ var buildAiTrainLineage = async ({
|
|
|
445
498
|
...Object.fromEntries(
|
|
446
499
|
RESEARCH_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
|
|
447
500
|
),
|
|
448
|
-
...runContext
|
|
501
|
+
...runContext,
|
|
502
|
+
...DERIVATIVES_CONTEXT_DATA_MODEL
|
|
449
503
|
};
|
|
450
504
|
return {
|
|
451
505
|
gitSha,
|