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

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.
@@ -174,7 +174,7 @@ function normalizeTrade(raw, fallbackStrategy, candlesBySymbol = {}) {
174
174
  pockets,
175
175
  features,
176
176
  groups,
177
- candles: normalizeCandles(r.candles ?? candlesBySymbol[symbol]),
177
+ candles: r.candles === void 0 ? candlesBySymbol[symbol] ?? [] : normalizeCandles(r.candles),
178
178
  figures: normalizeFigures(r.figures ?? payload.figures)
179
179
  };
180
180
  }
@@ -196,11 +196,16 @@ function normalizeDataset(input, options = {}) {
196
196
  );
197
197
  if (runs.size > 1)
198
198
  throw new Error("Mixed backtest runs; provide one immutable lineage");
199
+ const candlesBySymbol = Object.fromEntries(
200
+ Object.entries(options.candlesBySymbol ?? object(root.candlesBySymbol)).map(
201
+ ([symbol, candles]) => [symbol, normalizeCandles(candles)]
202
+ )
203
+ );
199
204
  const trades = rows.map(
200
205
  (r) => normalizeTrade(
201
206
  r,
202
207
  options.strategy ?? String(root.strategy ?? ""),
203
- options.candlesBySymbol ?? object(root.candlesBySymbol)
208
+ candlesBySymbol
204
209
  )
205
210
  );
206
211
  const ids = /* @__PURE__ */ new Set();
@@ -217,6 +222,21 @@ function normalizeDataset(input, options = {}) {
217
222
  trades
218
223
  };
219
224
  }
225
+ function tradeCandleWindow(trade, intervalMs) {
226
+ const lowerBound = (timestamp) => {
227
+ let lo = 0, hi = trade.candles.length;
228
+ while (lo < hi) {
229
+ const mid = Math.floor((lo + hi) / 2);
230
+ if (trade.candles[mid].timestamp < timestamp) lo = mid + 1;
231
+ else hi = mid;
232
+ }
233
+ return lo;
234
+ };
235
+ return trade.candles.slice(
236
+ lowerBound(trade.signalTime - 140 * intervalMs),
237
+ lowerBound(trade.exitTime + 20 * intervalMs + 1)
238
+ );
239
+ }
220
240
 
221
241
  // src/lib/researchVisuals/analysis.ts
222
242
  var import_node_crypto = require("crypto");
@@ -538,7 +558,10 @@ function pricePanel(t, c, step, x, y, w, h) {
538
558
  );
539
559
  }
540
560
  function renderTradeSvg(t, intervalMs) {
541
- const candles = chartCandles(t);
561
+ const candles = chartCandles({
562
+ ...t,
563
+ candles: tradeCandleWindow(t, intervalMs)
564
+ });
542
565
  const start = Math.min(
543
566
  t.signalTime - 90 * intervalMs,
544
567
  t.entryTime - 90 * intervalMs
@@ -813,9 +836,7 @@ async function generateResearchVisuals(options) {
813
836
  population: "selected",
814
837
  trades: selected.map((trade) => ({
815
838
  ...trade,
816
- candles: trade.candles.filter(
817
- (bar) => bar.timestamp >= trade.signalTime - 140 * dataset.intervalMs && bar.timestamp <= trade.exitTime + 20 * dataset.intervalMs
818
- )
839
+ candles: tradeCandleWindow(trade, dataset.intervalMs)
819
840
  }))
820
841
  };
821
842
  await write("chart-inputs.json.gz", (0, import_node_zlib.gzipSync)(JSON.stringify(retained)));