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