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