@tradejs/cli 3.1.29-beta.291 → 3.1.29-beta.292

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.
@@ -170,7 +170,7 @@ function normalizeTrade(raw, fallbackStrategy, candlesBySymbol = {}) {
170
170
  pockets,
171
171
  features,
172
172
  groups,
173
- candles: normalizeCandles(r.candles ?? candlesBySymbol[symbol]),
173
+ candles: r.candles === void 0 ? candlesBySymbol[symbol] ?? [] : normalizeCandles(r.candles),
174
174
  figures: normalizeFigures(r.figures ?? payload.figures)
175
175
  };
176
176
  }
@@ -192,11 +192,16 @@ function normalizeDataset(input, options = {}) {
192
192
  );
193
193
  if (runs.size > 1)
194
194
  throw new Error("Mixed backtest runs; provide one immutable lineage");
195
+ const candlesBySymbol = Object.fromEntries(
196
+ Object.entries(options.candlesBySymbol ?? object(root.candlesBySymbol)).map(
197
+ ([symbol, candles]) => [symbol, normalizeCandles(candles)]
198
+ )
199
+ );
195
200
  const trades = rows.map(
196
201
  (r) => normalizeTrade(
197
202
  r,
198
203
  options.strategy ?? String(root.strategy ?? ""),
199
- options.candlesBySymbol ?? object(root.candlesBySymbol)
204
+ candlesBySymbol
200
205
  )
201
206
  );
202
207
  const ids = /* @__PURE__ */ new Set();
@@ -213,6 +218,21 @@ function normalizeDataset(input, options = {}) {
213
218
  trades
214
219
  };
215
220
  }
221
+ function tradeCandleWindow(trade, intervalMs) {
222
+ const lowerBound = (timestamp) => {
223
+ let lo = 0, hi = trade.candles.length;
224
+ while (lo < hi) {
225
+ const mid = Math.floor((lo + hi) / 2);
226
+ if (trade.candles[mid].timestamp < timestamp) lo = mid + 1;
227
+ else hi = mid;
228
+ }
229
+ return lo;
230
+ };
231
+ return trade.candles.slice(
232
+ lowerBound(trade.signalTime - 140 * intervalMs),
233
+ lowerBound(trade.exitTime + 20 * intervalMs + 1)
234
+ );
235
+ }
216
236
 
217
237
  // src/lib/researchVisuals/analysis.ts
218
238
  var import_node_crypto = require("crypto");
@@ -534,7 +554,10 @@ function pricePanel(t, c, step, x, y, w, h) {
534
554
  );
535
555
  }
536
556
  function renderTradeSvg(t, intervalMs) {
537
- const candles = chartCandles(t);
557
+ const candles = chartCandles({
558
+ ...t,
559
+ candles: tradeCandleWindow(t, intervalMs)
560
+ });
538
561
  const start = Math.min(
539
562
  t.signalTime - 90 * intervalMs,
540
563
  t.entryTime - 90 * intervalMs
@@ -809,9 +832,7 @@ async function generateResearchVisuals(options) {
809
832
  population: "selected",
810
833
  trades: selected.map((trade) => ({
811
834
  ...trade,
812
- candles: trade.candles.filter(
813
- (bar) => bar.timestamp >= trade.signalTime - 140 * dataset.intervalMs && bar.timestamp <= trade.exitTime + 20 * dataset.intervalMs
814
- )
835
+ candles: tradeCandleWindow(trade, dataset.intervalMs)
815
836
  }))
816
837
  };
817
838
  await write("chart-inputs.json.gz", (0, import_node_zlib.gzipSync)(JSON.stringify(retained)));