@tradejs/cli 3.1.27 → 3.1.28-beta.251
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 +24040 -23180
- package/dist/lib/aiExport.js +1 -0
- package/dist/lib/coreResearch.js +42 -3
- package/dist/scripts/aiExport.js +1 -0
- package/dist/scripts/backtest.js +35 -6
- package/dist/scripts/coreResearch.js +42 -3
- package/dist/scripts/mlExport.js +1 -0
- package/dist/scripts/replay.js +808 -110
- package/dist/scripts/replayRunner.js +808 -110
- package/dist/scripts/signals.js +103 -27
- package/dist/scripts/signalsDaemon.js +103 -27
- package/package.json +7 -7
package/dist/lib/aiExport.js
CHANGED
|
@@ -41,6 +41,7 @@ var import_ai = require("@tradejs/infra/ai");
|
|
|
41
41
|
// src/lib/backtest/checkpoint.ts
|
|
42
42
|
var import_node_crypto = require("crypto");
|
|
43
43
|
var import_constants = require("@tradejs/core/constants");
|
|
44
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
44
45
|
var import_redis = require("@tradejs/infra/redis");
|
|
45
46
|
|
|
46
47
|
// src/lib/runFormatting.ts
|
package/dist/lib/coreResearch.js
CHANGED
|
@@ -61,6 +61,7 @@ var import_node_path2 = __toESM(require("path"));
|
|
|
61
61
|
var import_node_crypto = require("crypto");
|
|
62
62
|
var import_node_fs = require("fs");
|
|
63
63
|
var import_promises = __toESM(require("fs/promises"));
|
|
64
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
64
65
|
var import_node_path = __toESM(require("path"));
|
|
65
66
|
|
|
66
67
|
// src/lib/coreResearch/types.ts
|
|
@@ -189,6 +190,8 @@ var validateCoreResearchSpec = (value) => {
|
|
|
189
190
|
"variant ids must be unique"
|
|
190
191
|
);
|
|
191
192
|
for (const variant of spec.variants) {
|
|
193
|
+
if (variant.resolvedConfig)
|
|
194
|
+
(0, import_backtest.assertStrategyExecutionIsolation)(variant.resolvedConfig);
|
|
192
195
|
assert(
|
|
193
196
|
RESEARCH_ID_RE.test(variant.id),
|
|
194
197
|
`variant id ${variant.id} is invalid`
|
|
@@ -267,6 +270,7 @@ var validateCoreResearchSpec = (value) => {
|
|
|
267
270
|
}
|
|
268
271
|
}
|
|
269
272
|
}
|
|
273
|
+
(0, import_backtest.parseBacktestExecutionCosts)(spec.execution?.costs);
|
|
270
274
|
assertFinite(
|
|
271
275
|
spec.execution?.maxLossValue,
|
|
272
276
|
"execution.maxLossValue must be finite"
|
|
@@ -1804,6 +1808,7 @@ var buildCoreResearchHtml = (params) => {
|
|
|
1804
1808
|
// src/lib/backtest/checkpoint.ts
|
|
1805
1809
|
var import_node_crypto4 = require("crypto");
|
|
1806
1810
|
var import_constants = require("@tradejs/core/constants");
|
|
1811
|
+
var import_backtest2 = require("@tradejs/core/backtest");
|
|
1807
1812
|
var import_redis = require("@tradejs/infra/redis");
|
|
1808
1813
|
|
|
1809
1814
|
// src/lib/runFormatting.ts
|
|
@@ -1826,6 +1831,7 @@ var loadBacktestRunManifest = async ({
|
|
|
1826
1831
|
);
|
|
1827
1832
|
|
|
1828
1833
|
// src/lib/coreResearch/reconciliation.ts
|
|
1834
|
+
var import_backtest3 = require("@tradejs/core/backtest");
|
|
1829
1835
|
var finite = (value) => {
|
|
1830
1836
|
const numeric = Number(value);
|
|
1831
1837
|
return Number.isFinite(numeric) ? numeric : 0;
|
|
@@ -1890,6 +1896,25 @@ var reconcileCoreResearchVariant = async (params) => {
|
|
|
1890
1896
|
};
|
|
1891
1897
|
const pnlTolerance = completed.length * 5e-3 + 1e-9;
|
|
1892
1898
|
const reasons = [];
|
|
1899
|
+
for (const envelope of completed) {
|
|
1900
|
+
const model = envelope.result.executionCostModel;
|
|
1901
|
+
try {
|
|
1902
|
+
if (!model) throw new Error("missing");
|
|
1903
|
+
if (sha256Json((0, import_backtest3.executionCostsFromModel)(model)) !== sha256Json(params.spec.execution.costs)) {
|
|
1904
|
+
reasons.push(
|
|
1905
|
+
"executed costs do not match the preregistered execution costs"
|
|
1906
|
+
);
|
|
1907
|
+
break;
|
|
1908
|
+
}
|
|
1909
|
+
if (model.fees.source !== "config" || model.slippage.source !== "config" || model.funding.enabled && model.funding.source !== "historical") {
|
|
1910
|
+
reasons.push("execution cost provenance is not explicit or historical");
|
|
1911
|
+
break;
|
|
1912
|
+
}
|
|
1913
|
+
} catch {
|
|
1914
|
+
reasons.push("executed execution cost model is missing or invalid");
|
|
1915
|
+
break;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1893
1918
|
if (manifest.status !== "completed") {
|
|
1894
1919
|
reasons.push(`manifest status is ${manifest.status}`);
|
|
1895
1920
|
}
|
|
@@ -2539,8 +2564,16 @@ var createCoreResearchSpecTemplate = (params) => {
|
|
|
2539
2564
|
connector: "ByBit",
|
|
2540
2565
|
interval: "15",
|
|
2541
2566
|
maxLossValue: 10,
|
|
2542
|
-
|
|
2543
|
-
|
|
2567
|
+
costs: {
|
|
2568
|
+
fees: { makerRate: 1e-3, takerRate: 1e-3 },
|
|
2569
|
+
slippage: {
|
|
2570
|
+
baseBps: 10,
|
|
2571
|
+
spreadMultiplier: 1,
|
|
2572
|
+
marketImpactBps: 0,
|
|
2573
|
+
delayRiskMultiplier: 0
|
|
2574
|
+
},
|
|
2575
|
+
funding: { enabled: false }
|
|
2576
|
+
},
|
|
2544
2577
|
entryDelayBars: 1
|
|
2545
2578
|
},
|
|
2546
2579
|
variants: [
|
|
@@ -2653,6 +2686,8 @@ var validateCoreResearchRunCommand = (params) => {
|
|
|
2653
2686
|
const { spec, variant } = params;
|
|
2654
2687
|
const command = variant.command ?? [];
|
|
2655
2688
|
const failures = [];
|
|
2689
|
+
if (commandHas(command, ["--executionCosts"]))
|
|
2690
|
+
failures.push("executionCosts is owned by the research spec");
|
|
2656
2691
|
if (!commandHas(command, ["--ai", "-A"])) failures.push("--ai");
|
|
2657
2692
|
if (!commandHas(command, ["--fast"])) failures.push("--fast");
|
|
2658
2693
|
if (!commandHas(command, ["--cacheOnly", "-C"])) failures.push("--cacheOnly");
|
|
@@ -2704,7 +2739,11 @@ var runCoreResearch = async (params) => {
|
|
|
2704
2739
|
);
|
|
2705
2740
|
try {
|
|
2706
2741
|
await runCommand({
|
|
2707
|
-
command:
|
|
2742
|
+
command: [
|
|
2743
|
+
...variant.command,
|
|
2744
|
+
"--executionCosts",
|
|
2745
|
+
JSON.stringify(spec.execution.costs)
|
|
2746
|
+
],
|
|
2708
2747
|
cwd,
|
|
2709
2748
|
logPath: backtestLogPath,
|
|
2710
2749
|
env: {
|
package/dist/scripts/aiExport.js
CHANGED
|
@@ -47,6 +47,7 @@ var import_ai = require("@tradejs/infra/ai");
|
|
|
47
47
|
// src/lib/backtest/checkpoint.ts
|
|
48
48
|
var import_node_crypto = require("crypto");
|
|
49
49
|
var import_constants = require("@tradejs/core/constants");
|
|
50
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
50
51
|
var import_redis = require("@tradejs/infra/redis");
|
|
51
52
|
|
|
52
53
|
// src/lib/runFormatting.ts
|
package/dist/scripts/backtest.js
CHANGED
|
@@ -59,7 +59,7 @@ module.exports = __toCommonJS(backtest_exports);
|
|
|
59
59
|
var import_fs2 = __toESM(require("fs"));
|
|
60
60
|
var import_path2 = __toESM(require("path"));
|
|
61
61
|
var import_chalk10 = __toESM(require("chalk"));
|
|
62
|
-
var
|
|
62
|
+
var import_backtest3 = require("@tradejs/core/backtest");
|
|
63
63
|
var import_grid = require("@tradejs/core/grid");
|
|
64
64
|
var import_data = require("@tradejs/core/data");
|
|
65
65
|
var import_redis5 = require("@tradejs/infra/redis");
|
|
@@ -69,7 +69,7 @@ var import_constants6 = require("@tradejs/core/constants");
|
|
|
69
69
|
var import_fs = __toESM(require("fs"));
|
|
70
70
|
var import_path = __toESM(require("path"));
|
|
71
71
|
var import_chalk9 = __toESM(require("chalk"));
|
|
72
|
-
var
|
|
72
|
+
var import_backtest2 = require("@tradejs/core/backtest");
|
|
73
73
|
var import_constants5 = require("@tradejs/core/constants");
|
|
74
74
|
var import_time3 = require("@tradejs/core/time");
|
|
75
75
|
var import_backtestArtifacts = require("@tradejs/infra/backtestArtifacts");
|
|
@@ -4210,6 +4210,10 @@ import_args.default.example(
|
|
|
4210
4210
|
"Run tests on uploaded data for 400 tickers"
|
|
4211
4211
|
);
|
|
4212
4212
|
import_args.default.option(["t", "tickers"], "Selected tickers");
|
|
4213
|
+
import_args.default.option(
|
|
4214
|
+
["J", "executionCosts"],
|
|
4215
|
+
"Explicit execution costs JSON: fees, slippage and funding"
|
|
4216
|
+
);
|
|
4213
4217
|
import_args.default.option(["e", "exclude"], "Exclude tickers from tests");
|
|
4214
4218
|
import_args.default.option(["l", "tickersLimit"], "Tickers limit");
|
|
4215
4219
|
import_args.default.option(["n", "tests"], "Tests limit", import_constants3.TESTS_LIMIT);
|
|
@@ -4344,7 +4348,18 @@ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || pro
|
|
|
4344
4348
|
// src/lib/backtest/checkpoint.ts
|
|
4345
4349
|
var import_node_crypto = require("crypto");
|
|
4346
4350
|
var import_constants4 = require("@tradejs/core/constants");
|
|
4351
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
4347
4352
|
var import_redis3 = require("@tradejs/infra/redis");
|
|
4353
|
+
var assertFrozenBacktestExecutionCosts = (testSuite) => {
|
|
4354
|
+
for (const test of testSuite) {
|
|
4355
|
+
if (test.executionCosts == null) {
|
|
4356
|
+
throw new Error(
|
|
4357
|
+
"Cannot continue a run without frozen executionCosts; start a new run with --executionCosts"
|
|
4358
|
+
);
|
|
4359
|
+
}
|
|
4360
|
+
(0, import_backtest.parseBacktestExecutionCosts)(test.executionCosts);
|
|
4361
|
+
}
|
|
4362
|
+
};
|
|
4348
4363
|
var toStableJson = (value) => {
|
|
4349
4364
|
if (value == null || typeof value !== "object") {
|
|
4350
4365
|
return JSON.stringify(value);
|
|
@@ -4366,6 +4381,8 @@ var buildBacktestTestKey = (test) => hashValue({
|
|
|
4366
4381
|
researchTrace: Boolean(test.researchTrace),
|
|
4367
4382
|
options: test.options,
|
|
4368
4383
|
strategyConfig: test.strategyConfig,
|
|
4384
|
+
executionCosts: test.executionCosts,
|
|
4385
|
+
executionCostsCacheOnly: Boolean(test.executionCostsCacheOnly),
|
|
4369
4386
|
strategyName: test.strategyName,
|
|
4370
4387
|
symbol: test.symbol,
|
|
4371
4388
|
userName: test.userName
|
|
@@ -4991,7 +5008,7 @@ var setTestData = async (test, stat, orderLog) => {
|
|
|
4991
5008
|
}
|
|
4992
5009
|
)
|
|
4993
5010
|
]);
|
|
4994
|
-
const { testId } = (0,
|
|
5011
|
+
const { testId } = (0, import_backtest2.parseTestName)(test.name);
|
|
4995
5012
|
setPersistedTestSummary(`${test.strategyName}:${test.name}`, {
|
|
4996
5013
|
value: test.name,
|
|
4997
5014
|
label: `${test.symbol}_${testId}`,
|
|
@@ -5075,6 +5092,9 @@ var buildPreparedTestSuite = async ({
|
|
|
5075
5092
|
isReplay
|
|
5076
5093
|
}) => {
|
|
5077
5094
|
const mlEnabled = Boolean(flags.ml);
|
|
5095
|
+
const executionCosts = flags.executionCosts == null ? void 0 : (0, import_backtest2.parseBacktestExecutionCosts)(JSON.parse(String(flags.executionCosts)));
|
|
5096
|
+
for (const test of testSuite)
|
|
5097
|
+
(0, import_backtest2.assertStrategyExecutionIsolation)(test.strategyConfig);
|
|
5078
5098
|
const aiEnabled = Boolean(flags.ai);
|
|
5079
5099
|
const requestedTestsLimit = resolveRequestedTestsLimit({
|
|
5080
5100
|
isLiveMode: isReplay,
|
|
@@ -5084,6 +5104,8 @@ var buildPreparedTestSuite = async ({
|
|
|
5084
5104
|
const preparedSuite = testSuite.map((test) => ({
|
|
5085
5105
|
...test,
|
|
5086
5106
|
interval,
|
|
5107
|
+
executionCosts: executionCosts ?? test.executionCosts,
|
|
5108
|
+
executionCostsCacheOnly: Boolean(flags.cacheOnly),
|
|
5087
5109
|
strategyConfig: {
|
|
5088
5110
|
...test.strategyConfig,
|
|
5089
5111
|
ENV: "BACKTEST",
|
|
@@ -5091,8 +5113,7 @@ var buildPreparedTestSuite = async ({
|
|
|
5091
5113
|
MAKE_ORDERS: true,
|
|
5092
5114
|
CLOSE_OPPOSITE_POSITIONS: false,
|
|
5093
5115
|
BACKTEST_PRICE_MODE: backtestPriceMode,
|
|
5094
|
-
BACKTEST_ENTRY_DELAY_BARS: backtestEntryDelayBars
|
|
5095
|
-
...flags.cacheOnly ? { EXECUTION_COSTS_CACHE_ONLY: true } : {}
|
|
5116
|
+
BACKTEST_ENTRY_DELAY_BARS: backtestEntryDelayBars
|
|
5096
5117
|
},
|
|
5097
5118
|
options: {
|
|
5098
5119
|
start: window.start,
|
|
@@ -5294,6 +5315,8 @@ var toPersistedBacktestResultEntry = (result) => ({
|
|
|
5294
5315
|
symbol: result.test.symbol,
|
|
5295
5316
|
strategyName: result.test.strategyName,
|
|
5296
5317
|
strategyConfig: result.test.strategyConfig,
|
|
5318
|
+
executionCosts: result.test.executionCosts,
|
|
5319
|
+
executionCostsCacheOnly: result.test.executionCostsCacheOnly,
|
|
5297
5320
|
connectorName: result.test.connectorName,
|
|
5298
5321
|
universe: result.test.universe,
|
|
5299
5322
|
assetClass: result.test.assetClass,
|
|
@@ -5322,7 +5345,7 @@ var resolveRenderableStat = async (result) => {
|
|
|
5322
5345
|
hasArtifacts: false
|
|
5323
5346
|
};
|
|
5324
5347
|
}
|
|
5325
|
-
const stat = (0,
|
|
5348
|
+
const stat = (0, import_backtest3.calculateStatsFull)(positionLog);
|
|
5326
5349
|
if (!stat && fallbackStat.orders > 0) {
|
|
5327
5350
|
throw new Error(
|
|
5328
5351
|
`Position log is empty for ${name} despite ${fallbackStat.orders} closed orders`
|
|
@@ -5592,6 +5615,11 @@ var loadBacktestRunForContinue = async () => {
|
|
|
5592
5615
|
if (!flags.continue) {
|
|
5593
5616
|
return null;
|
|
5594
5617
|
}
|
|
5618
|
+
if (flags.executionCosts != null) {
|
|
5619
|
+
throw new Error(
|
|
5620
|
+
"A continued run uses its frozen executionCosts; start a new run to change costs"
|
|
5621
|
+
);
|
|
5622
|
+
}
|
|
5595
5623
|
const runId = await resolveBacktestRunIdForContinue({
|
|
5596
5624
|
config: flags.config,
|
|
5597
5625
|
requestedRunId: typeof flags.runId === "string" ? flags.runId : void 0,
|
|
@@ -5606,6 +5634,7 @@ var loadBacktestRunForContinue = async () => {
|
|
|
5606
5634
|
if (!manifest) {
|
|
5607
5635
|
throw new Error(`Backtest run "${runId}" was not found`);
|
|
5608
5636
|
}
|
|
5637
|
+
assertFrozenBacktestExecutionCosts(manifest.testSuite);
|
|
5609
5638
|
if (manifest.userName !== userName) {
|
|
5610
5639
|
throw new Error(
|
|
5611
5640
|
`Backtest run "${runId}" belongs to user "${manifest.userName}", not "${userName}"`
|
|
@@ -41,6 +41,7 @@ var import_chalk = __toESM(require("chalk"));
|
|
|
41
41
|
var import_node_crypto = require("crypto");
|
|
42
42
|
var import_node_fs = require("fs");
|
|
43
43
|
var import_promises = __toESM(require("fs/promises"));
|
|
44
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
44
45
|
var import_node_path = __toESM(require("path"));
|
|
45
46
|
|
|
46
47
|
// src/lib/coreResearch/types.ts
|
|
@@ -169,6 +170,8 @@ var validateCoreResearchSpec = (value) => {
|
|
|
169
170
|
"variant ids must be unique"
|
|
170
171
|
);
|
|
171
172
|
for (const variant of spec.variants) {
|
|
173
|
+
if (variant.resolvedConfig)
|
|
174
|
+
(0, import_backtest.assertStrategyExecutionIsolation)(variant.resolvedConfig);
|
|
172
175
|
assert(
|
|
173
176
|
RESEARCH_ID_RE.test(variant.id),
|
|
174
177
|
`variant id ${variant.id} is invalid`
|
|
@@ -247,6 +250,7 @@ var validateCoreResearchSpec = (value) => {
|
|
|
247
250
|
}
|
|
248
251
|
}
|
|
249
252
|
}
|
|
253
|
+
(0, import_backtest.parseBacktestExecutionCosts)(spec.execution?.costs);
|
|
250
254
|
assertFinite(
|
|
251
255
|
spec.execution?.maxLossValue,
|
|
252
256
|
"execution.maxLossValue must be finite"
|
|
@@ -1795,6 +1799,7 @@ var buildCoreResearchHtml = (params) => {
|
|
|
1795
1799
|
// src/lib/backtest/checkpoint.ts
|
|
1796
1800
|
var import_node_crypto4 = require("crypto");
|
|
1797
1801
|
var import_constants = require("@tradejs/core/constants");
|
|
1802
|
+
var import_backtest2 = require("@tradejs/core/backtest");
|
|
1798
1803
|
var import_redis = require("@tradejs/infra/redis");
|
|
1799
1804
|
|
|
1800
1805
|
// src/lib/runFormatting.ts
|
|
@@ -1817,6 +1822,7 @@ var loadBacktestRunManifest = async ({
|
|
|
1817
1822
|
);
|
|
1818
1823
|
|
|
1819
1824
|
// src/lib/coreResearch/reconciliation.ts
|
|
1825
|
+
var import_backtest3 = require("@tradejs/core/backtest");
|
|
1820
1826
|
var finite = (value) => {
|
|
1821
1827
|
const numeric = Number(value);
|
|
1822
1828
|
return Number.isFinite(numeric) ? numeric : 0;
|
|
@@ -1881,6 +1887,25 @@ var reconcileCoreResearchVariant = async (params) => {
|
|
|
1881
1887
|
};
|
|
1882
1888
|
const pnlTolerance = completed.length * 5e-3 + 1e-9;
|
|
1883
1889
|
const reasons = [];
|
|
1890
|
+
for (const envelope of completed) {
|
|
1891
|
+
const model = envelope.result.executionCostModel;
|
|
1892
|
+
try {
|
|
1893
|
+
if (!model) throw new Error("missing");
|
|
1894
|
+
if (sha256Json((0, import_backtest3.executionCostsFromModel)(model)) !== sha256Json(params.spec.execution.costs)) {
|
|
1895
|
+
reasons.push(
|
|
1896
|
+
"executed costs do not match the preregistered execution costs"
|
|
1897
|
+
);
|
|
1898
|
+
break;
|
|
1899
|
+
}
|
|
1900
|
+
if (model.fees.source !== "config" || model.slippage.source !== "config" || model.funding.enabled && model.funding.source !== "historical") {
|
|
1901
|
+
reasons.push("execution cost provenance is not explicit or historical");
|
|
1902
|
+
break;
|
|
1903
|
+
}
|
|
1904
|
+
} catch {
|
|
1905
|
+
reasons.push("executed execution cost model is missing or invalid");
|
|
1906
|
+
break;
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1884
1909
|
if (manifest.status !== "completed") {
|
|
1885
1910
|
reasons.push(`manifest status is ${manifest.status}`);
|
|
1886
1911
|
}
|
|
@@ -2558,8 +2583,16 @@ var createCoreResearchSpecTemplate = (params) => {
|
|
|
2558
2583
|
connector: "ByBit",
|
|
2559
2584
|
interval: "15",
|
|
2560
2585
|
maxLossValue: 10,
|
|
2561
|
-
|
|
2562
|
-
|
|
2586
|
+
costs: {
|
|
2587
|
+
fees: { makerRate: 1e-3, takerRate: 1e-3 },
|
|
2588
|
+
slippage: {
|
|
2589
|
+
baseBps: 10,
|
|
2590
|
+
spreadMultiplier: 1,
|
|
2591
|
+
marketImpactBps: 0,
|
|
2592
|
+
delayRiskMultiplier: 0
|
|
2593
|
+
},
|
|
2594
|
+
funding: { enabled: false }
|
|
2595
|
+
},
|
|
2563
2596
|
entryDelayBars: 1
|
|
2564
2597
|
},
|
|
2565
2598
|
variants: [
|
|
@@ -2672,6 +2705,8 @@ var validateCoreResearchRunCommand = (params) => {
|
|
|
2672
2705
|
const { spec, variant } = params;
|
|
2673
2706
|
const command = variant.command ?? [];
|
|
2674
2707
|
const failures = [];
|
|
2708
|
+
if (commandHas(command, ["--executionCosts"]))
|
|
2709
|
+
failures.push("executionCosts is owned by the research spec");
|
|
2675
2710
|
if (!commandHas(command, ["--ai", "-A"])) failures.push("--ai");
|
|
2676
2711
|
if (!commandHas(command, ["--fast"])) failures.push("--fast");
|
|
2677
2712
|
if (!commandHas(command, ["--cacheOnly", "-C"])) failures.push("--cacheOnly");
|
|
@@ -2723,7 +2758,11 @@ var runCoreResearch = async (params) => {
|
|
|
2723
2758
|
);
|
|
2724
2759
|
try {
|
|
2725
2760
|
await runCommand({
|
|
2726
|
-
command:
|
|
2761
|
+
command: [
|
|
2762
|
+
...variant.command,
|
|
2763
|
+
"--executionCosts",
|
|
2764
|
+
JSON.stringify(spec.execution.costs)
|
|
2765
|
+
],
|
|
2727
2766
|
cwd,
|
|
2728
2767
|
logPath: backtestLogPath,
|
|
2729
2768
|
env: {
|
package/dist/scripts/mlExport.js
CHANGED
|
@@ -42,6 +42,7 @@ var import_ml = require("@tradejs/infra/ml");
|
|
|
42
42
|
// src/lib/backtest/checkpoint.ts
|
|
43
43
|
var import_node_crypto = require("crypto");
|
|
44
44
|
var import_constants = require("@tradejs/core/constants");
|
|
45
|
+
var import_backtest = require("@tradejs/core/backtest");
|
|
45
46
|
var import_redis = require("@tradejs/infra/redis");
|
|
46
47
|
|
|
47
48
|
// src/lib/runFormatting.ts
|