@tradejs/cli 2.0.8 → 2.0.9
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 +297 -134
- package/dist/lib/aiPocketSearchCli.js +54 -0
- package/dist/lib/marketContextPrepare.js +2 -2
- package/dist/scripts/aiPocketSearch.js +56 -8
- package/dist/scripts/backtest.js +2 -2
- package/dist/scripts/replay.js +2 -2
- package/dist/scripts/replayRunner.js +2 -2
- package/dist/scripts/runtimeParity.js +2 -2
- package/dist/scripts/signals.js +233 -125
- package/dist/scripts/signalsDaemon.js +233 -125
- package/package.json +9 -9
|
@@ -4707,7 +4707,7 @@ var buildCoinMarketCapBackfillParams = (params) => ({
|
|
|
4707
4707
|
userName: params.userName,
|
|
4708
4708
|
startMs: params.startMs,
|
|
4709
4709
|
endMs: params.endMs,
|
|
4710
|
-
preloadStartMs: params.preloadStartMs
|
|
4710
|
+
preloadStartMs: params.mode === "signals" ? void 0 : params.preloadStartMs
|
|
4711
4711
|
});
|
|
4712
4712
|
var buildBinanceMarketBackfillParams = (params) => ({
|
|
4713
4713
|
userName: params.userName,
|
|
@@ -4716,7 +4716,7 @@ var buildBinanceMarketBackfillParams = (params) => ({
|
|
|
4716
4716
|
interval: params.interval,
|
|
4717
4717
|
startMs: params.startMs,
|
|
4718
4718
|
endMs: params.endMs,
|
|
4719
|
-
preloadStartMs: params.preloadStartMs
|
|
4719
|
+
preloadStartMs: params.mode === "signals" ? void 0 : params.preloadStartMs
|
|
4720
4720
|
});
|
|
4721
4721
|
var buildDerivativesBackfillParams = (params) => ({
|
|
4722
4722
|
userName: params.userName,
|
|
@@ -5025,6 +5025,7 @@ var loadRuntimeStrategies = async ({
|
|
|
5025
5025
|
universe: configUniverse,
|
|
5026
5026
|
accountId: effectiveAccountId,
|
|
5027
5027
|
strategyCreator,
|
|
5028
|
+
sourceStrategyConfig: strategyConfig,
|
|
5028
5029
|
strategyConfig: {
|
|
5029
5030
|
...strategyConfig,
|
|
5030
5031
|
...deploymentStrategy?.config,
|
|
@@ -5313,79 +5314,140 @@ var runtimeLineageKey = (lineage) => [
|
|
|
5313
5314
|
// src/lib/signals/evaluations.ts
|
|
5314
5315
|
var runtimeLineageScopeCache = /* @__PURE__ */ new Map();
|
|
5315
5316
|
var runtimeLineageScopeCacheDayKey = "";
|
|
5317
|
+
var runtimeLineageScopeCacheLoaded = false;
|
|
5316
5318
|
var buildRuntimeSignalEvaluationId = ({
|
|
5317
5319
|
strategyName,
|
|
5318
5320
|
symbol,
|
|
5319
5321
|
timestamp,
|
|
5320
5322
|
runtimeConfigId
|
|
5321
5323
|
}) => runtimeConfigId && runtimeConfigId !== "config" ? [strategyName, runtimeConfigId, symbol, timestamp].join(":") : [strategyName, symbol, timestamp].join(":");
|
|
5322
|
-
var
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5324
|
+
var buildLineageField = (scope) => [
|
|
5325
|
+
scope.strategy,
|
|
5326
|
+
scope.runtimeConfigId ?? "config",
|
|
5327
|
+
scope.symbol,
|
|
5328
|
+
runtimeLineageKey(scope.lineage)
|
|
5329
|
+
].join(":");
|
|
5330
|
+
var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
5331
|
+
if (evaluations.length === 0) return;
|
|
5332
|
+
const evaluationsByDay = /* @__PURE__ */ new Map();
|
|
5333
|
+
for (const evaluation of evaluations) {
|
|
5334
|
+
const dayKey = (0, import_time.getRuntimeStorageDayKey)(evaluation.timestamp);
|
|
5335
|
+
const dayEvaluations = evaluationsByDay.get(dayKey) ?? [];
|
|
5336
|
+
dayEvaluations.push(evaluation);
|
|
5337
|
+
evaluationsByDay.set(dayKey, dayEvaluations);
|
|
5327
5338
|
}
|
|
5328
5339
|
const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
].join(":");
|
|
5340
|
+
for (const [dayKey, dayEvaluations] of evaluationsByDay) {
|
|
5341
|
+
if (runtimeLineageScopeCacheDayKey !== dayKey) {
|
|
5342
|
+
runtimeLineageScopeCache.clear();
|
|
5343
|
+
runtimeLineageScopeCacheDayKey = dayKey;
|
|
5344
|
+
runtimeLineageScopeCacheLoaded = false;
|
|
5345
|
+
}
|
|
5336
5346
|
const lineageBucket = import_redis3.redisKeys.runtimeLineageScopeBucket(
|
|
5337
|
-
|
|
5347
|
+
dayEvaluations[0].userName,
|
|
5338
5348
|
dayKey
|
|
5339
5349
|
);
|
|
5340
|
-
const
|
|
5341
|
-
|
|
5342
|
-
lineageBucket,
|
|
5343
|
-
lineageField
|
|
5350
|
+
const lineageEvaluations = dayEvaluations.filter(
|
|
5351
|
+
(evaluation) => evaluation.runtimeLineage != null
|
|
5344
5352
|
);
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
evaluation.
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5353
|
+
if (lineageEvaluations.length > 0 && !runtimeLineageScopeCacheLoaded) {
|
|
5354
|
+
const storedScopes = await (0, import_redis3.getHashJsonValues)(lineageBucket);
|
|
5355
|
+
for (const scope of storedScopes) {
|
|
5356
|
+
const lineageField = buildLineageField(scope);
|
|
5357
|
+
runtimeLineageScopeCache.set(`${lineageBucket}:${lineageField}`, scope);
|
|
5358
|
+
}
|
|
5359
|
+
runtimeLineageScopeCacheLoaded = true;
|
|
5360
|
+
}
|
|
5361
|
+
const lineageWrites = /* @__PURE__ */ new Map();
|
|
5362
|
+
for (const evaluation of lineageEvaluations) {
|
|
5363
|
+
const lineageField = buildLineageField({
|
|
5364
|
+
strategy: evaluation.strategy,
|
|
5365
|
+
runtimeConfigId: evaluation.runtimeConfigId,
|
|
5366
|
+
symbol: evaluation.symbol,
|
|
5367
|
+
lineage: evaluation.runtimeLineage
|
|
5368
|
+
});
|
|
5369
|
+
const cacheKey = `${lineageBucket}:${lineageField}`;
|
|
5370
|
+
const existing = runtimeLineageScopeCache.get(cacheKey);
|
|
5371
|
+
const scope = {
|
|
5372
|
+
strategy: evaluation.strategy,
|
|
5373
|
+
symbol: evaluation.symbol,
|
|
5374
|
+
runtimeConfigId: evaluation.runtimeConfigId,
|
|
5375
|
+
lineage: evaluation.runtimeLineage,
|
|
5376
|
+
firstTimestamp: Math.min(
|
|
5377
|
+
existing?.firstTimestamp ?? evaluation.timestamp,
|
|
5378
|
+
evaluation.timestamp
|
|
5379
|
+
),
|
|
5380
|
+
lastTimestamp: Math.max(
|
|
5381
|
+
existing?.lastTimestamp ?? evaluation.timestamp,
|
|
5382
|
+
evaluation.timestamp
|
|
5383
|
+
)
|
|
5384
|
+
};
|
|
5385
|
+
runtimeLineageScopeCache.set(cacheKey, scope);
|
|
5386
|
+
lineageWrites.set(lineageField, scope);
|
|
5387
|
+
}
|
|
5388
|
+
if (lineageWrites.size > 0) {
|
|
5389
|
+
await (0, import_redis3.setHashJsonFields)(
|
|
5390
|
+
lineageBucket,
|
|
5391
|
+
[...lineageWrites].map(([field, data]) => ({ field, data })),
|
|
5392
|
+
{
|
|
5393
|
+
expire: RUNTIME_LINEAGE_SCOPE_RETENTION_TTL_SECONDS
|
|
5394
|
+
}
|
|
5395
|
+
);
|
|
5396
|
+
}
|
|
5397
|
+
const detailedWrites = /* @__PURE__ */ new Map();
|
|
5398
|
+
const statsIncrements = /* @__PURE__ */ new Map();
|
|
5399
|
+
for (const evaluation of dayEvaluations) {
|
|
5400
|
+
if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
|
|
5401
|
+
const bucket = import_redis3.redisKeys.runtimeSignalEvaluationBucket(
|
|
5402
|
+
evaluation.userName,
|
|
5403
|
+
dayKey,
|
|
5404
|
+
evaluation.strategy
|
|
5405
|
+
);
|
|
5406
|
+
const entries = detailedWrites.get(bucket) ?? [];
|
|
5407
|
+
entries.push({
|
|
5408
|
+
field: evaluation.evaluationId,
|
|
5409
|
+
data: evaluation
|
|
5410
|
+
});
|
|
5411
|
+
detailedWrites.set(bucket, entries);
|
|
5412
|
+
}
|
|
5413
|
+
const statsBucket = import_redis3.redisKeys.runtimeSignalEvaluationStatsBucket(
|
|
5367
5414
|
evaluation.userName,
|
|
5368
5415
|
dayKey,
|
|
5369
5416
|
evaluation.strategy
|
|
5370
|
-
)
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5417
|
+
);
|
|
5418
|
+
const increments = statsIncrements.get(statsBucket) ?? {};
|
|
5419
|
+
for (const [field, increment] of Object.entries(
|
|
5420
|
+
buildRuntimeSignalStatsIncrements(evaluation)
|
|
5421
|
+
)) {
|
|
5422
|
+
increments[field] = (increments[field] ?? 0) + increment;
|
|
5375
5423
|
}
|
|
5376
|
-
|
|
5424
|
+
statsIncrements.set(statsBucket, increments);
|
|
5425
|
+
}
|
|
5426
|
+
await Promise.all([
|
|
5427
|
+
...[...detailedWrites].map(
|
|
5428
|
+
([bucket, entries]) => (0, import_redis3.setHashJsonFields)(bucket, entries, {
|
|
5429
|
+
expire: runtimeSignalRetentionTtl
|
|
5430
|
+
})
|
|
5431
|
+
),
|
|
5432
|
+
...[...statsIncrements].map(
|
|
5433
|
+
([bucket, increments]) => (0, import_redis3.incrHashFields)(bucket, increments, {
|
|
5434
|
+
expire: runtimeSignalRetentionTtl
|
|
5435
|
+
})
|
|
5436
|
+
)
|
|
5437
|
+
]);
|
|
5377
5438
|
}
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
{
|
|
5386
|
-
|
|
5439
|
+
};
|
|
5440
|
+
var createRuntimeSignalEvaluationBuffer = () => {
|
|
5441
|
+
const evaluations = [];
|
|
5442
|
+
return {
|
|
5443
|
+
save: async (evaluation) => {
|
|
5444
|
+
evaluations.push(evaluation);
|
|
5445
|
+
},
|
|
5446
|
+
flush: async () => {
|
|
5447
|
+
const pending = evaluations.splice(0);
|
|
5448
|
+
await flushRuntimeSignalEvaluations(pending);
|
|
5387
5449
|
}
|
|
5388
|
-
|
|
5450
|
+
};
|
|
5389
5451
|
};
|
|
5390
5452
|
|
|
5391
5453
|
// src/lib/signals/telegram.ts
|
|
@@ -5497,8 +5559,8 @@ var createSignalsStrategyLifecycle = ({
|
|
|
5497
5559
|
}
|
|
5498
5560
|
try {
|
|
5499
5561
|
const strategy = await create({
|
|
5500
|
-
btcBinanceData:
|
|
5501
|
-
btcCoinbaseData:
|
|
5562
|
+
btcBinanceData: btcBinanceData ?? [],
|
|
5563
|
+
btcCoinbaseData: btcCoinbaseData ?? [],
|
|
5502
5564
|
onRuntimeClose
|
|
5503
5565
|
});
|
|
5504
5566
|
strategy.__tradejsUpdateReferenceData?.({
|
|
@@ -5904,7 +5966,7 @@ var createSignalsSession = async (lifecycle, scope = {}) => {
|
|
|
5904
5966
|
lifecycle
|
|
5905
5967
|
};
|
|
5906
5968
|
};
|
|
5907
|
-
var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCoinbaseData, runtimeStrategies, strategyStats, runtimeCloseNotifications, lifecycle, preloadStart, currentTimestamp, persistStrategyState, universe, interval2, intervalMs2, accountId, deploymentId, instrument, runtimeScopeUniverse) => {
|
|
5969
|
+
var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCoinbaseData, primaryBtcClosedData, primaryEthClosedData, primaryEthByTimestamp, runtimeStrategies, strategyStats, runtimeCloseNotifications, lifecycle, preloadStart, currentTimestamp, persistStrategyState, universe, interval2, intervalMs2, accountId, deploymentId, instrument, runtimeScopeUniverse, saveRuntimeSignalEvaluation) => {
|
|
5908
5970
|
const strategySignals = [];
|
|
5909
5971
|
const loadCached = (cachedSymbol) => connector.kline({
|
|
5910
5972
|
symbol: cachedSymbol,
|
|
@@ -5913,36 +5975,21 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5913
5975
|
cacheOnly: true,
|
|
5914
5976
|
interval: interval2
|
|
5915
5977
|
});
|
|
5916
|
-
const
|
|
5917
|
-
loadCached(symbol),
|
|
5918
|
-
loadCached("BTCUSDT"),
|
|
5919
|
-
loadCached("ETHUSDT")
|
|
5920
|
-
]) : [await loadCached(symbol), [], []];
|
|
5978
|
+
const cachedData = universe === "crypto" && symbol === "BTCUSDT" ? primaryBtcClosedData : universe === "crypto" && symbol === "ETHUSDT" ? primaryEthClosedData : await loadCached(symbol);
|
|
5921
5979
|
const closedData = getClosedCandlesForInterval(
|
|
5922
5980
|
cachedData,
|
|
5923
5981
|
currentTimestamp,
|
|
5924
5982
|
intervalMs2
|
|
5925
5983
|
);
|
|
5926
|
-
const closedBtcData =
|
|
5927
|
-
|
|
5928
|
-
currentTimestamp,
|
|
5929
|
-
intervalMs2
|
|
5930
|
-
);
|
|
5931
|
-
const closedEthData = getClosedCandlesForInterval(
|
|
5932
|
-
ethCachedData,
|
|
5933
|
-
currentTimestamp,
|
|
5934
|
-
intervalMs2
|
|
5935
|
-
);
|
|
5984
|
+
const closedBtcData = primaryBtcClosedData;
|
|
5985
|
+
const closedEthData = primaryEthClosedData;
|
|
5936
5986
|
const { alignedCoinCandles, alignedBtcCandles } = universe === "crypto" ? alignSymbolWithBtcReference(closedData, closedBtcData) : { alignedCoinCandles: closedData, alignedBtcCandles: closedData };
|
|
5937
|
-
const
|
|
5938
|
-
closedEthData.map((candle) => [candle.timestamp, candle])
|
|
5939
|
-
);
|
|
5940
|
-
const alignedEthCandles = alignedCoinCandles.map((candle) => ethByTimestamp.get(candle.timestamp)).filter(
|
|
5987
|
+
const alignedEthCandles = alignedCoinCandles.map((candle) => primaryEthByTimestamp.get(candle.timestamp)).filter(
|
|
5941
5988
|
(candle) => Boolean(candle)
|
|
5942
5989
|
);
|
|
5943
5990
|
const lastCandle = alignedCoinCandles.at(-1);
|
|
5944
5991
|
const btcLastCandle = alignedBtcCandles.at(-1);
|
|
5945
|
-
const ethLastCandle = lastCandle == null ? void 0 :
|
|
5992
|
+
const ethLastCandle = lastCandle == null ? void 0 : primaryEthByTimestamp.get(lastCandle.timestamp);
|
|
5946
5993
|
if (!lastCandle || !btcLastCandle) {
|
|
5947
5994
|
return strategySignals;
|
|
5948
5995
|
}
|
|
@@ -5956,6 +6003,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5956
6003
|
strategyName,
|
|
5957
6004
|
configId,
|
|
5958
6005
|
strategyCreator,
|
|
6006
|
+
sourceStrategyConfig,
|
|
5959
6007
|
strategyConfig,
|
|
5960
6008
|
strategyResults
|
|
5961
6009
|
} = runtimeStrategy;
|
|
@@ -5990,46 +6038,61 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5990
6038
|
configId
|
|
5991
6039
|
});
|
|
5992
6040
|
const stats = strategyStats.get(strategyName);
|
|
5993
|
-
const
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
btcBinanceData
|
|
6007
|
-
btcCoinbaseData
|
|
6008
|
-
onRuntimeClose
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6041
|
+
const initialDataLength = previousData.length;
|
|
6042
|
+
const initialBtcDataLength = previousBtcData.length;
|
|
6043
|
+
const initialEthDataLength = previousEthData.length;
|
|
6044
|
+
let evaluation;
|
|
6045
|
+
try {
|
|
6046
|
+
evaluation = await lifecycle.evaluate({
|
|
6047
|
+
key: lifecycleKey,
|
|
6048
|
+
timestamp: lastCandle.timestamp,
|
|
6049
|
+
config: {
|
|
6050
|
+
runtimeConfig,
|
|
6051
|
+
sourceStrategyConfig,
|
|
6052
|
+
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
6053
|
+
},
|
|
6054
|
+
btcBinanceData,
|
|
6055
|
+
btcCoinbaseData,
|
|
6056
|
+
onRuntimeClose: (event) => {
|
|
6057
|
+
runtimeCloseNotifications.push(event);
|
|
6058
|
+
},
|
|
6059
|
+
create: async ({
|
|
6060
|
+
btcBinanceData: lifecycleBtcBinanceData,
|
|
6061
|
+
btcCoinbaseData: lifecycleBtcCoinbaseData,
|
|
6062
|
+
onRuntimeClose
|
|
6063
|
+
}) => strategyCreator({
|
|
6064
|
+
userName: flags.user,
|
|
6065
|
+
connectorName,
|
|
6066
|
+
runtimeConfigId: configId,
|
|
6067
|
+
runtimeConfigSnapshot: {
|
|
6068
|
+
userConfig: sourceStrategyConfig,
|
|
6069
|
+
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
6070
|
+
},
|
|
6071
|
+
connector,
|
|
6072
|
+
symbol,
|
|
6073
|
+
...runtimeScopeUniverse ? {
|
|
6074
|
+
universe,
|
|
6075
|
+
assetClass: instrument?.assetClass,
|
|
6076
|
+
instrument,
|
|
6077
|
+
accountId,
|
|
6078
|
+
deploymentId
|
|
6079
|
+
} : {},
|
|
6080
|
+
data: previousData,
|
|
6081
|
+
btcData: universe === "crypto" ? previousBtcData : [],
|
|
6082
|
+
ethData: universe === "crypto" ? previousEthData : [],
|
|
6083
|
+
btcBinanceData: lifecycleBtcBinanceData,
|
|
6084
|
+
btcCoinbaseData: lifecycleBtcCoinbaseData,
|
|
6085
|
+
config: runtimeConfig,
|
|
6086
|
+
...persistStrategyState ? { sharedStrategyStateKey: lifecycleKey } : {},
|
|
6087
|
+
onRuntimeClose
|
|
6088
|
+
}),
|
|
6089
|
+
run: (strategy) => strategy(lastCandle, btcLastCandle, ethLastCandle)
|
|
6090
|
+
});
|
|
6091
|
+
} finally {
|
|
6092
|
+
previousData.length = initialDataLength;
|
|
6093
|
+
previousBtcData.length = initialBtcDataLength;
|
|
6094
|
+
previousEthData.length = initialEthDataLength;
|
|
6095
|
+
}
|
|
6033
6096
|
if (evaluation.action === "duplicate" || evaluation.action === "stale") {
|
|
6034
6097
|
continue;
|
|
6035
6098
|
}
|
|
@@ -6050,7 +6113,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6050
6113
|
if (typeof signal === "string") {
|
|
6051
6114
|
recordStrategyReason(strategyStats, strategyName, signal, "core");
|
|
6052
6115
|
}
|
|
6053
|
-
await saveRuntimeSignalEvaluation({
|
|
6116
|
+
await saveRuntimeSignalEvaluation?.({
|
|
6054
6117
|
evaluationId: buildRuntimeSignalEvaluationId({
|
|
6055
6118
|
strategyName,
|
|
6056
6119
|
symbol,
|
|
@@ -6116,7 +6179,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6116
6179
|
expire: runtimeSignalRetentionTtl
|
|
6117
6180
|
}
|
|
6118
6181
|
);
|
|
6119
|
-
await saveRuntimeSignalEvaluation({
|
|
6182
|
+
await saveRuntimeSignalEvaluation?.({
|
|
6120
6183
|
evaluationId: buildRuntimeSignalEvaluationId({
|
|
6121
6184
|
strategyName,
|
|
6122
6185
|
symbol,
|
|
@@ -6158,6 +6221,7 @@ var signals = async (options = {}) => {
|
|
|
6158
6221
|
let activeSession;
|
|
6159
6222
|
let projectHooks;
|
|
6160
6223
|
let afterSignalsHookContext = null;
|
|
6224
|
+
const runtimeSignalEvaluations = createRuntimeSignalEvaluationBuffer();
|
|
6161
6225
|
try {
|
|
6162
6226
|
const session = options.session ?? await createSignalsSession(createDefaultSignalsLifecycle());
|
|
6163
6227
|
activeSession = session;
|
|
@@ -6269,7 +6333,12 @@ var signals = async (options = {}) => {
|
|
|
6269
6333
|
if (flags.updateOnly) {
|
|
6270
6334
|
return;
|
|
6271
6335
|
}
|
|
6272
|
-
const [
|
|
6336
|
+
const [
|
|
6337
|
+
btcBinanceData,
|
|
6338
|
+
btcCoinbaseData,
|
|
6339
|
+
primaryBtcCachedData,
|
|
6340
|
+
primaryEthCachedData
|
|
6341
|
+
] = universe === "crypto" ? await timeOperation2(
|
|
6273
6342
|
"reference candles load",
|
|
6274
6343
|
() => Promise.all([
|
|
6275
6344
|
btcReferences.binance.kline({
|
|
@@ -6285,9 +6354,36 @@ var signals = async (options = {}) => {
|
|
|
6285
6354
|
end: currentTimestamp,
|
|
6286
6355
|
cacheOnly: true,
|
|
6287
6356
|
interval: interval2
|
|
6357
|
+
}),
|
|
6358
|
+
marketConnector.kline({
|
|
6359
|
+
symbol: "BTCUSDT",
|
|
6360
|
+
start: preloadStart,
|
|
6361
|
+
end: currentTimestamp,
|
|
6362
|
+
cacheOnly: true,
|
|
6363
|
+
interval: interval2
|
|
6364
|
+
}),
|
|
6365
|
+
marketConnector.kline({
|
|
6366
|
+
symbol: "ETHUSDT",
|
|
6367
|
+
start: preloadStart,
|
|
6368
|
+
end: currentTimestamp,
|
|
6369
|
+
cacheOnly: true,
|
|
6370
|
+
interval: interval2
|
|
6288
6371
|
})
|
|
6289
6372
|
])
|
|
6290
|
-
) : [[], []];
|
|
6373
|
+
) : [[], [], [], []];
|
|
6374
|
+
const primaryBtcClosedData = getClosedCandlesForInterval(
|
|
6375
|
+
primaryBtcCachedData,
|
|
6376
|
+
currentTimestamp,
|
|
6377
|
+
intervalMs2
|
|
6378
|
+
);
|
|
6379
|
+
const primaryEthClosedData = getClosedCandlesForInterval(
|
|
6380
|
+
primaryEthCachedData,
|
|
6381
|
+
currentTimestamp,
|
|
6382
|
+
intervalMs2
|
|
6383
|
+
);
|
|
6384
|
+
const primaryEthByTimestamp = new Map(
|
|
6385
|
+
primaryEthClosedData.map((candle) => [candle.timestamp, candle])
|
|
6386
|
+
);
|
|
6291
6387
|
const runtimeStrategies = await loadRuntimeStrategies({
|
|
6292
6388
|
userName: flags.user,
|
|
6293
6389
|
projectRoot,
|
|
@@ -6371,6 +6467,9 @@ var signals = async (options = {}) => {
|
|
|
6371
6467
|
marketConnector,
|
|
6372
6468
|
btcBinanceData,
|
|
6373
6469
|
btcCoinbaseData,
|
|
6470
|
+
primaryBtcClosedData,
|
|
6471
|
+
primaryEthClosedData,
|
|
6472
|
+
primaryEthByTimestamp,
|
|
6374
6473
|
runtimeStrategies,
|
|
6375
6474
|
strategyStats,
|
|
6376
6475
|
runtimeCloseNotifications,
|
|
@@ -6384,7 +6483,8 @@ var signals = async (options = {}) => {
|
|
|
6384
6483
|
accountId,
|
|
6385
6484
|
deployment?.id,
|
|
6386
6485
|
instrumentsBySymbol.get(symbol),
|
|
6387
|
-
sessionUniverse
|
|
6486
|
+
sessionUniverse,
|
|
6487
|
+
runtimeSignalEvaluations.save
|
|
6388
6488
|
);
|
|
6389
6489
|
if (strategySignals.length > 0) {
|
|
6390
6490
|
signals2.push(...strategySignals);
|
|
@@ -6425,6 +6525,14 @@ var signals = async (options = {}) => {
|
|
|
6425
6525
|
);
|
|
6426
6526
|
throw error;
|
|
6427
6527
|
} finally {
|
|
6528
|
+
try {
|
|
6529
|
+
await runtimeSignalEvaluations.flush();
|
|
6530
|
+
} catch (error) {
|
|
6531
|
+
import_logger4.logger.error(
|
|
6532
|
+
"runtime signal evaluation flush failed: %s",
|
|
6533
|
+
error?.message || String(error)
|
|
6534
|
+
);
|
|
6535
|
+
}
|
|
6428
6536
|
const durationMs = Date.now() - startedAt;
|
|
6429
6537
|
if (activeSession?.deployment) {
|
|
6430
6538
|
await (0, import_tradingAccounts2.saveRuntimeDeploymentHeartbeat)(flags.user, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"tradejs": "dist/cli.js"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@tradejs/base": "^2.0.
|
|
33
|
-
"@tradejs/connectors": "^2.0.
|
|
34
|
-
"@tradejs/core": "^2.0.
|
|
35
|
-
"@tradejs/indicators": "^2.0.
|
|
36
|
-
"@tradejs/infra": "^2.0.
|
|
37
|
-
"@tradejs/node": "^2.0.
|
|
38
|
-
"@tradejs/strategies": "^2.0.
|
|
39
|
-
"@tradejs/types": "^2.0.
|
|
32
|
+
"@tradejs/base": "^2.0.9",
|
|
33
|
+
"@tradejs/connectors": "^2.0.9",
|
|
34
|
+
"@tradejs/core": "^2.0.9",
|
|
35
|
+
"@tradejs/indicators": "^2.0.9",
|
|
36
|
+
"@tradejs/infra": "^2.0.9",
|
|
37
|
+
"@tradejs/node": "^2.0.9",
|
|
38
|
+
"@tradejs/strategies": "^2.0.9",
|
|
39
|
+
"@tradejs/types": "^2.0.9",
|
|
40
40
|
"args": "^5.0.3",
|
|
41
41
|
"bcryptjs": "^2.4.3",
|
|
42
42
|
"chalk": "4.1.2",
|