@tradejs/cli 1.0.6 → 1.0.8

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.
@@ -497,19 +497,21 @@ var require_supports_color = __commonJS({
497
497
  var tty = require("tty");
498
498
  var hasFlag = require_has_flag();
499
499
  var { env } = process;
500
- var forceColor;
500
+ var flagForceColor;
501
501
  if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
502
- forceColor = 0;
502
+ flagForceColor = 0;
503
503
  } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
504
- forceColor = 1;
504
+ flagForceColor = 1;
505
505
  }
506
- if ("FORCE_COLOR" in env) {
507
- if (env.FORCE_COLOR === "true") {
508
- forceColor = 1;
509
- } else if (env.FORCE_COLOR === "false") {
510
- forceColor = 0;
511
- } else {
512
- forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
506
+ function envForceColor() {
507
+ if ("FORCE_COLOR" in env) {
508
+ if (env.FORCE_COLOR === "true") {
509
+ return 1;
510
+ }
511
+ if (env.FORCE_COLOR === "false") {
512
+ return 0;
513
+ }
514
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
513
515
  }
514
516
  }
515
517
  function translateLevel(level) {
@@ -523,15 +525,22 @@ var require_supports_color = __commonJS({
523
525
  has16m: level >= 3
524
526
  };
525
527
  }
526
- function supportsColor(haveStream, streamIsTTY) {
528
+ function supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
529
+ const noFlagForceColor = envForceColor();
530
+ if (noFlagForceColor !== void 0) {
531
+ flagForceColor = noFlagForceColor;
532
+ }
533
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
527
534
  if (forceColor === 0) {
528
535
  return 0;
529
536
  }
530
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
531
- return 3;
532
- }
533
- if (hasFlag("color=256")) {
534
- return 2;
537
+ if (sniffFlags) {
538
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
539
+ return 3;
540
+ }
541
+ if (hasFlag("color=256")) {
542
+ return 2;
543
+ }
535
544
  }
536
545
  if (haveStream && !streamIsTTY && forceColor === void 0) {
537
546
  return 0;
@@ -548,7 +557,7 @@ var require_supports_color = __commonJS({
548
557
  return 1;
549
558
  }
550
559
  if ("CI" in env) {
551
- if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
560
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
552
561
  return 1;
553
562
  }
554
563
  return min;
@@ -560,7 +569,7 @@ var require_supports_color = __commonJS({
560
569
  return 3;
561
570
  }
562
571
  if ("TERM_PROGRAM" in env) {
563
- const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
572
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
564
573
  switch (env.TERM_PROGRAM) {
565
574
  case "iTerm.app":
566
575
  return version >= 3 ? 3 : 2;
@@ -579,14 +588,17 @@ var require_supports_color = __commonJS({
579
588
  }
580
589
  return min;
581
590
  }
582
- function getSupportLevel(stream) {
583
- const level = supportsColor(stream, stream && stream.isTTY);
591
+ function getSupportLevel(stream, options = {}) {
592
+ const level = supportsColor(stream, {
593
+ streamIsTTY: stream && stream.isTTY,
594
+ ...options
595
+ });
584
596
  return translateLevel(level);
585
597
  }
586
598
  module2.exports = {
587
599
  supportsColor: getSupportLevel,
588
- stdout: translateLevel(supportsColor(true, tty.isatty(1))),
589
- stderr: translateLevel(supportsColor(true, tty.isatty(2)))
600
+ stdout: getSupportLevel({ isTTY: tty.isatty(1) }),
601
+ stderr: getSupportLevel({ isTTY: tty.isatty(2) })
590
602
  };
591
603
  }
592
604
  });
@@ -1627,6 +1639,20 @@ var divideOrNull = (num, denom) => {
1627
1639
  }
1628
1640
  return num / denom;
1629
1641
  };
1642
+ var DAY_MS = 24 * 60 * 60 * 1e3;
1643
+ var DAYS_PER_WEEK = 7;
1644
+ var DAYS_PER_MONTH = 30.4375;
1645
+ var getEvaluationPeriodDays = (evaluations) => {
1646
+ const timestamps = evaluations.map(
1647
+ (evaluation) => typeof evaluation.timestamp === "number" && Number.isFinite(evaluation.timestamp) ? evaluation.timestamp : null
1648
+ ).filter((timestamp) => timestamp != null);
1649
+ if (!timestamps.length) {
1650
+ return null;
1651
+ }
1652
+ const minTimestamp = Math.min(...timestamps);
1653
+ const maxTimestamp = Math.max(...timestamps);
1654
+ return Math.max((maxTimestamp - minTimestamp) / DAY_MS, 1);
1655
+ };
1630
1656
  var qualitySortKey = (quality) => quality == null ? Number.POSITIVE_INFINITY : quality;
1631
1657
  var summarizeAiTrainEvaluations = (evaluations) => {
1632
1658
  let approved = 0;
@@ -1693,6 +1719,11 @@ var summarizeAiTrainEvaluations = (evaluations) => {
1693
1719
  }
1694
1720
  const avgProfitAll = divideOrNull(totalProfitAll, evaluations.length);
1695
1721
  const avgProfitApproved = divideOrNull(totalProfitApproved, approved);
1722
+ const periodDays = getEvaluationPeriodDays(evaluations);
1723
+ const avgProfitApprovedPerDay = periodDays == null ? null : divideOrNull(totalProfitApproved, periodDays);
1724
+ const avgApprovedTradesPerDay = periodDays == null ? null : divideOrNull(approved, periodDays);
1725
+ const avgProfitApprovedPerMonth = avgProfitApprovedPerDay == null ? null : avgProfitApprovedPerDay * DAYS_PER_MONTH;
1726
+ const avgApprovedTradesPerWeek = avgApprovedTradesPerDay == null ? null : avgApprovedTradesPerDay * DAYS_PER_WEEK;
1696
1727
  const expectancyDelta = avgProfitAll == null || avgProfitApproved == null ? null : avgProfitApproved - avgProfitAll;
1697
1728
  return {
1698
1729
  approved,
@@ -1710,6 +1741,10 @@ var summarizeAiTrainEvaluations = (evaluations) => {
1710
1741
  recallWinners: divideOrNull(truePositive, profitable),
1711
1742
  avgProfitAll,
1712
1743
  avgProfitApproved,
1744
+ avgProfitApprovedPerDay,
1745
+ avgProfitApprovedPerMonth,
1746
+ avgApprovedTradesPerDay,
1747
+ avgApprovedTradesPerWeek,
1713
1748
  expectancyDelta,
1714
1749
  qualityBuckets: [...bucketMap.values()].sort(
1715
1750
  (a, b) => qualitySortKey(a.quality) - qualitySortKey(b.quality)
@@ -1776,6 +1811,7 @@ import_args.default.option(
1776
1811
  "Replay deterministic adapter gate without AI provider calls",
1777
1812
  false
1778
1813
  );
1814
+ import_args.default.option("json", "Print structured JSON summary", false);
1779
1815
  var flags = import_args.default.parse(process.argv);
1780
1816
  var createListIt = () => new ListIt({
1781
1817
  autoAlign: true,
@@ -1784,6 +1820,7 @@ var createListIt = () => new ListIt({
1784
1820
  var createTable = (headers, rows) => createListIt().setHeaderRow(headers).d(rows).toString();
1785
1821
  var formatRatio = (value) => value == null ? "n/a" : `${(value * 100).toFixed(1)}%`;
1786
1822
  var formatProfit = (value) => value == null ? "n/a" : value.toFixed(2);
1823
+ var formatMetricNumber = (value) => value == null ? "n/a" : value.toFixed(2);
1787
1824
  var colorizeRatio = (value) => {
1788
1825
  const text = formatRatio(value);
1789
1826
  if (value == null) {
@@ -1814,6 +1851,10 @@ var colorizeProfit = (value) => {
1814
1851
  }
1815
1852
  return import_chalk.default.yellow(text);
1816
1853
  };
1854
+ var colorizeMetricNumber = (value) => {
1855
+ const text = formatMetricNumber(value);
1856
+ return value == null ? import_chalk.default.gray(text) : import_chalk.default.cyan(text);
1857
+ };
1817
1858
  var colorizeQuality = (quality) => {
1818
1859
  const text = quality == null ? "n/a" : String(quality);
1819
1860
  if (quality == null) {
@@ -1975,6 +2016,7 @@ var main = async () => {
1975
2016
  const skip = normalizeInt(flags.skip, 0);
1976
2017
  const minQuality = normalizeInt(flags.minQuality, 4);
1977
2018
  const localOnly = Boolean(flags.localOnly);
2019
+ const jsonOutput = Boolean(flags.json);
1978
2020
  const model = String(flags.model || import_ai2.DEFAULT_AI_MODEL).trim() || import_ai2.DEFAULT_AI_MODEL;
1979
2021
  const parallel = normalizePositiveInt(flags.parallel, import_constants.AI_CONCURRENCY_LIMIT);
1980
2022
  await (0, import_ai2.ensureAiStrategyPluginsLoaded)();
@@ -2005,13 +2047,10 @@ var main = async () => {
2005
2047
  };
2006
2048
  });
2007
2049
  const concurrency = Math.max(1, Math.min(parallel, rows.length));
2008
- const bar = new import_progress.default(
2009
- ":current/:total [:bar][:percent] :symbol :status",
2010
- {
2011
- total: rows.length,
2012
- width: 20
2013
- }
2014
- );
2050
+ const bar = jsonOutput ? null : new import_progress.default(":current/:total [:bar][:percent] :symbol :status", {
2051
+ total: rows.length,
2052
+ width: 20
2053
+ });
2015
2054
  let failed = 0;
2016
2055
  const errorMessages = [];
2017
2056
  const evaluations = [];
@@ -2037,9 +2076,10 @@ var main = async () => {
2037
2076
  aiApproved,
2038
2077
  quality,
2039
2078
  direction: row.direction,
2079
+ timestamp: Number.isFinite(Number(row.timestamp)) ? Number(row.timestamp) : null,
2040
2080
  modelCandidate: deterministic.modelCandidate
2041
2081
  });
2042
- bar.tick(1, {
2082
+ bar?.tick(1, {
2043
2083
  symbol: import_chalk.default.gray(row.symbol),
2044
2084
  status: isCorrect ? import_chalk.default.green("ok") : import_chalk.default.red("miss")
2045
2085
  });
@@ -2050,7 +2090,7 @@ var main = async () => {
2050
2090
  `[${row.symbol}/${row.signalId}] ${error instanceof Error ? error.message : String(error)}`
2051
2091
  );
2052
2092
  }
2053
- bar.tick(1, {
2093
+ bar?.tick(1, {
2054
2094
  symbol: import_chalk.default.gray(row.symbol),
2055
2095
  status: import_chalk.default.yellow("error")
2056
2096
  });
@@ -2063,6 +2103,32 @@ var main = async () => {
2063
2103
  evaluations
2064
2104
  );
2065
2105
  const evaluated = summary.correct + summary.incorrect;
2106
+ const result = {
2107
+ run: {
2108
+ strategy: strategyName,
2109
+ filePath,
2110
+ selected: rows.length,
2111
+ sourceRows: totalRows,
2112
+ recent,
2113
+ skip,
2114
+ minQuality,
2115
+ mode: localOnly ? "local-deterministic" : "llm",
2116
+ model: localOnly ? "local-deterministic" : model,
2117
+ parallel: concurrency
2118
+ },
2119
+ outcome: summary,
2120
+ byDirection: directionSummaries,
2121
+ deterministicFlow: deterministicSummary,
2122
+ qualityBreakdown: summary.qualityBuckets,
2123
+ errors: {
2124
+ failed,
2125
+ providerErrors: errorMessages
2126
+ }
2127
+ };
2128
+ if (jsonOutput) {
2129
+ console.log(JSON.stringify(result));
2130
+ process.exit(failed === rows.length ? 1 : 0);
2131
+ }
2066
2132
  console.log("");
2067
2133
  console.log(import_chalk.default.green("AI train finished"));
2068
2134
  console.log(import_chalk.default.gray(filePath));
@@ -2109,6 +2175,22 @@ var main = async () => {
2109
2175
  ["recall_winners", colorizeRatio(summary.recallWinners)],
2110
2176
  ["avg_profit_all", colorizeProfit(summary.avgProfitAll)],
2111
2177
  ["avg_profit_approved", colorizeProfit(summary.avgProfitApproved)],
2178
+ [
2179
+ "avg_profit_approved_per_day",
2180
+ colorizeProfit(summary.avgProfitApprovedPerDay)
2181
+ ],
2182
+ [
2183
+ "avg_profit_approved_per_month",
2184
+ colorizeProfit(summary.avgProfitApprovedPerMonth)
2185
+ ],
2186
+ [
2187
+ "avg_approved_trades_per_day",
2188
+ colorizeMetricNumber(summary.avgApprovedTradesPerDay)
2189
+ ],
2190
+ [
2191
+ "avg_approved_trades_per_week",
2192
+ colorizeMetricNumber(summary.avgApprovedTradesPerWeek)
2193
+ ],
2112
2194
  ["expectancy_delta", colorizeProfit(summary.expectancyDelta)]
2113
2195
  ]
2114
2196
  )