@tradejs/infra 1.0.9 → 1.0.11
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/ai.d.mts +39 -3
- package/dist/ai.d.ts +39 -3
- package/dist/ai.js +404 -28
- package/dist/ai.mjs +372 -24
- package/dist/backtestArtifacts.d.mts +57 -0
- package/dist/backtestArtifacts.d.ts +57 -0
- package/dist/backtestArtifacts.js +255 -0
- package/dist/backtestArtifacts.mjs +211 -0
- package/dist/{chunk-KVEZORMS.mjs → chunk-RQP5VSTH.mjs} +54 -3
- package/dist/{chunk-MLVWC2I2.mjs → chunk-XZQ6COOV.mjs} +62 -5
- package/dist/ml.d.mts +1 -1
- package/dist/ml.d.ts +1 -1
- package/dist/ml.js +55 -3
- package/dist/ml.mjs +3 -1
- package/dist/{mlDatasetFile-sRGWgR_o.d.mts → mlDatasetFile-Czx__g9M.d.mts} +7 -1
- package/dist/{mlDatasetFile-sRGWgR_o.d.ts → mlDatasetFile-Czx__g9M.d.ts} +7 -1
- package/dist/redis.d.mts +23 -3
- package/dist/redis.d.ts +23 -3
- package/dist/redis.js +65 -5
- package/dist/redis.mjs +7 -1
- package/dist/timescale.d.mts +221 -5
- package/dist/timescale.d.ts +221 -5
- package/dist/timescale.js +2022 -93
- package/dist/timescale.mjs +1994 -93
- package/dist/tradingAccounts.d.mts +20 -0
- package/dist/tradingAccounts.d.ts +20 -0
- package/dist/tradingAccounts.js +558 -0
- package/dist/tradingAccounts.mjs +190 -0
- package/dist/userSettings.d.mts +2 -0
- package/dist/userSettings.d.ts +2 -0
- package/dist/userSettings.js +26 -5
- package/dist/userSettings.mjs +2 -1
- package/package.json +13 -3
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/backtestArtifacts.ts
|
|
31
|
+
var backtestArtifacts_exports = {};
|
|
32
|
+
__export(backtestArtifacts_exports, {
|
|
33
|
+
deleteCachedBacktestArtifacts: () => deleteCachedBacktestArtifacts,
|
|
34
|
+
deletePersistedBacktestOrderLog: () => deletePersistedBacktestOrderLog,
|
|
35
|
+
getBacktestArtifactsRootDir: () => getBacktestArtifactsRootDir,
|
|
36
|
+
getBacktestCacheArtifactsDirForUser: () => getBacktestCacheArtifactsDirForUser,
|
|
37
|
+
getPersistedBacktestArtifactsDirForUser: () => getPersistedBacktestArtifactsDirForUser,
|
|
38
|
+
parseBacktestArtifactRef: () => parseBacktestArtifactRef,
|
|
39
|
+
readCachedBacktestArtifacts: () => readCachedBacktestArtifacts,
|
|
40
|
+
readPersistedBacktestOrderLog: () => readPersistedBacktestOrderLog,
|
|
41
|
+
writeCachedBacktestArtifacts: () => writeCachedBacktestArtifacts,
|
|
42
|
+
writePersistedBacktestOrderLog: () => writePersistedBacktestOrderLog
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(backtestArtifacts_exports);
|
|
45
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
46
|
+
var import_path = __toESM(require("path"));
|
|
47
|
+
var BACKTEST_ARTIFACTS_DIR = import_path.default.join("data", "backtests");
|
|
48
|
+
var resolveProjectRoot = (projectRoot) => {
|
|
49
|
+
const explicit = String(projectRoot || "").trim();
|
|
50
|
+
if (explicit) {
|
|
51
|
+
return import_path.default.resolve(explicit);
|
|
52
|
+
}
|
|
53
|
+
const fromEnv = String(process.env.PROJECT_CWD || "").trim();
|
|
54
|
+
if (fromEnv) {
|
|
55
|
+
return import_path.default.resolve(fromEnv);
|
|
56
|
+
}
|
|
57
|
+
return process.cwd();
|
|
58
|
+
};
|
|
59
|
+
var encodeSegment = (value) => encodeURIComponent(String(value));
|
|
60
|
+
var toProjectRelativePath = (projectRoot, absolutePath) => import_path.default.relative(projectRoot, absolutePath);
|
|
61
|
+
var resolveArtifactPath = (relativePath, projectRoot) => {
|
|
62
|
+
const root = resolveProjectRoot(projectRoot);
|
|
63
|
+
return import_path.default.isAbsolute(relativePath) ? relativePath : import_path.default.resolve(root, relativePath);
|
|
64
|
+
};
|
|
65
|
+
var isEnoentError = (error) => error?.code === "ENOENT";
|
|
66
|
+
var createRef = (absolutePath, projectRoot) => ({
|
|
67
|
+
kind: "file",
|
|
68
|
+
version: 1,
|
|
69
|
+
path: toProjectRelativePath(resolveProjectRoot(projectRoot), absolutePath)
|
|
70
|
+
});
|
|
71
|
+
var isBacktestArtifactRef = (value) => Boolean(
|
|
72
|
+
value && typeof value === "object" && value.kind === "file" && value.version === 1 && typeof value.path === "string"
|
|
73
|
+
);
|
|
74
|
+
var getCachedArtifactPath = (userName, orderLogId, artifactName, projectRoot) => import_path.default.join(
|
|
75
|
+
resolveProjectRoot(projectRoot),
|
|
76
|
+
BACKTEST_ARTIFACTS_DIR,
|
|
77
|
+
"cache",
|
|
78
|
+
encodeSegment(userName),
|
|
79
|
+
artifactName,
|
|
80
|
+
`${encodeSegment(orderLogId)}.json`
|
|
81
|
+
);
|
|
82
|
+
var getPersistedOrderLogPath = (userName, strategyName, testName, projectRoot) => import_path.default.join(
|
|
83
|
+
resolveProjectRoot(projectRoot),
|
|
84
|
+
BACKTEST_ARTIFACTS_DIR,
|
|
85
|
+
"tests",
|
|
86
|
+
encodeSegment(userName),
|
|
87
|
+
encodeSegment(strategyName),
|
|
88
|
+
`${encodeSegment(testName)}.json`
|
|
89
|
+
);
|
|
90
|
+
var readJsonFile = async (absolutePath, fallback) => {
|
|
91
|
+
try {
|
|
92
|
+
const raw = await import_promises.default.readFile(absolutePath, "utf8");
|
|
93
|
+
return JSON.parse(raw);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (isEnoentError(error)) {
|
|
96
|
+
return fallback;
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var writeJsonFile = async (absolutePath, value) => {
|
|
102
|
+
await import_promises.default.mkdir(import_path.default.dirname(absolutePath), { recursive: true });
|
|
103
|
+
await import_promises.default.writeFile(absolutePath, JSON.stringify(value), "utf8");
|
|
104
|
+
};
|
|
105
|
+
var removeFileIfExists = async (absolutePath) => {
|
|
106
|
+
try {
|
|
107
|
+
await import_promises.default.rm(absolutePath, { force: true });
|
|
108
|
+
return true;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (isEnoentError(error)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var writeCachedBacktestArtifacts = async ({
|
|
117
|
+
orderLog,
|
|
118
|
+
orderLogId,
|
|
119
|
+
positionLog,
|
|
120
|
+
projectRoot,
|
|
121
|
+
userName
|
|
122
|
+
}) => {
|
|
123
|
+
const orderPath = getCachedArtifactPath(
|
|
124
|
+
userName,
|
|
125
|
+
orderLogId,
|
|
126
|
+
"orders",
|
|
127
|
+
projectRoot
|
|
128
|
+
);
|
|
129
|
+
const positionPath = getCachedArtifactPath(
|
|
130
|
+
userName,
|
|
131
|
+
orderLogId,
|
|
132
|
+
"positions",
|
|
133
|
+
projectRoot
|
|
134
|
+
);
|
|
135
|
+
await Promise.all([
|
|
136
|
+
writeJsonFile(orderPath, orderLog),
|
|
137
|
+
writeJsonFile(positionPath, positionLog)
|
|
138
|
+
]);
|
|
139
|
+
return {
|
|
140
|
+
orderLog: createRef(orderPath, projectRoot),
|
|
141
|
+
positionLog: createRef(positionPath, projectRoot)
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
var readCachedBacktestArtifacts = async ({
|
|
145
|
+
orderLogId,
|
|
146
|
+
projectRoot,
|
|
147
|
+
userName
|
|
148
|
+
}) => {
|
|
149
|
+
const orderPath = getCachedArtifactPath(
|
|
150
|
+
userName,
|
|
151
|
+
orderLogId,
|
|
152
|
+
"orders",
|
|
153
|
+
projectRoot
|
|
154
|
+
);
|
|
155
|
+
const positionPath = getCachedArtifactPath(
|
|
156
|
+
userName,
|
|
157
|
+
orderLogId,
|
|
158
|
+
"positions",
|
|
159
|
+
projectRoot
|
|
160
|
+
);
|
|
161
|
+
const [orderLog, positionLog] = await Promise.all([
|
|
162
|
+
readJsonFile(orderPath, null),
|
|
163
|
+
readJsonFile(positionPath, null)
|
|
164
|
+
]);
|
|
165
|
+
return { orderLog, positionLog };
|
|
166
|
+
};
|
|
167
|
+
var deleteCachedBacktestArtifacts = async ({
|
|
168
|
+
orderLogId,
|
|
169
|
+
projectRoot,
|
|
170
|
+
userName
|
|
171
|
+
}) => {
|
|
172
|
+
const orderPath = getCachedArtifactPath(
|
|
173
|
+
userName,
|
|
174
|
+
orderLogId,
|
|
175
|
+
"orders",
|
|
176
|
+
projectRoot
|
|
177
|
+
);
|
|
178
|
+
const positionPath = getCachedArtifactPath(
|
|
179
|
+
userName,
|
|
180
|
+
orderLogId,
|
|
181
|
+
"positions",
|
|
182
|
+
projectRoot
|
|
183
|
+
);
|
|
184
|
+
const [removedOrderLog, removedPositionLog] = await Promise.all([
|
|
185
|
+
removeFileIfExists(orderPath),
|
|
186
|
+
removeFileIfExists(positionPath)
|
|
187
|
+
]);
|
|
188
|
+
return removedOrderLog || removedPositionLog;
|
|
189
|
+
};
|
|
190
|
+
var writePersistedBacktestOrderLog = async ({
|
|
191
|
+
orderLog,
|
|
192
|
+
projectRoot,
|
|
193
|
+
strategyName,
|
|
194
|
+
testName,
|
|
195
|
+
userName
|
|
196
|
+
}) => {
|
|
197
|
+
const absolutePath = getPersistedOrderLogPath(
|
|
198
|
+
userName,
|
|
199
|
+
strategyName,
|
|
200
|
+
testName,
|
|
201
|
+
projectRoot
|
|
202
|
+
);
|
|
203
|
+
await writeJsonFile(absolutePath, orderLog);
|
|
204
|
+
return createRef(absolutePath, projectRoot);
|
|
205
|
+
};
|
|
206
|
+
var readPersistedBacktestOrderLog = async ({
|
|
207
|
+
projectRoot,
|
|
208
|
+
ref,
|
|
209
|
+
strategyName,
|
|
210
|
+
testName,
|
|
211
|
+
userName
|
|
212
|
+
}) => {
|
|
213
|
+
const absolutePath = ref ? resolveArtifactPath(ref.path, projectRoot) : getPersistedOrderLogPath(userName, strategyName, testName, projectRoot);
|
|
214
|
+
return readJsonFile(absolutePath, null);
|
|
215
|
+
};
|
|
216
|
+
var deletePersistedBacktestOrderLog = async ({
|
|
217
|
+
projectRoot,
|
|
218
|
+
ref,
|
|
219
|
+
strategyName,
|
|
220
|
+
testName,
|
|
221
|
+
userName
|
|
222
|
+
}) => {
|
|
223
|
+
const absolutePath = ref ? resolveArtifactPath(ref.path, projectRoot) : getPersistedOrderLogPath(userName, strategyName, testName, projectRoot);
|
|
224
|
+
return removeFileIfExists(absolutePath);
|
|
225
|
+
};
|
|
226
|
+
var parseBacktestArtifactRef = (value) => {
|
|
227
|
+
if (isBacktestArtifactRef(value)) {
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
};
|
|
232
|
+
var getBacktestArtifactsRootDir = (projectRoot) => import_path.default.join(resolveProjectRoot(projectRoot), BACKTEST_ARTIFACTS_DIR);
|
|
233
|
+
var getBacktestCacheArtifactsDirForUser = (userName, projectRoot) => import_path.default.join(
|
|
234
|
+
getBacktestArtifactsRootDir(projectRoot),
|
|
235
|
+
"cache",
|
|
236
|
+
encodeSegment(userName)
|
|
237
|
+
);
|
|
238
|
+
var getPersistedBacktestArtifactsDirForUser = (userName, projectRoot) => import_path.default.join(
|
|
239
|
+
getBacktestArtifactsRootDir(projectRoot),
|
|
240
|
+
"tests",
|
|
241
|
+
encodeSegment(userName)
|
|
242
|
+
);
|
|
243
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
244
|
+
0 && (module.exports = {
|
|
245
|
+
deleteCachedBacktestArtifacts,
|
|
246
|
+
deletePersistedBacktestOrderLog,
|
|
247
|
+
getBacktestArtifactsRootDir,
|
|
248
|
+
getBacktestCacheArtifactsDirForUser,
|
|
249
|
+
getPersistedBacktestArtifactsDirForUser,
|
|
250
|
+
parseBacktestArtifactRef,
|
|
251
|
+
readCachedBacktestArtifacts,
|
|
252
|
+
readPersistedBacktestOrderLog,
|
|
253
|
+
writeCachedBacktestArtifacts,
|
|
254
|
+
writePersistedBacktestOrderLog
|
|
255
|
+
});
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// src/backtestArtifacts.ts
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var BACKTEST_ARTIFACTS_DIR = path.join("data", "backtests");
|
|
5
|
+
var resolveProjectRoot = (projectRoot) => {
|
|
6
|
+
const explicit = String(projectRoot || "").trim();
|
|
7
|
+
if (explicit) {
|
|
8
|
+
return path.resolve(explicit);
|
|
9
|
+
}
|
|
10
|
+
const fromEnv = String(process.env.PROJECT_CWD || "").trim();
|
|
11
|
+
if (fromEnv) {
|
|
12
|
+
return path.resolve(fromEnv);
|
|
13
|
+
}
|
|
14
|
+
return process.cwd();
|
|
15
|
+
};
|
|
16
|
+
var encodeSegment = (value) => encodeURIComponent(String(value));
|
|
17
|
+
var toProjectRelativePath = (projectRoot, absolutePath) => path.relative(projectRoot, absolutePath);
|
|
18
|
+
var resolveArtifactPath = (relativePath, projectRoot) => {
|
|
19
|
+
const root = resolveProjectRoot(projectRoot);
|
|
20
|
+
return path.isAbsolute(relativePath) ? relativePath : path.resolve(root, relativePath);
|
|
21
|
+
};
|
|
22
|
+
var isEnoentError = (error) => error?.code === "ENOENT";
|
|
23
|
+
var createRef = (absolutePath, projectRoot) => ({
|
|
24
|
+
kind: "file",
|
|
25
|
+
version: 1,
|
|
26
|
+
path: toProjectRelativePath(resolveProjectRoot(projectRoot), absolutePath)
|
|
27
|
+
});
|
|
28
|
+
var isBacktestArtifactRef = (value) => Boolean(
|
|
29
|
+
value && typeof value === "object" && value.kind === "file" && value.version === 1 && typeof value.path === "string"
|
|
30
|
+
);
|
|
31
|
+
var getCachedArtifactPath = (userName, orderLogId, artifactName, projectRoot) => path.join(
|
|
32
|
+
resolveProjectRoot(projectRoot),
|
|
33
|
+
BACKTEST_ARTIFACTS_DIR,
|
|
34
|
+
"cache",
|
|
35
|
+
encodeSegment(userName),
|
|
36
|
+
artifactName,
|
|
37
|
+
`${encodeSegment(orderLogId)}.json`
|
|
38
|
+
);
|
|
39
|
+
var getPersistedOrderLogPath = (userName, strategyName, testName, projectRoot) => path.join(
|
|
40
|
+
resolveProjectRoot(projectRoot),
|
|
41
|
+
BACKTEST_ARTIFACTS_DIR,
|
|
42
|
+
"tests",
|
|
43
|
+
encodeSegment(userName),
|
|
44
|
+
encodeSegment(strategyName),
|
|
45
|
+
`${encodeSegment(testName)}.json`
|
|
46
|
+
);
|
|
47
|
+
var readJsonFile = async (absolutePath, fallback) => {
|
|
48
|
+
try {
|
|
49
|
+
const raw = await fs.readFile(absolutePath, "utf8");
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (isEnoentError(error)) {
|
|
53
|
+
return fallback;
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var writeJsonFile = async (absolutePath, value) => {
|
|
59
|
+
await fs.mkdir(path.dirname(absolutePath), { recursive: true });
|
|
60
|
+
await fs.writeFile(absolutePath, JSON.stringify(value), "utf8");
|
|
61
|
+
};
|
|
62
|
+
var removeFileIfExists = async (absolutePath) => {
|
|
63
|
+
try {
|
|
64
|
+
await fs.rm(absolutePath, { force: true });
|
|
65
|
+
return true;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (isEnoentError(error)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var writeCachedBacktestArtifacts = async ({
|
|
74
|
+
orderLog,
|
|
75
|
+
orderLogId,
|
|
76
|
+
positionLog,
|
|
77
|
+
projectRoot,
|
|
78
|
+
userName
|
|
79
|
+
}) => {
|
|
80
|
+
const orderPath = getCachedArtifactPath(
|
|
81
|
+
userName,
|
|
82
|
+
orderLogId,
|
|
83
|
+
"orders",
|
|
84
|
+
projectRoot
|
|
85
|
+
);
|
|
86
|
+
const positionPath = getCachedArtifactPath(
|
|
87
|
+
userName,
|
|
88
|
+
orderLogId,
|
|
89
|
+
"positions",
|
|
90
|
+
projectRoot
|
|
91
|
+
);
|
|
92
|
+
await Promise.all([
|
|
93
|
+
writeJsonFile(orderPath, orderLog),
|
|
94
|
+
writeJsonFile(positionPath, positionLog)
|
|
95
|
+
]);
|
|
96
|
+
return {
|
|
97
|
+
orderLog: createRef(orderPath, projectRoot),
|
|
98
|
+
positionLog: createRef(positionPath, projectRoot)
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
var readCachedBacktestArtifacts = async ({
|
|
102
|
+
orderLogId,
|
|
103
|
+
projectRoot,
|
|
104
|
+
userName
|
|
105
|
+
}) => {
|
|
106
|
+
const orderPath = getCachedArtifactPath(
|
|
107
|
+
userName,
|
|
108
|
+
orderLogId,
|
|
109
|
+
"orders",
|
|
110
|
+
projectRoot
|
|
111
|
+
);
|
|
112
|
+
const positionPath = getCachedArtifactPath(
|
|
113
|
+
userName,
|
|
114
|
+
orderLogId,
|
|
115
|
+
"positions",
|
|
116
|
+
projectRoot
|
|
117
|
+
);
|
|
118
|
+
const [orderLog, positionLog] = await Promise.all([
|
|
119
|
+
readJsonFile(orderPath, null),
|
|
120
|
+
readJsonFile(positionPath, null)
|
|
121
|
+
]);
|
|
122
|
+
return { orderLog, positionLog };
|
|
123
|
+
};
|
|
124
|
+
var deleteCachedBacktestArtifacts = async ({
|
|
125
|
+
orderLogId,
|
|
126
|
+
projectRoot,
|
|
127
|
+
userName
|
|
128
|
+
}) => {
|
|
129
|
+
const orderPath = getCachedArtifactPath(
|
|
130
|
+
userName,
|
|
131
|
+
orderLogId,
|
|
132
|
+
"orders",
|
|
133
|
+
projectRoot
|
|
134
|
+
);
|
|
135
|
+
const positionPath = getCachedArtifactPath(
|
|
136
|
+
userName,
|
|
137
|
+
orderLogId,
|
|
138
|
+
"positions",
|
|
139
|
+
projectRoot
|
|
140
|
+
);
|
|
141
|
+
const [removedOrderLog, removedPositionLog] = await Promise.all([
|
|
142
|
+
removeFileIfExists(orderPath),
|
|
143
|
+
removeFileIfExists(positionPath)
|
|
144
|
+
]);
|
|
145
|
+
return removedOrderLog || removedPositionLog;
|
|
146
|
+
};
|
|
147
|
+
var writePersistedBacktestOrderLog = async ({
|
|
148
|
+
orderLog,
|
|
149
|
+
projectRoot,
|
|
150
|
+
strategyName,
|
|
151
|
+
testName,
|
|
152
|
+
userName
|
|
153
|
+
}) => {
|
|
154
|
+
const absolutePath = getPersistedOrderLogPath(
|
|
155
|
+
userName,
|
|
156
|
+
strategyName,
|
|
157
|
+
testName,
|
|
158
|
+
projectRoot
|
|
159
|
+
);
|
|
160
|
+
await writeJsonFile(absolutePath, orderLog);
|
|
161
|
+
return createRef(absolutePath, projectRoot);
|
|
162
|
+
};
|
|
163
|
+
var readPersistedBacktestOrderLog = async ({
|
|
164
|
+
projectRoot,
|
|
165
|
+
ref,
|
|
166
|
+
strategyName,
|
|
167
|
+
testName,
|
|
168
|
+
userName
|
|
169
|
+
}) => {
|
|
170
|
+
const absolutePath = ref ? resolveArtifactPath(ref.path, projectRoot) : getPersistedOrderLogPath(userName, strategyName, testName, projectRoot);
|
|
171
|
+
return readJsonFile(absolutePath, null);
|
|
172
|
+
};
|
|
173
|
+
var deletePersistedBacktestOrderLog = async ({
|
|
174
|
+
projectRoot,
|
|
175
|
+
ref,
|
|
176
|
+
strategyName,
|
|
177
|
+
testName,
|
|
178
|
+
userName
|
|
179
|
+
}) => {
|
|
180
|
+
const absolutePath = ref ? resolveArtifactPath(ref.path, projectRoot) : getPersistedOrderLogPath(userName, strategyName, testName, projectRoot);
|
|
181
|
+
return removeFileIfExists(absolutePath);
|
|
182
|
+
};
|
|
183
|
+
var parseBacktestArtifactRef = (value) => {
|
|
184
|
+
if (isBacktestArtifactRef(value)) {
|
|
185
|
+
return value;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
};
|
|
189
|
+
var getBacktestArtifactsRootDir = (projectRoot) => path.join(resolveProjectRoot(projectRoot), BACKTEST_ARTIFACTS_DIR);
|
|
190
|
+
var getBacktestCacheArtifactsDirForUser = (userName, projectRoot) => path.join(
|
|
191
|
+
getBacktestArtifactsRootDir(projectRoot),
|
|
192
|
+
"cache",
|
|
193
|
+
encodeSegment(userName)
|
|
194
|
+
);
|
|
195
|
+
var getPersistedBacktestArtifactsDirForUser = (userName, projectRoot) => path.join(
|
|
196
|
+
getBacktestArtifactsRootDir(projectRoot),
|
|
197
|
+
"tests",
|
|
198
|
+
encodeSegment(userName)
|
|
199
|
+
);
|
|
200
|
+
export {
|
|
201
|
+
deleteCachedBacktestArtifacts,
|
|
202
|
+
deletePersistedBacktestOrderLog,
|
|
203
|
+
getBacktestArtifactsRootDir,
|
|
204
|
+
getBacktestCacheArtifactsDirForUser,
|
|
205
|
+
getPersistedBacktestArtifactsDirForUser,
|
|
206
|
+
parseBacktestArtifactRef,
|
|
207
|
+
readCachedBacktestArtifacts,
|
|
208
|
+
readPersistedBacktestOrderLog,
|
|
209
|
+
writeCachedBacktestArtifacts,
|
|
210
|
+
writePersistedBacktestOrderLog
|
|
211
|
+
};
|
|
@@ -3,15 +3,26 @@ import { once } from "events";
|
|
|
3
3
|
import { createReadStream, createWriteStream } from "fs";
|
|
4
4
|
import fs from "fs/promises";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import readline from "readline";
|
|
6
7
|
var DEFAULT_DIR = "data/ml/export";
|
|
7
8
|
var ML_DATASET_WRITE_BATCH_SIZE = 200;
|
|
8
9
|
var ML_CHUNK_FILE_RE = /^ml-dataset-(.+)-chunk-[^.]+\.jsonl$/;
|
|
10
|
+
var BACKTEST_RUN_CHUNK_ID_RE = /^(\d{12}-[a-f0-9]{8})-/;
|
|
9
11
|
var writerByPath = /* @__PURE__ */ new Map();
|
|
10
12
|
var toFileToken = (value) => value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "any";
|
|
11
13
|
var getMlChunkFilePath = (strategyName, chunkId, outDir = DEFAULT_DIR) => path.join(
|
|
12
14
|
outDir,
|
|
13
15
|
`ml-dataset-${toFileToken(strategyName)}-chunk-${toFileToken(chunkId)}.jsonl`
|
|
14
16
|
);
|
|
17
|
+
var getMlChunkFilePrefix = (strategyName, runId) => `ml-dataset-${toFileToken(strategyName)}-chunk-${runId ? `${toFileToken(runId)}-` : ""}`;
|
|
18
|
+
var getRunIdFromMlChunkFileName = (strategyName, fileName) => {
|
|
19
|
+
const prefix = getMlChunkFilePrefix(strategyName);
|
|
20
|
+
if (!fileName.startsWith(prefix) || !fileName.endsWith(".jsonl")) {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
const chunkToken = fileName.slice(prefix.length, -".jsonl".length);
|
|
24
|
+
return chunkToken.match(BACKTEST_RUN_CHUNK_ID_RE)?.[1] ?? "";
|
|
25
|
+
};
|
|
15
26
|
var appendMlDatasetRow = async (params) => {
|
|
16
27
|
const { strategyName, chunkId, row, outDir = DEFAULT_DIR } = params;
|
|
17
28
|
const filePath = getMlChunkFilePath(strategyName, chunkId, outDir);
|
|
@@ -85,8 +96,8 @@ var closeAllMlDatasetWriters = async () => {
|
|
|
85
96
|
}
|
|
86
97
|
};
|
|
87
98
|
var listMlChunkFiles = async (params) => {
|
|
88
|
-
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
89
|
-
const prefix =
|
|
99
|
+
const { strategyName, outDir = DEFAULT_DIR, runId } = params;
|
|
100
|
+
const prefix = getMlChunkFilePrefix(strategyName, runId);
|
|
90
101
|
let entries = [];
|
|
91
102
|
try {
|
|
92
103
|
entries = await fs.readdir(outDir);
|
|
@@ -95,6 +106,20 @@ var listMlChunkFiles = async (params) => {
|
|
|
95
106
|
}
|
|
96
107
|
return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).map((name) => path.join(outDir, name)).sort();
|
|
97
108
|
};
|
|
109
|
+
var listMlChunkRunIds = async (params) => {
|
|
110
|
+
const { strategyName, outDir = DEFAULT_DIR } = params;
|
|
111
|
+
let entries = [];
|
|
112
|
+
try {
|
|
113
|
+
entries = await fs.readdir(outDir);
|
|
114
|
+
} catch {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
return [
|
|
118
|
+
...new Set(
|
|
119
|
+
entries.map((name) => getRunIdFromMlChunkFileName(strategyName, name)).filter(Boolean)
|
|
120
|
+
)
|
|
121
|
+
].sort();
|
|
122
|
+
};
|
|
98
123
|
var listMlChunkStrategies = async (params) => {
|
|
99
124
|
const outDir = params?.outDir ?? DEFAULT_DIR;
|
|
100
125
|
let entries = [];
|
|
@@ -110,12 +135,37 @@ var listMlChunkStrategies = async (params) => {
|
|
|
110
135
|
].sort();
|
|
111
136
|
};
|
|
112
137
|
var mergeJsonlFiles = async (params) => {
|
|
113
|
-
const { filePaths, outPath } = params;
|
|
138
|
+
const { filePaths, outPath, shouldIncludeRow } = params;
|
|
114
139
|
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
115
140
|
const stream = createWriteStream(outPath, { encoding: "utf8" });
|
|
116
141
|
const done = Promise.all([once(stream, "finish"), once(stream, "close")]);
|
|
117
142
|
try {
|
|
118
143
|
for (const filePath of filePaths) {
|
|
144
|
+
if (shouldIncludeRow) {
|
|
145
|
+
const reader2 = readline.createInterface({
|
|
146
|
+
input: createReadStream(filePath, { encoding: "utf8" }),
|
|
147
|
+
crlfDelay: Infinity
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
for await (const line of reader2) {
|
|
151
|
+
const trimmed = line.trim();
|
|
152
|
+
if (!trimmed) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const row = JSON.parse(trimmed);
|
|
156
|
+
if (!shouldIncludeRow(row)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (!stream.write(`${trimmed}
|
|
160
|
+
`)) {
|
|
161
|
+
await once(stream, "drain");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
reader2.close();
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
119
169
|
const reader = createReadStream(filePath, { encoding: "utf8" });
|
|
120
170
|
for await (const chunk of reader) {
|
|
121
171
|
if (!stream.write(chunk)) {
|
|
@@ -137,6 +187,7 @@ export {
|
|
|
137
187
|
closeMlDatasetWriter,
|
|
138
188
|
closeAllMlDatasetWriters,
|
|
139
189
|
listMlChunkFiles,
|
|
190
|
+
listMlChunkRunIds,
|
|
140
191
|
listMlChunkStrategies,
|
|
141
192
|
mergeJsonlFiles
|
|
142
193
|
};
|