@tradejs/cli 3.1.0 → 3.1.2
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 +2 -0
- package/dist/cli.js +1330 -928
- package/dist/lib/coreResearch.js +52 -20
- package/dist/lib/researchRoots.js +59 -0
- package/dist/lib/runtimeLineage.js +19 -4
- package/dist/lib/runtimeModeConfig.js +1 -1
- package/dist/lib/runtimeSignalsStorage.js +2 -1
- package/dist/scripts/agentRun.js +37 -11
- package/dist/scripts/coreResearch.js +91 -30
- package/dist/scripts/replay.js +45 -12
- package/dist/scripts/replayRunner.js +45 -12
- package/dist/scripts/researchAuto.js +32 -11
- package/dist/scripts/runtimeConfig.js +395 -0
- package/dist/scripts/runtimeEvidence.js +1 -1
- package/dist/scripts/runtimeParity.js +1 -1
- package/dist/scripts/signals.js +138 -209
- package/dist/scripts/signalsDaemon.js +138 -209
- package/package.json +12 -8
package/dist/scripts/signals.js
CHANGED
|
@@ -46,10 +46,10 @@ var import_chalk7 = __toESM(require("chalk"));
|
|
|
46
46
|
var import_connectors6 = require("@tradejs/node/connectors");
|
|
47
47
|
var import_cli2 = require("@tradejs/node/cli");
|
|
48
48
|
var import_async3 = require("@tradejs/core/async");
|
|
49
|
-
var
|
|
49
|
+
var import_strategies5 = require("@tradejs/core/strategies");
|
|
50
50
|
var import_constants3 = require("@tradejs/core/constants");
|
|
51
|
-
var
|
|
52
|
-
var
|
|
51
|
+
var import_time2 = require("@tradejs/core/time");
|
|
52
|
+
var import_logger4 = require("@tradejs/infra/logger");
|
|
53
53
|
var import_runtimeDeployments = require("@tradejs/infra/runtimeDeployments");
|
|
54
54
|
|
|
55
55
|
// src/lib/marketData/windows.ts
|
|
@@ -3737,125 +3737,15 @@ var updateBtcReferenceHistory = async ({
|
|
|
3737
3737
|
};
|
|
3738
3738
|
|
|
3739
3739
|
// src/lib/signals/runtimeStrategies.ts
|
|
3740
|
-
var
|
|
3741
|
-
var import_redis2 = require("@tradejs/infra/redis");
|
|
3742
|
-
var import_tradingAccounts = require("@tradejs/infra/tradingAccounts");
|
|
3743
|
-
var import_strategies3 = require("@tradejs/node/strategies");
|
|
3744
|
-
|
|
3745
|
-
// src/lib/runtimeRedis.ts
|
|
3746
|
-
var import_redis = require("@tradejs/infra/redis");
|
|
3747
|
-
var import_time = require("@tradejs/core/time");
|
|
3748
|
-
var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
|
|
3749
|
-
var isRuntimeStrategyEnabled = (strategyConfig) => {
|
|
3750
|
-
const enabled = strategyConfig.ENABLE;
|
|
3751
|
-
return enabled !== false;
|
|
3752
|
-
};
|
|
3753
|
-
|
|
3754
|
-
// src/lib/signals/runtimeStrategies.ts
|
|
3755
|
-
var loadRuntimeStrategies = async ({
|
|
3756
|
-
userName,
|
|
3757
|
-
projectRoot,
|
|
3758
|
-
deployment,
|
|
3759
|
-
connectorName = "bybit",
|
|
3760
|
-
universe,
|
|
3761
|
-
accountId,
|
|
3762
|
-
interval
|
|
3763
|
-
}) => {
|
|
3764
|
-
const deploymentStrategies = new Map(
|
|
3765
|
-
(deployment?.strategies ?? []).map((strategy) => [
|
|
3766
|
-
strategy.strategyName,
|
|
3767
|
-
strategy
|
|
3768
|
-
])
|
|
3769
|
-
);
|
|
3770
|
-
const strategyConfigs = await Promise.all(
|
|
3771
|
-
(await (0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName)).map(
|
|
3772
|
-
async ({
|
|
3773
|
-
key,
|
|
3774
|
-
strategyName,
|
|
3775
|
-
configId,
|
|
3776
|
-
strategyConfig
|
|
3777
|
-
}) => {
|
|
3778
|
-
const deploymentStrategy = deployment ? deploymentStrategies.get(strategyName) : void 0;
|
|
3779
|
-
if (deploymentStrategy?.enabled === false) {
|
|
3780
|
-
import_logger.logger.info(
|
|
3781
|
-
"Skip deployment-disabled strategy config: %s",
|
|
3782
|
-
strategyName
|
|
3783
|
-
);
|
|
3784
|
-
return null;
|
|
3785
|
-
}
|
|
3786
|
-
if (!isRuntimeStrategyEnabled(strategyConfig)) {
|
|
3787
|
-
import_logger.logger.info(
|
|
3788
|
-
"Skip inactive strategy config by ENABLE=false: %s",
|
|
3789
|
-
strategyName
|
|
3790
|
-
);
|
|
3791
|
-
return null;
|
|
3792
|
-
}
|
|
3793
|
-
const configUniverse = deployment?.universe ?? (strategyConfig.UNIVERSE === "tradfi" ? "tradfi" : "crypto");
|
|
3794
|
-
const configInterval = String(
|
|
3795
|
-
deployment?.interval ?? strategyConfig.INTERVAL ?? "15"
|
|
3796
|
-
);
|
|
3797
|
-
const requestedAccountId = deployment?.accountId ?? (typeof strategyConfig.ACCOUNT_ID === "string" && strategyConfig.ACCOUNT_ID.trim() ? strategyConfig.ACCOUNT_ID.trim() : void 0);
|
|
3798
|
-
const resolvedAccount = await (0, import_tradingAccounts.resolveTradingAccount)({
|
|
3799
|
-
userName,
|
|
3800
|
-
accountId: requestedAccountId,
|
|
3801
|
-
provider: deployment?.provider ?? connectorName,
|
|
3802
|
-
universe: configUniverse
|
|
3803
|
-
});
|
|
3804
|
-
const effectiveAccountId = resolvedAccount?.id ?? requestedAccountId;
|
|
3805
|
-
const [strategyCreator, strategyResults] = await Promise.all([
|
|
3806
|
-
(0, import_strategies3.getStrategyCreator)(strategyName, projectRoot),
|
|
3807
|
-
(0, import_redis2.getData)(import_redis2.redisKeys.strategyResults(userName, strategyName), {})
|
|
3808
|
-
]);
|
|
3809
|
-
if (!strategyCreator) {
|
|
3810
|
-
import_logger.logger.warn("Skip unknown strategy config key: %s", key);
|
|
3811
|
-
return null;
|
|
3812
|
-
}
|
|
3813
|
-
return {
|
|
3814
|
-
strategyName,
|
|
3815
|
-
configId,
|
|
3816
|
-
interval: configInterval,
|
|
3817
|
-
universe: configUniverse,
|
|
3818
|
-
accountId: effectiveAccountId,
|
|
3819
|
-
releaseCompositionId: deploymentStrategy?.releaseCompositionId,
|
|
3820
|
-
strategyCreator,
|
|
3821
|
-
sourceStrategyConfig: strategyConfig,
|
|
3822
|
-
strategyConfig: {
|
|
3823
|
-
...strategyConfig,
|
|
3824
|
-
...deploymentStrategy?.config,
|
|
3825
|
-
INTERVAL: configInterval,
|
|
3826
|
-
UNIVERSE: configUniverse,
|
|
3827
|
-
...effectiveAccountId ? { ACCOUNT_ID: effectiveAccountId } : {},
|
|
3828
|
-
...deploymentStrategy?.policyProfileId ? { POLICY_PROFILE_ID: deploymentStrategy.policyProfileId } : {}
|
|
3829
|
-
},
|
|
3830
|
-
strategyResults: strategyResults ?? {}
|
|
3831
|
-
};
|
|
3832
|
-
}
|
|
3833
|
-
)
|
|
3834
|
-
);
|
|
3835
|
-
const active = strategyConfigs.filter(Boolean);
|
|
3836
|
-
const byStrategyAndAccount = /* @__PURE__ */ new Map();
|
|
3837
|
-
for (const candidate of active) {
|
|
3838
|
-
const conflictKey = `${candidate.strategyName}:${candidate.accountId ?? "default"}`;
|
|
3839
|
-
const existing = byStrategyAndAccount.get(conflictKey);
|
|
3840
|
-
if (existing) {
|
|
3841
|
-
throw new Error(
|
|
3842
|
-
`Runtime strategy conflict: ${candidate.strategyName} configs "${existing.configId}" and "${candidate.configId}" resolve to account "${candidate.accountId ?? "default"}". Disable one config or select another account.`
|
|
3843
|
-
);
|
|
3844
|
-
}
|
|
3845
|
-
byStrategyAndAccount.set(conflictKey, candidate);
|
|
3846
|
-
}
|
|
3847
|
-
return active.filter(
|
|
3848
|
-
(candidate) => (!universe || candidate.universe === universe) && (!interval || String(candidate.interval) === String(interval)) && (!accountId || candidate.accountId === accountId)
|
|
3849
|
-
);
|
|
3850
|
-
};
|
|
3740
|
+
var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
3851
3741
|
|
|
3852
3742
|
// src/lib/signals/skipStats.ts
|
|
3853
3743
|
var import_chalk6 = __toESM(require("chalk"));
|
|
3854
|
-
var
|
|
3744
|
+
var import_logger = require("@tradejs/infra/logger");
|
|
3855
3745
|
|
|
3856
3746
|
// src/lib/runtimeSignalsStorage.ts
|
|
3857
3747
|
var import_constants2 = require("@tradejs/core/constants");
|
|
3858
|
-
var
|
|
3748
|
+
var import_time = require("@tradejs/core/time");
|
|
3859
3749
|
var SECONDS_PER_DAY = 86400;
|
|
3860
3750
|
var RUNTIME_SIGNAL_RETENTION_DAYS_ENV = "RUNTIME_SIGNAL_RETENTION_DAYS";
|
|
3861
3751
|
var DEFAULT_RUNTIME_SIGNAL_RETENTION_TTL_SECONDS = import_constants2.TTL_3D;
|
|
@@ -3881,7 +3771,8 @@ var toRuntimeSignalBucketRef = (signal) => ({
|
|
|
3881
3771
|
symbol: signal.symbol,
|
|
3882
3772
|
strategy: signal.strategy,
|
|
3883
3773
|
timestamp: signal.timestamp,
|
|
3884
|
-
...signal.runtimeConfigId && signal.runtimeConfigId !== "config" ? { runtimeConfigId: signal.runtimeConfigId } : {}
|
|
3774
|
+
...signal.runtimeConfigId && signal.runtimeConfigId !== "config" ? { runtimeConfigId: signal.runtimeConfigId } : {},
|
|
3775
|
+
...signal.runtimeReleaseVersion ? { runtimeReleaseVersion: signal.runtimeReleaseVersion } : {}
|
|
3885
3776
|
});
|
|
3886
3777
|
var shouldStoreRuntimeSignalDiagnostics = (signal) => signal.orderStatus === "completed" || signal.orderStatus === "failed";
|
|
3887
3778
|
var toStoredRuntimeSignal = (signal) => {
|
|
@@ -3980,30 +3871,30 @@ var recordStrategyReason = (strategyStats, strategyName, reason, fallbackSource
|
|
|
3980
3871
|
);
|
|
3981
3872
|
};
|
|
3982
3873
|
var logStrategySkipStats = (runtimeStrategies, strategyStats) => {
|
|
3983
|
-
|
|
3874
|
+
import_logger.logger.info(import_chalk6.default.yellow("skip stats:"));
|
|
3984
3875
|
for (const { strategyName } of runtimeStrategies) {
|
|
3985
3876
|
const stats = strategyStats.get(strategyName);
|
|
3986
3877
|
if (!stats) {
|
|
3987
3878
|
continue;
|
|
3988
3879
|
}
|
|
3989
|
-
|
|
3880
|
+
import_logger.logger.info(
|
|
3990
3881
|
`${strategyName}: evaluated=${stats.evaluated}, signals=${stats.signals}`
|
|
3991
3882
|
);
|
|
3992
3883
|
const sortedReasons = [...stats.reasons.entries()].sort(
|
|
3993
3884
|
(left, right) => right[1] - left[1] || left[0].localeCompare(right[0])
|
|
3994
3885
|
);
|
|
3995
3886
|
if (!sortedReasons.length) {
|
|
3996
|
-
|
|
3887
|
+
import_logger.logger.info(" none");
|
|
3997
3888
|
continue;
|
|
3998
3889
|
}
|
|
3999
3890
|
for (const [reason, count] of sortedReasons) {
|
|
4000
|
-
|
|
3891
|
+
import_logger.logger.info(` ${reason}: ${count}`);
|
|
4001
3892
|
}
|
|
4002
3893
|
}
|
|
4003
3894
|
};
|
|
4004
3895
|
|
|
4005
3896
|
// src/lib/signals/evaluations.ts
|
|
4006
|
-
var
|
|
3897
|
+
var import_redis = require("@tradejs/infra/redis");
|
|
4007
3898
|
|
|
4008
3899
|
// src/lib/runtimeLineage.ts
|
|
4009
3900
|
var import_node_child_process = require("child_process");
|
|
@@ -4011,7 +3902,7 @@ var import_node_crypto2 = require("crypto");
|
|
|
4011
3902
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
4012
3903
|
var import_node_path2 = __toESM(require("path"));
|
|
4013
3904
|
var import_types = require("@tradejs/types");
|
|
4014
|
-
var
|
|
3905
|
+
var import_strategies3 = require("@tradejs/node/strategies");
|
|
4015
3906
|
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
4016
3907
|
|
|
4017
3908
|
// src/lib/strategyGateFingerprint.ts
|
|
@@ -4241,20 +4132,35 @@ var resolveRuntimeGateFingerprint = async ({
|
|
|
4241
4132
|
gateFingerprintCache.set(cacheKey, result);
|
|
4242
4133
|
return result;
|
|
4243
4134
|
};
|
|
4244
|
-
|
|
4135
|
+
async function buildRuntimeLineage({
|
|
4245
4136
|
projectRoot,
|
|
4246
4137
|
strategyName,
|
|
4247
4138
|
compositionId,
|
|
4139
|
+
releaseVersion,
|
|
4140
|
+
strategyPackageVersion,
|
|
4141
|
+
runtimePackageVersion,
|
|
4248
4142
|
config: config2,
|
|
4249
4143
|
runContext,
|
|
4250
4144
|
env = process.env
|
|
4251
|
-
})
|
|
4145
|
+
}) {
|
|
4146
|
+
if (releaseVersion != null) {
|
|
4147
|
+
if (!Number.isSafeInteger(releaseVersion) || releaseVersion <= 0) {
|
|
4148
|
+
throw new Error(`Invalid runtime releaseVersion: ${releaseVersion}`);
|
|
4149
|
+
}
|
|
4150
|
+
return {
|
|
4151
|
+
schemaVersion: 2,
|
|
4152
|
+
releaseVersion,
|
|
4153
|
+
strategyPackageVersion,
|
|
4154
|
+
runtimePackageVersion,
|
|
4155
|
+
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4252
4158
|
const git = resolveGitLineage(projectRoot);
|
|
4253
|
-
const hyperliquidPerpUniverseFingerprint = typeof
|
|
4159
|
+
const hyperliquidPerpUniverseFingerprint = typeof import_strategies3.getHyperliquidPerpUniverseSnapshot === "function" ? (0, import_strategies3.getHyperliquidPerpUniverseSnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
4254
4160
|
projectRoot,
|
|
4255
4161
|
"packages/node/src/config/hyperliquidPerpUniverse.json"
|
|
4256
4162
|
);
|
|
4257
|
-
const hyperliquidWhaleRegistryFingerprint = typeof
|
|
4163
|
+
const hyperliquidWhaleRegistryFingerprint = typeof import_strategies3.getHyperliquidWhaleRegistrySnapshot === "function" ? (0, import_strategies3.getHyperliquidWhaleRegistrySnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
4258
4164
|
projectRoot,
|
|
4259
4165
|
"packages/node/src/config/hyperliquidWhales.json"
|
|
4260
4166
|
);
|
|
@@ -4283,8 +4189,8 @@ var buildRuntimeLineage = async ({
|
|
|
4283
4189
|
contextFingerprint: fingerprintRuntimeValue(context),
|
|
4284
4190
|
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
4285
4191
|
};
|
|
4286
|
-
}
|
|
4287
|
-
var runtimeLineageKey = (lineage) => [
|
|
4192
|
+
}
|
|
4193
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? ["v2", lineage.releaseVersion].join(":") : [
|
|
4288
4194
|
lineage.schemaVersion,
|
|
4289
4195
|
lineage.compositionId ?? "unbound-composition",
|
|
4290
4196
|
lineage.gitSha ?? "unknown",
|
|
@@ -4302,11 +4208,13 @@ var buildRuntimeSignalEvaluationId = ({
|
|
|
4302
4208
|
strategyName,
|
|
4303
4209
|
symbol,
|
|
4304
4210
|
timestamp,
|
|
4305
|
-
runtimeConfigId
|
|
4306
|
-
|
|
4211
|
+
runtimeConfigId,
|
|
4212
|
+
runtimeReleaseVersion
|
|
4213
|
+
}) => runtimeReleaseVersion ? [strategyName, `v${runtimeReleaseVersion}`, symbol, timestamp].join(":") : runtimeConfigId && runtimeConfigId !== "config" ? [strategyName, runtimeConfigId, symbol, timestamp].join(":") : [strategyName, symbol, timestamp].join(":");
|
|
4307
4214
|
var buildLineageField = (scope) => [
|
|
4308
4215
|
scope.strategy,
|
|
4309
4216
|
scope.runtimeConfigId ?? "config",
|
|
4217
|
+
scope.runtimeReleaseVersion ? `v${scope.runtimeReleaseVersion}` : "legacy",
|
|
4310
4218
|
scope.symbol,
|
|
4311
4219
|
runtimeLineageKey(scope.lineage)
|
|
4312
4220
|
].join(":");
|
|
@@ -4314,7 +4222,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4314
4222
|
if (evaluations.length === 0) return;
|
|
4315
4223
|
const evaluationsByDay = /* @__PURE__ */ new Map();
|
|
4316
4224
|
for (const evaluation of evaluations) {
|
|
4317
|
-
const dayKey = (0,
|
|
4225
|
+
const dayKey = (0, import_time.getRuntimeStorageDayKey)(evaluation.timestamp);
|
|
4318
4226
|
const dayEvaluations = evaluationsByDay.get(dayKey) ?? [];
|
|
4319
4227
|
dayEvaluations.push(evaluation);
|
|
4320
4228
|
evaluationsByDay.set(dayKey, dayEvaluations);
|
|
@@ -4326,7 +4234,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4326
4234
|
runtimeLineageScopeCacheDayKey = dayKey;
|
|
4327
4235
|
runtimeLineageScopeCacheLoaded = false;
|
|
4328
4236
|
}
|
|
4329
|
-
const lineageBucket =
|
|
4237
|
+
const lineageBucket = import_redis.redisKeys.runtimeLineageScopeBucket(
|
|
4330
4238
|
dayEvaluations[0].userName,
|
|
4331
4239
|
dayKey
|
|
4332
4240
|
);
|
|
@@ -4334,7 +4242,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4334
4242
|
(evaluation) => evaluation.runtimeLineage != null
|
|
4335
4243
|
);
|
|
4336
4244
|
if (lineageEvaluations.length > 0 && !runtimeLineageScopeCacheLoaded) {
|
|
4337
|
-
const storedScopes = await (0,
|
|
4245
|
+
const storedScopes = await (0, import_redis.getHashJsonValues)(lineageBucket);
|
|
4338
4246
|
for (const scope of storedScopes) {
|
|
4339
4247
|
const lineageField = buildLineageField(scope);
|
|
4340
4248
|
runtimeLineageScopeCache.set(`${lineageBucket}:${lineageField}`, scope);
|
|
@@ -4346,6 +4254,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4346
4254
|
const lineageField = buildLineageField({
|
|
4347
4255
|
strategy: evaluation.strategy,
|
|
4348
4256
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4257
|
+
runtimeReleaseVersion: evaluation.runtimeReleaseVersion,
|
|
4349
4258
|
symbol: evaluation.symbol,
|
|
4350
4259
|
lineage: evaluation.runtimeLineage
|
|
4351
4260
|
});
|
|
@@ -4355,6 +4264,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4355
4264
|
strategy: evaluation.strategy,
|
|
4356
4265
|
symbol: evaluation.symbol,
|
|
4357
4266
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4267
|
+
runtimeReleaseVersion: evaluation.runtimeReleaseVersion,
|
|
4358
4268
|
lineage: evaluation.runtimeLineage,
|
|
4359
4269
|
firstTimestamp: Math.min(
|
|
4360
4270
|
existing?.firstTimestamp ?? evaluation.timestamp,
|
|
@@ -4369,7 +4279,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4369
4279
|
lineageWrites.set(lineageField, scope);
|
|
4370
4280
|
}
|
|
4371
4281
|
if (lineageWrites.size > 0) {
|
|
4372
|
-
await (0,
|
|
4282
|
+
await (0, import_redis.setHashJsonFields)(
|
|
4373
4283
|
lineageBucket,
|
|
4374
4284
|
[...lineageWrites].map(([field, data]) => ({ field, data })),
|
|
4375
4285
|
{
|
|
@@ -4381,7 +4291,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4381
4291
|
const statsIncrements = /* @__PURE__ */ new Map();
|
|
4382
4292
|
for (const evaluation of dayEvaluations) {
|
|
4383
4293
|
if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
|
|
4384
|
-
const bucket =
|
|
4294
|
+
const bucket = import_redis.redisKeys.runtimeSignalEvaluationBucket(
|
|
4385
4295
|
evaluation.userName,
|
|
4386
4296
|
dayKey,
|
|
4387
4297
|
evaluation.strategy
|
|
@@ -4393,7 +4303,7 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4393
4303
|
});
|
|
4394
4304
|
detailedWrites.set(bucket, entries);
|
|
4395
4305
|
}
|
|
4396
|
-
const statsBucket =
|
|
4306
|
+
const statsBucket = import_redis.redisKeys.runtimeSignalEvaluationStatsBucket(
|
|
4397
4307
|
evaluation.userName,
|
|
4398
4308
|
dayKey,
|
|
4399
4309
|
evaluation.strategy
|
|
@@ -4408,12 +4318,12 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4408
4318
|
}
|
|
4409
4319
|
await Promise.all([
|
|
4410
4320
|
...[...detailedWrites].map(
|
|
4411
|
-
([bucket, entries]) => (0,
|
|
4321
|
+
([bucket, entries]) => (0, import_redis.setHashJsonFields)(bucket, entries, {
|
|
4412
4322
|
expire: runtimeSignalRetentionTtl
|
|
4413
4323
|
})
|
|
4414
4324
|
),
|
|
4415
4325
|
...[...statsIncrements].map(
|
|
4416
|
-
([bucket, increments]) => (0,
|
|
4326
|
+
([bucket, increments]) => (0, import_redis.incrHashFields)(bucket, increments, {
|
|
4417
4327
|
expire: runtimeSignalRetentionTtl
|
|
4418
4328
|
})
|
|
4419
4329
|
)
|
|
@@ -4429,9 +4339,9 @@ var createRuntimeSignalEvaluationBuffer = () => {
|
|
|
4429
4339
|
const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
|
|
4430
4340
|
const signalRefsByBucket = /* @__PURE__ */ new Map();
|
|
4431
4341
|
for (const { userName, signal } of pendingSignals) {
|
|
4432
|
-
const bucket =
|
|
4342
|
+
const bucket = import_redis.redisKeys.runtimeSignalBucket(
|
|
4433
4343
|
userName,
|
|
4434
|
-
(0,
|
|
4344
|
+
(0, import_time.getRuntimeStorageDayKey)(signal.timestamp),
|
|
4435
4345
|
signal.strategy
|
|
4436
4346
|
);
|
|
4437
4347
|
const entries = signalRefsByBucket.get(bucket) ?? [];
|
|
@@ -4443,14 +4353,14 @@ var createRuntimeSignalEvaluationBuffer = () => {
|
|
|
4443
4353
|
}
|
|
4444
4354
|
await Promise.all([
|
|
4445
4355
|
...pendingSignals.map(
|
|
4446
|
-
({ signal }) => (0,
|
|
4447
|
-
|
|
4356
|
+
({ signal }) => (0, import_redis.setData)(
|
|
4357
|
+
import_redis.redisKeys.storeSignal(signal.symbol, signal.signalId),
|
|
4448
4358
|
toStoredRuntimeSignal(signal),
|
|
4449
4359
|
{ expire: runtimeSignalRetentionTtl }
|
|
4450
4360
|
)
|
|
4451
4361
|
),
|
|
4452
4362
|
...[...signalRefsByBucket].map(
|
|
4453
|
-
([bucket, entries]) => (0,
|
|
4363
|
+
([bucket, entries]) => (0, import_redis.setHashJsonFields)(bucket, entries, {
|
|
4454
4364
|
expire: runtimeSignalRetentionTtl
|
|
4455
4365
|
})
|
|
4456
4366
|
)
|
|
@@ -4684,14 +4594,14 @@ var runSignalsDaemon = async ({
|
|
|
4684
4594
|
|
|
4685
4595
|
// src/lib/signals/klineFeed.ts
|
|
4686
4596
|
var import_connectors5 = require("@tradejs/connectors");
|
|
4687
|
-
var
|
|
4597
|
+
var import_logger2 = require("@tradejs/infra/logger");
|
|
4688
4598
|
var import_candles = require("@tradejs/infra/timescale/candles");
|
|
4689
4599
|
|
|
4690
4600
|
// src/lib/marketData/klineEvents.ts
|
|
4691
4601
|
var import_ioredis = __toESM(require("ioredis"));
|
|
4692
|
-
var
|
|
4602
|
+
var import_redis2 = require("@tradejs/infra/redis");
|
|
4693
4603
|
var MARKET_KLINE_CHANNEL = "tradejs:market:kline";
|
|
4694
|
-
var publishMarketKlineEvent = (event) => (0,
|
|
4604
|
+
var publishMarketKlineEvent = (event) => (0, import_redis2.publishData)(MARKET_KLINE_CHANNEL, event);
|
|
4695
4605
|
|
|
4696
4606
|
// src/lib/signals/klineFeed.ts
|
|
4697
4607
|
var FLUSH_DELAY_MS = 100;
|
|
@@ -4745,7 +4655,7 @@ var createSignalsKlineFeed = async ({
|
|
|
4745
4655
|
if (flushTimer || closed) return;
|
|
4746
4656
|
flushTimer = setTimeout(() => {
|
|
4747
4657
|
void flush().catch(
|
|
4748
|
-
(error) =>
|
|
4658
|
+
(error) => import_logger2.logger.error("websocket candle batch flush failed: %s", String(error))
|
|
4749
4659
|
);
|
|
4750
4660
|
}, FLUSH_DELAY_MS);
|
|
4751
4661
|
};
|
|
@@ -4762,7 +4672,7 @@ var createSignalsKlineFeed = async ({
|
|
|
4762
4672
|
confirm: event.confirm,
|
|
4763
4673
|
receivedAt: event.receivedAt
|
|
4764
4674
|
}).catch(
|
|
4765
|
-
(error) =>
|
|
4675
|
+
(error) => import_logger2.logger.warn("websocket candle publish failed: %s", String(error))
|
|
4766
4676
|
);
|
|
4767
4677
|
if (!event.confirm) return;
|
|
4768
4678
|
pending.set(`${event.symbol}:${event.candle.timestamp}`, {
|
|
@@ -4815,8 +4725,8 @@ var createSignalsKlineFeed = async ({
|
|
|
4815
4725
|
};
|
|
4816
4726
|
|
|
4817
4727
|
// src/lib/signals/tickerEvaluator.ts
|
|
4818
|
-
var
|
|
4819
|
-
var
|
|
4728
|
+
var import_strategies4 = require("@tradejs/node/strategies");
|
|
4729
|
+
var import_logger3 = require("@tradejs/infra/logger");
|
|
4820
4730
|
|
|
4821
4731
|
// src/lib/runtimeModeConfig.ts
|
|
4822
4732
|
var buildRuntimeModeStrategyConfig = ({
|
|
@@ -4830,7 +4740,7 @@ var buildRuntimeModeStrategyConfig = ({
|
|
|
4830
4740
|
...strategyConfig,
|
|
4831
4741
|
ENV: env,
|
|
4832
4742
|
MAKE_ORDERS: makeOrders,
|
|
4833
|
-
INTERVAL: interval,
|
|
4743
|
+
INTERVAL: strategyConfig.INTERVAL ?? interval,
|
|
4834
4744
|
...typeof recordRuntimeTrades === "boolean" ? { RECORD_RUNTIME_TRADES: recordRuntimeTrades } : {},
|
|
4835
4745
|
...aiReplayAnalyses?.length ? { AI_REPLAY_ANALYSES: aiReplayAnalyses } : {}
|
|
4836
4746
|
});
|
|
@@ -4894,12 +4804,16 @@ var createSignalsTickerEvaluator = ({
|
|
|
4894
4804
|
const {
|
|
4895
4805
|
strategyName,
|
|
4896
4806
|
configId,
|
|
4807
|
+
releaseVersion,
|
|
4808
|
+
controlState,
|
|
4809
|
+
strategyPackageVersion,
|
|
4810
|
+
runtimePackageVersion,
|
|
4897
4811
|
strategyCreator,
|
|
4898
|
-
releaseCompositionId,
|
|
4899
4812
|
sourceStrategyConfig,
|
|
4900
4813
|
strategyConfig,
|
|
4901
4814
|
strategyResults
|
|
4902
4815
|
} = runtimeStrategy;
|
|
4816
|
+
const runtimeIdentity = releaseVersion ? `v${releaseVersion}` : configId ?? "config";
|
|
4903
4817
|
const symbolResultConfig = strategyResults?.[symbol]?.config ?? null;
|
|
4904
4818
|
const runtimeConfig = buildRuntimeModeStrategyConfig({
|
|
4905
4819
|
strategyConfig,
|
|
@@ -4910,7 +4824,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4910
4824
|
const runtimeLineage = await buildRuntimeLineage({
|
|
4911
4825
|
projectRoot,
|
|
4912
4826
|
strategyName,
|
|
4913
|
-
|
|
4827
|
+
releaseVersion,
|
|
4828
|
+
strategyPackageVersion,
|
|
4829
|
+
runtimePackageVersion,
|
|
4914
4830
|
config: { configId, strategyConfig, symbolResultConfig },
|
|
4915
4831
|
runContext: {
|
|
4916
4832
|
connectorName: connectorName.toLowerCase(),
|
|
@@ -4926,7 +4842,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4926
4842
|
symbol,
|
|
4927
4843
|
interval,
|
|
4928
4844
|
strategyName,
|
|
4929
|
-
configId
|
|
4845
|
+
configId: runtimeIdentity
|
|
4930
4846
|
});
|
|
4931
4847
|
const stats = strategyStats.get(strategyName);
|
|
4932
4848
|
const initialLengths = [
|
|
@@ -4951,6 +4867,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4951
4867
|
userName,
|
|
4952
4868
|
connectorName,
|
|
4953
4869
|
runtimeConfigId: configId,
|
|
4870
|
+
runtimeReleaseVersion: releaseVersion,
|
|
4871
|
+
entriesPaused: controlState === "entries_paused",
|
|
4872
|
+
runtimeLineage,
|
|
4954
4873
|
runtimeConfigSnapshot: {
|
|
4955
4874
|
userConfig: sourceStrategyConfig,
|
|
4956
4875
|
symbolResultConfig
|
|
@@ -4984,7 +4903,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4984
4903
|
continue;
|
|
4985
4904
|
}
|
|
4986
4905
|
if (evaluation.action.startsWith("rebuilt_")) {
|
|
4987
|
-
|
|
4906
|
+
import_logger3.logger.info(
|
|
4988
4907
|
"Rebuilt signals strategy state (%s): %s %s",
|
|
4989
4908
|
evaluation.action.slice("rebuilt_".length),
|
|
4990
4909
|
strategyName,
|
|
@@ -5003,11 +4922,13 @@ var createSignalsTickerEvaluator = ({
|
|
|
5003
4922
|
strategyName,
|
|
5004
4923
|
symbol,
|
|
5005
4924
|
timestamp: lastCandle.timestamp,
|
|
5006
|
-
runtimeConfigId: configId
|
|
4925
|
+
runtimeConfigId: configId,
|
|
4926
|
+
runtimeReleaseVersion: releaseVersion
|
|
5007
4927
|
}),
|
|
5008
4928
|
userName,
|
|
5009
4929
|
strategy: strategyName,
|
|
5010
4930
|
runtimeConfigId: configId,
|
|
4931
|
+
runtimeReleaseVersion: releaseVersion,
|
|
5011
4932
|
runtimeLineage,
|
|
5012
4933
|
symbol,
|
|
5013
4934
|
interval,
|
|
@@ -5025,11 +4946,15 @@ var createSignalsTickerEvaluator = ({
|
|
|
5025
4946
|
}
|
|
5026
4947
|
if (stats) stats.signals += 1;
|
|
5027
4948
|
signal.runtimeConfigId = configId;
|
|
4949
|
+
signal.runtimeReleaseVersion = releaseVersion;
|
|
5028
4950
|
signal.runtimeLineage = runtimeLineage;
|
|
5029
4951
|
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
5030
4952
|
signal.signalId = `${signal.signalId}:${configId}`;
|
|
5031
4953
|
}
|
|
5032
|
-
|
|
4954
|
+
if (releaseVersion && !signal.signalId.endsWith(`:v${releaseVersion}`)) {
|
|
4955
|
+
signal.signalId = `${signal.signalId}:v${releaseVersion}`;
|
|
4956
|
+
}
|
|
4957
|
+
await (0, import_strategies4.enrichSignalWithBinanceMarketContext)({ signal, env: "CRON" });
|
|
5033
4958
|
if (signal.orderStatus === "skipped" && typeof signal.orderSkipReason === "string" && signal.orderSkipReason.trim()) {
|
|
5034
4959
|
recordStrategyReason(
|
|
5035
4960
|
strategyStats,
|
|
@@ -5045,11 +4970,13 @@ var createSignalsTickerEvaluator = ({
|
|
|
5045
4970
|
strategyName,
|
|
5046
4971
|
symbol,
|
|
5047
4972
|
timestamp: lastCandle.timestamp,
|
|
5048
|
-
runtimeConfigId: configId
|
|
4973
|
+
runtimeConfigId: configId,
|
|
4974
|
+
runtimeReleaseVersion: releaseVersion
|
|
5049
4975
|
}),
|
|
5050
4976
|
userName,
|
|
5051
4977
|
strategy: strategyName,
|
|
5052
4978
|
runtimeConfigId: configId,
|
|
4979
|
+
runtimeReleaseVersion: releaseVersion,
|
|
5053
4980
|
runtimeLineage,
|
|
5054
4981
|
symbol,
|
|
5055
4982
|
interval,
|
|
@@ -5069,7 +4996,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
5069
4996
|
...signal.aiAnalysis ? { aiAnalysis: signal.aiAnalysis } : {},
|
|
5070
4997
|
...signal.ml ? { ml: signal.ml } : {}
|
|
5071
4998
|
});
|
|
5072
|
-
|
|
4999
|
+
import_logger3.logger.info("Signal found %s by strategy %s", symbol, strategyName);
|
|
5073
5000
|
}
|
|
5074
5001
|
return strategySignals;
|
|
5075
5002
|
};
|
|
@@ -5112,12 +5039,12 @@ var createSignalsRunner = (config2) => {
|
|
|
5112
5039
|
const createDefaultSignalsLifecycle = (runtimeInterval = interval) => createSignalsStrategyLifecycle({
|
|
5113
5040
|
intervalMs: Number(runtimeInterval) * 6e4,
|
|
5114
5041
|
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
5115
|
-
releaseState:
|
|
5042
|
+
releaseState: import_strategies5.releaseStrategyReplayCache
|
|
5116
5043
|
});
|
|
5117
5044
|
const timeOperation2 = (label, operation) => timeOperation(
|
|
5118
5045
|
label,
|
|
5119
5046
|
operation,
|
|
5120
|
-
(message) =>
|
|
5047
|
+
(message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
5121
5048
|
);
|
|
5122
5049
|
const formatSlowSignalsWarning = (params) => [
|
|
5123
5050
|
"<b>Slow yarn signals run</b>",
|
|
@@ -5131,7 +5058,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5131
5058
|
if (connectorName) {
|
|
5132
5059
|
return connectorName;
|
|
5133
5060
|
}
|
|
5134
|
-
|
|
5061
|
+
import_logger4.logger.warn(
|
|
5135
5062
|
'Unknown connector "%s". Fallback to %s.',
|
|
5136
5063
|
String(value || "").trim() || String(value),
|
|
5137
5064
|
import_connectors6.DEFAULT_CONNECTOR_NAME
|
|
@@ -5147,12 +5074,17 @@ var createSignalsRunner = (config2) => {
|
|
|
5147
5074
|
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
5148
5075
|
}
|
|
5149
5076
|
const requestedRuntimeInterval = scope.interval ?? interval;
|
|
5150
|
-
const
|
|
5077
|
+
const versionedDeployment = Boolean(
|
|
5078
|
+
deployment?.strategies.some(
|
|
5079
|
+
(strategy) => strategy.releaseVersion != null
|
|
5080
|
+
)
|
|
5081
|
+
);
|
|
5082
|
+
const runtimeInterval = versionedDeployment ? requestedRuntimeInterval : deployment?.interval ?? requestedRuntimeInterval;
|
|
5151
5083
|
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
5152
5084
|
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
5153
5085
|
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
5154
5086
|
}
|
|
5155
|
-
if (deployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
5087
|
+
if (deployment && !versionedDeployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
5156
5088
|
throw new Error(
|
|
5157
5089
|
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
5158
5090
|
);
|
|
@@ -5160,7 +5092,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5160
5092
|
const connectorName = await resolveSignalsConnectorName(
|
|
5161
5093
|
deployment?.connectorName ?? scope.connectorName ?? config2.connectorName
|
|
5162
5094
|
);
|
|
5163
|
-
const universe = deployment?.universe ?? scope.universe ?? config2.universe;
|
|
5095
|
+
const universe = versionedDeployment ? scope.universe ?? config2.universe : deployment?.universe ?? scope.universe ?? config2.universe;
|
|
5164
5096
|
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? config2.accountId;
|
|
5165
5097
|
const connectorFactory = await (0, import_connectors6.getConnectorCreatorByName)(
|
|
5166
5098
|
connectorName,
|
|
@@ -5181,7 +5113,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5181
5113
|
userName: config2.userName,
|
|
5182
5114
|
projectRoot,
|
|
5183
5115
|
shouldUseDedicatedReferences: universe === "crypto" && connectorName.toLowerCase() === import_connectors6.DEFAULT_CONNECTOR_NAME.toLowerCase(),
|
|
5184
|
-
warn: (message) =>
|
|
5116
|
+
warn: (message) => import_logger4.logger.warn(message)
|
|
5185
5117
|
});
|
|
5186
5118
|
return {
|
|
5187
5119
|
connectorName,
|
|
@@ -5252,8 +5184,8 @@ var createSignalsRunner = (config2) => {
|
|
|
5252
5184
|
}
|
|
5253
5185
|
const projectConfig = await (0, import_cli2.loadTradejsConfig)(projectRoot);
|
|
5254
5186
|
projectHooks = projectConfig.hooks;
|
|
5255
|
-
const currentTimestamp = (0,
|
|
5256
|
-
const preloadStart = (0,
|
|
5187
|
+
const currentTimestamp = (0, import_time2.getTimestamp)();
|
|
5188
|
+
const preloadStart = (0, import_time2.getTimestamp)(import_constants3.SIGNALS_CLI_PRELOAD_DAYS);
|
|
5257
5189
|
if (!config2.cacheOnly && session.klineFeed) {
|
|
5258
5190
|
const expectedSymbols = universe === "crypto" ? [.../* @__PURE__ */ new Set([...tickers, "BTCUSDT", "ETHUSDT"])] : tickers;
|
|
5259
5191
|
session.klineFeed.setSubscriptions(expectedSymbols);
|
|
@@ -5267,7 +5199,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5267
5199
|
})
|
|
5268
5200
|
);
|
|
5269
5201
|
await session.klineFeed.flush();
|
|
5270
|
-
|
|
5202
|
+
import_logger4.logger.info(
|
|
5271
5203
|
import_chalk7.default.gray(
|
|
5272
5204
|
`websocket candles: ready=${expectedSymbols.length - missingSymbols.length}/${expectedSymbols.length} missing=${missingSymbols.length}`
|
|
5273
5205
|
)
|
|
@@ -5279,7 +5211,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5279
5211
|
symbols: missingSymbols,
|
|
5280
5212
|
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5281
5213
|
universe,
|
|
5282
|
-
log: (message) =>
|
|
5214
|
+
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
5283
5215
|
});
|
|
5284
5216
|
await updateBtcReferenceHistory({
|
|
5285
5217
|
marketConnector,
|
|
@@ -5287,7 +5219,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5287
5219
|
interval: interval2,
|
|
5288
5220
|
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5289
5221
|
universe,
|
|
5290
|
-
log: (message) =>
|
|
5222
|
+
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
5291
5223
|
});
|
|
5292
5224
|
} else if (!config2.cacheOnly) {
|
|
5293
5225
|
await updateMarketHistoryWithBtcReferences({
|
|
@@ -5298,7 +5230,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5298
5230
|
symbols: tickers,
|
|
5299
5231
|
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5300
5232
|
universe,
|
|
5301
|
-
log: (message) =>
|
|
5233
|
+
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
5302
5234
|
});
|
|
5303
5235
|
}
|
|
5304
5236
|
await prepareMarketContextForRun({
|
|
@@ -5312,7 +5244,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5312
5244
|
endMs: currentTimestamp,
|
|
5313
5245
|
preloadStartMs: preloadStart,
|
|
5314
5246
|
cacheOnly: config2.cacheOnly,
|
|
5315
|
-
log: (message) =>
|
|
5247
|
+
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
5316
5248
|
});
|
|
5317
5249
|
if (config2.updateOnly) {
|
|
5318
5250
|
return;
|
|
@@ -5368,7 +5300,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5368
5300
|
const primaryEthByTimestamp = new Map(
|
|
5369
5301
|
primaryEthClosedData.map((candle) => [candle.timestamp, candle])
|
|
5370
5302
|
);
|
|
5371
|
-
const runtimeStrategies = await
|
|
5303
|
+
const runtimeStrategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
|
|
5372
5304
|
userName: config2.userName,
|
|
5373
5305
|
projectRoot,
|
|
5374
5306
|
deployment,
|
|
@@ -5379,7 +5311,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5379
5311
|
});
|
|
5380
5312
|
if (!runtimeStrategies.length) {
|
|
5381
5313
|
lifecycle.clear();
|
|
5382
|
-
|
|
5314
|
+
import_logger4.logger.warn(
|
|
5383
5315
|
"No strategy configs found by users:%s:strategies:*:config",
|
|
5384
5316
|
config2.userName
|
|
5385
5317
|
);
|
|
@@ -5389,7 +5321,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5389
5321
|
new Set(
|
|
5390
5322
|
tickers.flatMap(
|
|
5391
5323
|
(symbol) => runtimeStrategies.map(
|
|
5392
|
-
({ strategyName, configId }) => buildSignalsStrategyLifecycleKey({
|
|
5324
|
+
({ strategyName, configId, releaseVersion }) => buildSignalsStrategyLifecycleKey({
|
|
5393
5325
|
connectorName,
|
|
5394
5326
|
universe: sessionUniverse,
|
|
5395
5327
|
accountId,
|
|
@@ -5397,13 +5329,13 @@ var createSignalsRunner = (config2) => {
|
|
|
5397
5329
|
symbol,
|
|
5398
5330
|
interval: interval2,
|
|
5399
5331
|
strategyName,
|
|
5400
|
-
configId
|
|
5332
|
+
configId: releaseVersion ? `v${releaseVersion}` : configId
|
|
5401
5333
|
})
|
|
5402
5334
|
)
|
|
5403
5335
|
)
|
|
5404
5336
|
)
|
|
5405
5337
|
);
|
|
5406
|
-
|
|
5338
|
+
import_logger4.logger.info(
|
|
5407
5339
|
import_chalk7.default.yellow(
|
|
5408
5340
|
`loaded strategies (user=${config2.userName}): ${runtimeStrategies.map((s) => s.strategyName).join(", ")}`
|
|
5409
5341
|
)
|
|
@@ -5426,7 +5358,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5426
5358
|
afterSignalsHookContext
|
|
5427
5359
|
);
|
|
5428
5360
|
if (beforeSignalsResult?.abort === true) {
|
|
5429
|
-
|
|
5361
|
+
import_logger4.logger.info(
|
|
5430
5362
|
"signals aborted before ticker evaluation: %s",
|
|
5431
5363
|
beforeSignalsResult.reason ?? "PROJECT_BEFORE_SIGNALS_ABORTED"
|
|
5432
5364
|
);
|
|
@@ -5440,9 +5372,9 @@ var createSignalsRunner = (config2) => {
|
|
|
5440
5372
|
width: 30
|
|
5441
5373
|
}
|
|
5442
5374
|
);
|
|
5443
|
-
|
|
5375
|
+
import_logger4.logger.info(import_chalk7.default.yellow(`tickers: ${tickers.length}`));
|
|
5444
5376
|
const signalsParallel = resolvePositiveInteger(config2.parallel, 4);
|
|
5445
|
-
|
|
5377
|
+
import_logger4.logger.info(import_chalk7.default.yellow(`signal workers: ${signalsParallel}`));
|
|
5446
5378
|
const evaluateTicker = createSignalsTickerEvaluator({
|
|
5447
5379
|
userName: config2.userName,
|
|
5448
5380
|
makeOrders: config2.makeOrders,
|
|
@@ -5499,7 +5431,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5499
5431
|
config2.userName
|
|
5500
5432
|
);
|
|
5501
5433
|
}
|
|
5502
|
-
|
|
5434
|
+
import_logger4.logger.info(
|
|
5503
5435
|
JSON.stringify(
|
|
5504
5436
|
signals3.map((s) => s.symbol),
|
|
5505
5437
|
null,
|
|
@@ -5512,7 +5444,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5512
5444
|
} catch (error) {
|
|
5513
5445
|
status = "failed";
|
|
5514
5446
|
failureMessage = error?.message || String(error);
|
|
5515
|
-
|
|
5447
|
+
import_logger4.logger.error(
|
|
5516
5448
|
"signals failed: %s",
|
|
5517
5449
|
error?.message || String(error)
|
|
5518
5450
|
);
|
|
@@ -5521,7 +5453,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5521
5453
|
try {
|
|
5522
5454
|
await runtimeSignalEvaluations.flush();
|
|
5523
5455
|
} catch (error) {
|
|
5524
|
-
|
|
5456
|
+
import_logger4.logger.error(
|
|
5525
5457
|
"runtime signal evaluation flush failed: %s",
|
|
5526
5458
|
error?.message || String(error)
|
|
5527
5459
|
);
|
|
@@ -5549,7 +5481,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5549
5481
|
durationMs
|
|
5550
5482
|
});
|
|
5551
5483
|
} catch (error) {
|
|
5552
|
-
|
|
5484
|
+
import_logger4.logger.error(
|
|
5553
5485
|
"afterSignals hook failed: %s",
|
|
5554
5486
|
error?.message || String(error)
|
|
5555
5487
|
);
|
|
@@ -5566,24 +5498,24 @@ var createSignalsRunner = (config2) => {
|
|
|
5566
5498
|
{ userName: config2.userName }
|
|
5567
5499
|
);
|
|
5568
5500
|
} catch (error) {
|
|
5569
|
-
|
|
5501
|
+
import_logger4.logger.error(
|
|
5570
5502
|
"slow signals warning failed: %s",
|
|
5571
5503
|
error?.message || String(error)
|
|
5572
5504
|
);
|
|
5573
5505
|
}
|
|
5574
5506
|
}
|
|
5575
|
-
|
|
5507
|
+
import_logger4.logger.info(
|
|
5576
5508
|
import_chalk7.default.yellow(
|
|
5577
5509
|
`signals ${status} in ${formatDuration2(durationMs)} (found=${signals3.length})`
|
|
5578
5510
|
)
|
|
5579
5511
|
);
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5512
|
+
import_logger4.logger.info("");
|
|
5513
|
+
import_logger4.logger.info("");
|
|
5514
|
+
import_logger4.logger.info("");
|
|
5583
5515
|
}
|
|
5584
5516
|
};
|
|
5585
5517
|
const loadConfiguredSignalsScopes = async (deployment) => {
|
|
5586
|
-
const configuredStrategies = await
|
|
5518
|
+
const configuredStrategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
|
|
5587
5519
|
userName: config2.userName,
|
|
5588
5520
|
projectRoot,
|
|
5589
5521
|
deployment,
|
|
@@ -5611,10 +5543,14 @@ var createSignalsRunner = (config2) => {
|
|
|
5611
5543
|
};
|
|
5612
5544
|
const hasExplicitSignalsScope = () => Boolean(config2.hasExplicitScope);
|
|
5613
5545
|
const signalsConfiguredScopesOnce2 = async () => {
|
|
5614
|
-
if (config2.updateOnly || config2.showTickersList ||
|
|
5546
|
+
if (config2.updateOnly || config2.showTickersList || hasExplicitSignalsScope()) {
|
|
5615
5547
|
return signals2();
|
|
5616
5548
|
}
|
|
5617
|
-
const
|
|
5549
|
+
const configuredDeployment = config2.deploymentId ? await (0, import_runtimeDeployments.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
5550
|
+
if (config2.deploymentId && !configuredDeployment) {
|
|
5551
|
+
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5552
|
+
}
|
|
5553
|
+
const scopes = await loadConfiguredSignalsScopes(configuredDeployment);
|
|
5618
5554
|
if (!scopes.size) return signals2();
|
|
5619
5555
|
for (const scope of scopes.values()) {
|
|
5620
5556
|
const session = await createSignalsSession2(
|
|
@@ -5643,14 +5579,14 @@ var createSignalsRunner = (config2) => {
|
|
|
5643
5579
|
const sessions = /* @__PURE__ */ new Map();
|
|
5644
5580
|
const lastBoundaryByScope = /* @__PURE__ */ new Map();
|
|
5645
5581
|
const stop = (signalName) => {
|
|
5646
|
-
|
|
5582
|
+
import_logger4.logger.info("signals daemon stopping by %s", signalName);
|
|
5647
5583
|
abortController.abort();
|
|
5648
5584
|
};
|
|
5649
5585
|
const stopOnSigint = () => stop("SIGINT");
|
|
5650
5586
|
const stopOnSigterm = () => stop("SIGTERM");
|
|
5651
5587
|
process.once("SIGINT", stopOnSigint);
|
|
5652
5588
|
process.once("SIGTERM", stopOnSigterm);
|
|
5653
|
-
|
|
5589
|
+
import_logger4.logger.info(
|
|
5654
5590
|
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
5655
5591
|
interval
|
|
5656
5592
|
);
|
|
@@ -5691,7 +5627,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5691
5627
|
interval: session.interval,
|
|
5692
5628
|
universe: session.universe
|
|
5693
5629
|
});
|
|
5694
|
-
|
|
5630
|
+
import_logger4.logger.info(
|
|
5695
5631
|
"Bybit websocket candle feed enabled (account=%s, universe=%s, interval=%s)",
|
|
5696
5632
|
session.accountId ?? "default",
|
|
5697
5633
|
session.universe,
|
|
@@ -5713,7 +5649,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5713
5649
|
(sum, session) => sum + session.lifecycle.size(),
|
|
5714
5650
|
0
|
|
5715
5651
|
);
|
|
5716
|
-
|
|
5652
|
+
import_logger4.logger.info(
|
|
5717
5653
|
"signals daemon resources: rss=%sMB heapUsed=%sMB heapTotal=%sMB stateKeys=%s scopes=%s",
|
|
5718
5654
|
(memory.rss / 1024 / 1024).toFixed(1),
|
|
5719
5655
|
(memory.heapUsed / 1024 / 1024).toFixed(1),
|
|
@@ -5723,7 +5659,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5723
5659
|
);
|
|
5724
5660
|
},
|
|
5725
5661
|
onCycleError: (error) => {
|
|
5726
|
-
|
|
5662
|
+
import_logger4.logger.error(
|
|
5727
5663
|
"signals daemon cycle failed: %s",
|
|
5728
5664
|
error?.message || String(error)
|
|
5729
5665
|
);
|
|
@@ -5794,16 +5730,9 @@ import_args.default.option(["A", "account"], "Trading account id");
|
|
|
5794
5730
|
import_args.default.option(["D", "deployment"], "Runtime deployment id");
|
|
5795
5731
|
var flags = import_args.default.parse(process.argv);
|
|
5796
5732
|
var hasExplicitScope = process.argv.some(
|
|
5797
|
-
(argument) => [
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
"-V",
|
|
5801
|
-
"--universe",
|
|
5802
|
-
"-A",
|
|
5803
|
-
"--account",
|
|
5804
|
-
"-D",
|
|
5805
|
-
"--deployment"
|
|
5806
|
-
].some((option) => argument === option || argument.startsWith(`${option}=`))
|
|
5733
|
+
(argument) => ["-f", "--timeframe", "-V", "--universe", "-A", "--account"].some(
|
|
5734
|
+
(option) => argument === option || argument.startsWith(`${option}=`)
|
|
5735
|
+
)
|
|
5807
5736
|
);
|
|
5808
5737
|
var config = {
|
|
5809
5738
|
projectRoot: String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd(),
|