@tradejs/cli 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/README.md +13 -4
- package/dist/cli.js +29531 -13520
- package/dist/lib/aiPocketSearch.js +1316 -0
- package/dist/lib/aiTrainCharts.js +711 -0
- package/dist/lib/aiTrainDataset.js +40 -0
- package/dist/lib/aiTrainEvaluationDump.js +76 -0
- package/dist/lib/aiTrainMetrics.js +148 -8
- package/dist/lib/aiTrainOptions.js +130 -0
- package/dist/lib/aiTrainQuarantine.js +199 -0
- package/dist/lib/aiTrainResearch.js +467 -0
- package/dist/lib/binanceMarketContextBackfill.js +841 -0
- package/dist/lib/binanceMarketData.js +392 -0
- package/dist/lib/coinMarketCapContextBackfill.js +1126 -0
- package/dist/lib/continuity.js +60 -0
- package/dist/lib/derivativesContextBackfill.js +490 -77
- package/dist/lib/executionCalibration.js +705 -0
- package/dist/lib/marketContextPrepare.js +4441 -0
- package/dist/lib/paritySummary.js +101 -0
- package/dist/lib/runBot.js +1 -0
- package/dist/lib/runEnvironment.js +2259 -0
- package/dist/lib/runFormatting.js +1657 -0
- package/dist/lib/runtimeDebugEvidence.js +526 -0
- package/dist/lib/runtimeModeConfig.js +53 -0
- package/dist/lib/runtimeParity.js +88 -11
- package/dist/lib/runtimeParityDetails.js +751 -0
- package/dist/lib/runtimeRedis.js +157 -0
- package/dist/lib/runtimeSignalsLoader.js +40 -6
- package/dist/lib/runtimeSignalsStorage.js +45 -22
- package/dist/lib/runtimeStrategyBacktest.js +134 -0
- package/dist/lib/runtimeTradeSync.js +263 -0
- package/dist/lib/telegramReports.js +9 -0
- package/dist/lib/tickerUniverseCache.js +116 -0
- package/dist/lib/timeWindow.js +3 -3
- package/dist/scripts/agentRun.js +14 -8
- package/dist/scripts/aiExport.js +1721 -7
- package/dist/scripts/aiExportSelect.js +16 -4
- package/dist/scripts/aiPocketSearch.js +4190 -0
- package/dist/scripts/aiTrain.js +1866 -87
- package/dist/scripts/backtest.js +4534 -803
- package/dist/scripts/binanceMarketIngest.js +565 -0
- package/dist/scripts/bot.js +16 -2
- package/dist/scripts/candlesMigrateProvider.js +32 -22
- package/dist/scripts/cleanDir.js +15 -2
- package/dist/scripts/cleanRedis.js +15 -2
- package/dist/scripts/cleanTests.js +38 -2
- package/dist/scripts/cleanupMarketContext.js +69 -0
- package/dist/scripts/continuity.js +148 -67
- package/dist/scripts/derivativesIngest.js +14 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +14 -4
- package/dist/scripts/doctor.js +14 -4
- package/dist/scripts/executionCalibration.js +792 -0
- package/dist/scripts/infraCommon.js +18 -5
- package/dist/scripts/infraDown.js +14 -4
- package/dist/scripts/infraInit.js +32 -9
- package/dist/scripts/infraUp.js +24 -6
- package/dist/scripts/marketWs.js +222 -0
- package/dist/scripts/migration.js +15 -2
- package/dist/scripts/mlExport.js +1698 -10
- package/dist/scripts/mlExportSelect.js +16 -4
- package/dist/scripts/mlInspect.js +13 -3
- package/dist/scripts/mlTrainLatestSelect.js +14 -4
- package/dist/scripts/replay.js +8867 -0
- package/dist/scripts/replayRunner.js +8870 -0
- package/dist/scripts/replayRuntimeEvidence.js +868 -0
- package/dist/scripts/researchAuto.js +286 -59
- package/dist/scripts/results.js +3 -3
- package/dist/scripts/runtimeEvidence.js +605 -0
- package/dist/scripts/runtimeParity.js +6400 -1043
- package/dist/scripts/serverHealth.js +588 -0
- package/dist/scripts/signals.js +5628 -511
- package/dist/scripts/signalsDaemon.js +6205 -0
- package/dist/scripts/signalsSummary.js +833 -248
- package/dist/scripts/test-ml.js +25 -3
- package/dist/scripts/test.js +26 -1
- package/dist/scripts/user-add.js +15 -2
- package/dist/workers/testerWorker.js +130 -21
- package/package.json +18 -12
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/runtimeTradeSync.ts
|
|
21
|
+
var runtimeTradeSync_exports = {};
|
|
22
|
+
__export(runtimeTradeSync_exports, {
|
|
23
|
+
EXCHANGE_HISTORY_MAX_RANGE_MS: () => EXCHANGE_HISTORY_MAX_RANGE_MS,
|
|
24
|
+
consumeClosedPnlMatch: () => consumeClosedPnlMatch,
|
|
25
|
+
formatRuntimeTradeSyncError: () => formatRuntimeTradeSyncError,
|
|
26
|
+
loadClosedPnlRows: () => loadClosedPnlRows,
|
|
27
|
+
splitExchangeHistoryTimeRange: () => splitExchangeHistoryTimeRange,
|
|
28
|
+
syncRuntimeTrades: () => syncRuntimeTrades
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(runtimeTradeSync_exports);
|
|
31
|
+
var import_constants = require("@tradejs/core/constants");
|
|
32
|
+
var import_time = require("@tradejs/core/time");
|
|
33
|
+
var import_redis = require("@tradejs/infra/redis");
|
|
34
|
+
var CLOSED_PNL_LIMIT = 100;
|
|
35
|
+
var EXCHANGE_HISTORY_MAX_RANGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
36
|
+
var splitExchangeHistoryTimeRange = ({
|
|
37
|
+
startTime,
|
|
38
|
+
endTime,
|
|
39
|
+
maxRangeMs = EXCHANGE_HISTORY_MAX_RANGE_MS
|
|
40
|
+
}) => {
|
|
41
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || !Number.isFinite(maxRangeMs) || maxRangeMs <= 0 || endTime <= startTime) {
|
|
42
|
+
return [{ startTime, endTime }];
|
|
43
|
+
}
|
|
44
|
+
const chunks = [];
|
|
45
|
+
let chunkStart = Math.trunc(startTime);
|
|
46
|
+
const finalEnd = Math.trunc(endTime);
|
|
47
|
+
const maxRange = Math.trunc(maxRangeMs);
|
|
48
|
+
while (chunkStart < finalEnd) {
|
|
49
|
+
const chunkEnd = Math.min(finalEnd, chunkStart + maxRange);
|
|
50
|
+
chunks.push({ startTime: chunkStart, endTime: chunkEnd });
|
|
51
|
+
if (chunkEnd >= finalEnd) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
chunkStart = chunkEnd + 1;
|
|
55
|
+
}
|
|
56
|
+
return chunks;
|
|
57
|
+
};
|
|
58
|
+
var formatRuntimeTradeSyncError = (error) => {
|
|
59
|
+
if (!error || typeof error !== "object") {
|
|
60
|
+
return String(error || "unknown error");
|
|
61
|
+
}
|
|
62
|
+
const record = error;
|
|
63
|
+
const message = typeof record.message === "string" && record.message.trim() ? record.message.trim() : String(error);
|
|
64
|
+
const code = typeof record.code === "string" && record.code.trim() ? record.code.trim() : null;
|
|
65
|
+
const isAxiosError = record.isAxiosError === true;
|
|
66
|
+
const config = record.config && typeof record.config === "object" ? record.config : null;
|
|
67
|
+
const response = record.response && typeof record.response === "object" ? record.response : null;
|
|
68
|
+
const method = typeof config?.method === "string" && config.method.trim() ? config.method.toUpperCase() : null;
|
|
69
|
+
const url = typeof config?.url === "string" && config.url.trim() ? config.url.trim() : null;
|
|
70
|
+
const timeout = typeof config?.timeout === "number" && Number.isFinite(config.timeout) ? config.timeout : null;
|
|
71
|
+
const status = typeof response?.status === "number" && Number.isFinite(response.status) ? response.status : null;
|
|
72
|
+
const details = [
|
|
73
|
+
isAxiosError ? "axios" : null,
|
|
74
|
+
code,
|
|
75
|
+
status == null ? null : `status=${status}`,
|
|
76
|
+
method && url ? `${method} ${url}` : url,
|
|
77
|
+
timeout == null ? null : `timeout=${timeout}ms`
|
|
78
|
+
].filter(Boolean);
|
|
79
|
+
return details.length > 0 ? `${message} (${details.join(", ")})` : message;
|
|
80
|
+
};
|
|
81
|
+
var loadClosedPnlRows = async ({
|
|
82
|
+
connector,
|
|
83
|
+
startTime,
|
|
84
|
+
endTime,
|
|
85
|
+
callbacks
|
|
86
|
+
}) => {
|
|
87
|
+
if (typeof connector.getClosedPnl !== "function") {
|
|
88
|
+
callbacks?.onUnsupported?.();
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const rows = [];
|
|
92
|
+
const chunks = splitExchangeHistoryTimeRange({ startTime, endTime });
|
|
93
|
+
for (const chunk of chunks) {
|
|
94
|
+
try {
|
|
95
|
+
const chunkRows = await connector.getClosedPnl({
|
|
96
|
+
startTime: chunk.startTime,
|
|
97
|
+
endTime: chunk.endTime,
|
|
98
|
+
limit: CLOSED_PNL_LIMIT
|
|
99
|
+
});
|
|
100
|
+
if (chunkRows.length >= CLOSED_PNL_LIMIT) {
|
|
101
|
+
callbacks?.onCapped?.(chunkRows.length);
|
|
102
|
+
}
|
|
103
|
+
rows.push(...chunkRows);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
callbacks?.onError?.(error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return rows.sort((left, right) => left.closedAt - right.closedAt);
|
|
109
|
+
};
|
|
110
|
+
var consumeClosedPnlMatch = (buckets, trade) => {
|
|
111
|
+
const rows = buckets.get(trade.symbol);
|
|
112
|
+
if (!rows?.length) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const minimumClosedAt = trade.entryTimestamp - 5 * 6e4;
|
|
116
|
+
const matchIndex = rows.findIndex(
|
|
117
|
+
(row2) => Number.isFinite(row2.closedAt) && row2.closedAt >= minimumClosedAt
|
|
118
|
+
);
|
|
119
|
+
if (matchIndex < 0) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const [row] = rows.splice(matchIndex, 1);
|
|
123
|
+
return row ?? null;
|
|
124
|
+
};
|
|
125
|
+
var syncRuntimeTrades = async ({
|
|
126
|
+
userName,
|
|
127
|
+
connector,
|
|
128
|
+
trades,
|
|
129
|
+
startTime,
|
|
130
|
+
endTime,
|
|
131
|
+
closedPnlCallbacks,
|
|
132
|
+
openPositionCallbacks
|
|
133
|
+
}) => {
|
|
134
|
+
let openPositions = [];
|
|
135
|
+
let openPositionsReliable = true;
|
|
136
|
+
if (typeof connector.getOpenPositionPnl === "function") {
|
|
137
|
+
try {
|
|
138
|
+
openPositions = await connector.getOpenPositionPnl();
|
|
139
|
+
} catch (error) {
|
|
140
|
+
openPositionCallbacks?.onError?.(error);
|
|
141
|
+
openPositionsReliable = false;
|
|
142
|
+
openPositions = [];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const openPositionsBySymbol = new Map(
|
|
146
|
+
openPositions.map((position) => [position.symbol, position])
|
|
147
|
+
);
|
|
148
|
+
const activeOrderIdBySymbol = /* @__PURE__ */ new Map();
|
|
149
|
+
const symbols = [...new Set(trades.map((trade) => trade.symbol))];
|
|
150
|
+
await Promise.all(
|
|
151
|
+
symbols.map(async (symbol) => {
|
|
152
|
+
const activeRef = await (0, import_redis.getData)(
|
|
153
|
+
import_redis.redisKeys.runtimeActiveTrade(userName, symbol),
|
|
154
|
+
null
|
|
155
|
+
);
|
|
156
|
+
activeOrderIdBySymbol.set(
|
|
157
|
+
symbol,
|
|
158
|
+
typeof activeRef?.orderId === "string" ? activeRef.orderId : null
|
|
159
|
+
);
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
const closedPnlRows = await loadClosedPnlRows({
|
|
163
|
+
connector,
|
|
164
|
+
startTime,
|
|
165
|
+
endTime,
|
|
166
|
+
callbacks: closedPnlCallbacks
|
|
167
|
+
});
|
|
168
|
+
const closedPnlBuckets = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const row of closedPnlRows) {
|
|
170
|
+
const bucket = closedPnlBuckets.get(row.symbol) ?? [];
|
|
171
|
+
bucket.push(row);
|
|
172
|
+
closedPnlBuckets.set(row.symbol, bucket);
|
|
173
|
+
}
|
|
174
|
+
const syncedTrades = [];
|
|
175
|
+
for (const trade of trades) {
|
|
176
|
+
if (trade.status !== "active") {
|
|
177
|
+
syncedTrades.push(trade);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const openPosition = openPositionsBySymbol.get(trade.symbol);
|
|
181
|
+
const activeOrderId = activeOrderIdBySymbol.get(trade.symbol);
|
|
182
|
+
const isCurrentActiveTrade = activeOrderId === trade.orderId;
|
|
183
|
+
if (!openPositionsReliable) {
|
|
184
|
+
syncedTrades.push({
|
|
185
|
+
...trade,
|
|
186
|
+
status: "active",
|
|
187
|
+
lastSyncedAt: endTime
|
|
188
|
+
});
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (isCurrentActiveTrade && openPosition && openPosition.direction === trade.direction) {
|
|
192
|
+
const nextTrade2 = {
|
|
193
|
+
...trade,
|
|
194
|
+
status: "active",
|
|
195
|
+
currentPrice: openPosition.currentPrice,
|
|
196
|
+
currentPnl: openPosition.unrealizedPnl,
|
|
197
|
+
lastSyncedAt: endTime
|
|
198
|
+
};
|
|
199
|
+
await (0, import_redis.setData)(
|
|
200
|
+
import_redis.redisKeys.runtimeTrade(userName, trade.orderId),
|
|
201
|
+
nextTrade2,
|
|
202
|
+
{
|
|
203
|
+
expire: 0
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
await (0, import_redis.setHashJsonField)(
|
|
207
|
+
import_redis.redisKeys.runtimeTradeBucket(
|
|
208
|
+
userName,
|
|
209
|
+
(0, import_time.getRuntimeStorageDayKey)(trade.entryTimestamp)
|
|
210
|
+
),
|
|
211
|
+
trade.orderId,
|
|
212
|
+
nextTrade2,
|
|
213
|
+
{ expire: 0 }
|
|
214
|
+
);
|
|
215
|
+
syncedTrades.push(nextTrade2);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const matchedClosedPnl = consumeClosedPnlMatch(closedPnlBuckets, trade);
|
|
219
|
+
const nextTrade = {
|
|
220
|
+
...trade,
|
|
221
|
+
status: "closed",
|
|
222
|
+
currentPrice: matchedClosedPnl?.exitPrice ?? trade.currentPrice ?? null,
|
|
223
|
+
currentPnl: matchedClosedPnl?.closedPnl ?? trade.closedPnl ?? trade.currentPnl ?? null,
|
|
224
|
+
closedPnl: matchedClosedPnl?.closedPnl ?? trade.closedPnl ?? trade.currentPnl ?? null,
|
|
225
|
+
actualEntryPrice: matchedClosedPnl?.entryPrice ?? trade.actualEntryPrice ?? null,
|
|
226
|
+
exitPrice: matchedClosedPnl?.exitPrice ?? trade.exitPrice ?? null,
|
|
227
|
+
actualExitPrice: matchedClosedPnl?.exitPrice ?? trade.actualExitPrice ?? null,
|
|
228
|
+
exitTimestamp: matchedClosedPnl?.closedAt ?? trade.exitTimestamp ?? endTime,
|
|
229
|
+
exitType: trade.exitType ?? null,
|
|
230
|
+
openFee: matchedClosedPnl?.openFee ?? trade.openFee ?? null,
|
|
231
|
+
closeFee: matchedClosedPnl?.closeFee ?? trade.closeFee ?? null,
|
|
232
|
+
fundingFee: matchedClosedPnl?.fundingFee ?? trade.fundingFee ?? null,
|
|
233
|
+
totalFee: matchedClosedPnl?.totalFee ?? trade.totalFee ?? null,
|
|
234
|
+
lastSyncedAt: endTime
|
|
235
|
+
};
|
|
236
|
+
await Promise.all([
|
|
237
|
+
(0, import_redis.setData)(import_redis.redisKeys.runtimeTrade(userName, trade.orderId), nextTrade, {
|
|
238
|
+
expire: import_constants.TTL_1M
|
|
239
|
+
}),
|
|
240
|
+
(0, import_redis.setHashJsonField)(
|
|
241
|
+
import_redis.redisKeys.runtimeTradeBucket(
|
|
242
|
+
userName,
|
|
243
|
+
(0, import_time.getRuntimeStorageDayKey)(trade.entryTimestamp)
|
|
244
|
+
),
|
|
245
|
+
trade.orderId,
|
|
246
|
+
nextTrade,
|
|
247
|
+
{ expire: import_constants.TTL_1M }
|
|
248
|
+
),
|
|
249
|
+
...isCurrentActiveTrade ? [(0, import_redis.delKey)(import_redis.redisKeys.runtimeActiveTrade(userName, trade.symbol))] : []
|
|
250
|
+
]);
|
|
251
|
+
syncedTrades.push(nextTrade);
|
|
252
|
+
}
|
|
253
|
+
return syncedTrades;
|
|
254
|
+
};
|
|
255
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
256
|
+
0 && (module.exports = {
|
|
257
|
+
EXCHANGE_HISTORY_MAX_RANGE_MS,
|
|
258
|
+
consumeClosedPnlMatch,
|
|
259
|
+
formatRuntimeTradeSyncError,
|
|
260
|
+
loadClosedPnlRows,
|
|
261
|
+
splitExchangeHistoryTimeRange,
|
|
262
|
+
syncRuntimeTrades
|
|
263
|
+
});
|
|
@@ -68,8 +68,16 @@ ${line}` : line;
|
|
|
68
68
|
};
|
|
69
69
|
var sendTelegramReport = async (message, options = {}) => {
|
|
70
70
|
const chunks = splitTelegramReport(message);
|
|
71
|
+
const sendAttachments = async () => {
|
|
72
|
+
for (const attachment of options.attachments || []) {
|
|
73
|
+
await (0, import_cli.sendDocumentToTG)(attachment, {
|
|
74
|
+
userName: options.userName
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
71
78
|
if (chunks.length === 1) {
|
|
72
79
|
await (0, import_cli.sendTextToTG)(chunks[0], options);
|
|
80
|
+
await sendAttachments();
|
|
73
81
|
return chunks.length;
|
|
74
82
|
}
|
|
75
83
|
for (const [index, chunk] of chunks.entries()) {
|
|
@@ -81,6 +89,7 @@ ${chunk}`, {
|
|
|
81
89
|
markup: index === chunks.length - 1 ? options.markup : void 0
|
|
82
90
|
});
|
|
83
91
|
}
|
|
92
|
+
await sendAttachments();
|
|
84
93
|
return chunks.length;
|
|
85
94
|
};
|
|
86
95
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/tickerUniverseCache.ts
|
|
21
|
+
var tickerUniverseCache_exports = {};
|
|
22
|
+
__export(tickerUniverseCache_exports, {
|
|
23
|
+
loadRunTickers: () => loadRunTickers
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(tickerUniverseCache_exports);
|
|
26
|
+
var import_tickers = require("@tradejs/core/tickers");
|
|
27
|
+
var import_redis = require("@tradejs/infra/redis");
|
|
28
|
+
var import_cli = require("@tradejs/node/cli");
|
|
29
|
+
var TICKER_CACHE_VERSION = 1;
|
|
30
|
+
var parseSymbolsFromCLI = (symbols = "") => symbols.split(",").map((symbol) => symbol.trim().toUpperCase()).filter(Boolean);
|
|
31
|
+
var isTickerLike = (value) => {
|
|
32
|
+
if (!value || typeof value !== "object") {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const ticker = value;
|
|
36
|
+
return typeof ticker.symbol === "string" && ticker.symbol.trim().length > 0 && typeof ticker.volume24h === "number" && Number.isFinite(ticker.volume24h);
|
|
37
|
+
};
|
|
38
|
+
var readCachedTickerUniverse = async (cacheKey) => {
|
|
39
|
+
const cached = await (0, import_redis.getData)(cacheKey, null);
|
|
40
|
+
if (!cached || !Array.isArray(cached.tickers)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const tickers = cached.tickers.filter(isTickerLike);
|
|
44
|
+
return tickers.length ? tickers : null;
|
|
45
|
+
};
|
|
46
|
+
var selectTickerSymbols = ({
|
|
47
|
+
tickers,
|
|
48
|
+
exclude,
|
|
49
|
+
limit
|
|
50
|
+
}) => {
|
|
51
|
+
const excludedTickers = parseSymbolsFromCLI(exclude);
|
|
52
|
+
return (0, import_tickers.getTopTickers)(tickers, limit).map(({ value }) => value).filter((ticker) => !excludedTickers.includes(ticker));
|
|
53
|
+
};
|
|
54
|
+
var loadRunTickers = async ({
|
|
55
|
+
connector,
|
|
56
|
+
connectorName,
|
|
57
|
+
userName,
|
|
58
|
+
include,
|
|
59
|
+
exclude,
|
|
60
|
+
limit,
|
|
61
|
+
cacheOnly,
|
|
62
|
+
universe,
|
|
63
|
+
accountId,
|
|
64
|
+
assetClasses
|
|
65
|
+
}) => {
|
|
66
|
+
if (include?.trim()) {
|
|
67
|
+
return (0, import_cli.getTickers)(connector, include, exclude, limit, void 0, {
|
|
68
|
+
universe,
|
|
69
|
+
assetClasses
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const cacheKey = import_redis.redisKeys.tickerUniverse(
|
|
73
|
+
userName,
|
|
74
|
+
connectorName,
|
|
75
|
+
universe,
|
|
76
|
+
accountId
|
|
77
|
+
);
|
|
78
|
+
if (cacheOnly) {
|
|
79
|
+
const cachedTickers = await readCachedTickerUniverse(cacheKey);
|
|
80
|
+
if (!cachedTickers) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`No cached ticker universe for ${connectorName}. Run once without --cacheOnly or pass --tickers explicitly.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return selectTickerSymbols({
|
|
86
|
+
tickers: cachedTickers,
|
|
87
|
+
exclude,
|
|
88
|
+
limit
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const exchangeTickers = await connector.getTickers({
|
|
92
|
+
universe,
|
|
93
|
+
assetClasses
|
|
94
|
+
});
|
|
95
|
+
if (exchangeTickers.length) {
|
|
96
|
+
await (0, import_redis.setData)(
|
|
97
|
+
cacheKey,
|
|
98
|
+
{
|
|
99
|
+
version: TICKER_CACHE_VERSION,
|
|
100
|
+
connectorName,
|
|
101
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
102
|
+
tickers: exchangeTickers
|
|
103
|
+
},
|
|
104
|
+
{ expire: 0 }
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return selectTickerSymbols({
|
|
108
|
+
tickers: exchangeTickers,
|
|
109
|
+
exclude,
|
|
110
|
+
limit
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
114
|
+
0 && (module.exports = {
|
|
115
|
+
loadRunTickers
|
|
116
|
+
});
|
package/dist/lib/timeWindow.js
CHANGED
|
@@ -54,9 +54,10 @@ var resolveTimeWindow = ({
|
|
|
54
54
|
}) => {
|
|
55
55
|
const explicitStart = toEpochMs(startTime);
|
|
56
56
|
const explicitEnd = toEpochMs(endTime);
|
|
57
|
+
const resolvedDays = toPositiveNumber(days);
|
|
57
58
|
if (explicitStart != null || explicitEnd != null) {
|
|
58
|
-
const
|
|
59
|
-
const
|
|
59
|
+
const resolvedStart = explicitStart ?? (resolvedDays != null && explicitEnd != null ? explicitEnd - resolvedDays * ONE_DAY_MS : defaultStartMs);
|
|
60
|
+
const resolvedEnd2 = explicitEnd ?? (resolvedDays != null && explicitStart != null ? explicitStart + resolvedDays * ONE_DAY_MS : defaultEndMs ?? nowMs);
|
|
60
61
|
if (resolvedStart >= resolvedEnd2) {
|
|
61
62
|
throw new Error(
|
|
62
63
|
`Invalid time window: startTime (${resolvedStart}) must be less than endTime (${resolvedEnd2})`
|
|
@@ -68,7 +69,6 @@ var resolveTimeWindow = ({
|
|
|
68
69
|
source: "explicit"
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
|
-
const resolvedDays = toPositiveNumber(days);
|
|
72
72
|
if (resolvedDays != null) {
|
|
73
73
|
const resolvedEnd2 = defaultEndMs ?? nowMs;
|
|
74
74
|
const resolvedStart = resolvedEnd2 - resolvedDays * ONE_DAY_MS;
|
package/dist/scripts/agentRun.js
CHANGED
|
@@ -39,6 +39,7 @@ var import_promises = __toESM(require("fs/promises"));
|
|
|
39
39
|
var import_node_os = __toESM(require("os"));
|
|
40
40
|
var import_node_path2 = __toESM(require("path"));
|
|
41
41
|
var import_node_child_process = require("child_process");
|
|
42
|
+
var import_constants = require("@tradejs/core/constants");
|
|
42
43
|
var import_redis = require("@tradejs/infra/redis");
|
|
43
44
|
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
44
45
|
|
|
@@ -86,8 +87,16 @@ ${line}` : line;
|
|
|
86
87
|
};
|
|
87
88
|
var sendTelegramReport = async (message, options = {}) => {
|
|
88
89
|
const chunks = splitTelegramReport(message);
|
|
90
|
+
const sendAttachments = async () => {
|
|
91
|
+
for (const attachment of options.attachments || []) {
|
|
92
|
+
await (0, import_cli.sendDocumentToTG)(attachment, {
|
|
93
|
+
userName: options.userName
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
89
97
|
if (chunks.length === 1) {
|
|
90
98
|
await (0, import_cli.sendTextToTG)(chunks[0], options);
|
|
99
|
+
await sendAttachments();
|
|
91
100
|
return chunks.length;
|
|
92
101
|
}
|
|
93
102
|
for (const [index, chunk] of chunks.entries()) {
|
|
@@ -99,6 +108,7 @@ ${chunk}`, {
|
|
|
99
108
|
markup: index === chunks.length - 1 ? options.markup : void 0
|
|
100
109
|
});
|
|
101
110
|
}
|
|
111
|
+
await sendAttachments();
|
|
102
112
|
return chunks.length;
|
|
103
113
|
};
|
|
104
114
|
|
|
@@ -603,9 +613,11 @@ var saveAgentRun = async (userName, runId, strategy, agentRun) => {
|
|
|
603
613
|
...run.artifacts,
|
|
604
614
|
agentRun
|
|
605
615
|
};
|
|
606
|
-
await (0, import_redis.setData)(import_redis.redisKeys.researchRun(userName, runId), run, {
|
|
616
|
+
await (0, import_redis.setData)(import_redis.redisKeys.researchRun(userName, runId), run, {
|
|
617
|
+
expire: import_constants.TTL_1M
|
|
618
|
+
});
|
|
607
619
|
await (0, import_redis.setData)(import_redis.redisKeys.researchLatestRun(userName, strategy), run, {
|
|
608
|
-
expire:
|
|
620
|
+
expire: import_constants.TTL_1M
|
|
609
621
|
});
|
|
610
622
|
};
|
|
611
623
|
var resolveGithubRepository = async (worktreePath) => {
|
|
@@ -897,12 +909,6 @@ Return a corrected unified diff only. Keep the same allowed paths.`
|
|
|
897
909
|
}
|
|
898
910
|
}
|
|
899
911
|
};
|
|
900
|
-
if (require.main === module) {
|
|
901
|
-
main().catch((error) => {
|
|
902
|
-
console.error(import_chalk.default.red(error?.message || String(error)));
|
|
903
|
-
process.exit(1);
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
912
|
// Annotate the CommonJS export names for ESM import in node:
|
|
907
913
|
0 && (module.exports = {
|
|
908
914
|
main
|