@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.
- package/dist/cli.js +11012 -5970
- package/dist/lib/aiTrainMetrics.js +23 -0
- package/dist/lib/candlesProviderMigration.js +266 -0
- package/dist/lib/cliArgs.js +40 -0
- package/dist/lib/derivativesContextBackfill.js +487 -0
- package/dist/lib/researchAgent.js +195 -0
- package/dist/lib/runtimeParity.js +234 -0
- package/dist/lib/telegramReports.js +91 -0
- package/dist/lib/timeWindow.js +101 -0
- package/dist/scripts/agentRun.js +895 -0
- package/dist/scripts/aiTrain.js +113 -31
- package/dist/scripts/backtest.js +794 -93
- package/dist/scripts/candlesMigrateProvider.js +5302 -0
- package/dist/scripts/continuity.js +1 -1
- package/dist/scripts/migration.js +1 -1
- package/dist/scripts/researchAuto.js +845 -0
- package/dist/scripts/results.js +46 -22
- package/dist/scripts/runtimeParity.js +1651 -0
- package/dist/scripts/signals.js +710 -57
- package/dist/scripts/signalsSummary.js +655 -0
- package/dist/scripts/user-add.js +0 -9
- package/package.json +16 -12
package/dist/scripts/aiTrain.js
CHANGED
|
@@ -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
|
|
500
|
+
var flagForceColor;
|
|
501
501
|
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
502
|
-
|
|
502
|
+
flagForceColor = 0;
|
|
503
503
|
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
504
|
-
|
|
504
|
+
flagForceColor = 1;
|
|
505
505
|
}
|
|
506
|
-
|
|
507
|
-
if (
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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 (
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
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,
|
|
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:
|
|
589
|
-
stderr:
|
|
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
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
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
|
|
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
|
|
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
|
)
|