@tradejs/node 3.1.29-beta.288 → 3.1.29-beta.290
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/backtest.js +442 -234
- package/dist/backtest.mjs +10 -5
- package/dist/{chunk-F7CLF3PT.mjs → chunk-PB2KHBGH.mjs} +415 -212
- package/dist/cli.js +3 -2
- package/dist/cli.mjs +3 -2
- package/dist/diagnostics.js +416 -213
- package/dist/diagnostics.mjs +1 -1
- package/dist/mcp.d.mts +3 -1
- package/dist/mcp.d.ts +3 -1
- package/dist/mcp.js +455 -230
- package/dist/mcp.mjs +24 -3
- package/dist/registry.js +416 -213
- package/dist/registry.mjs +1 -1
- package/dist/runtimeDashboard.js +418 -215
- package/dist/runtimeDashboard.mjs +1 -1
- package/dist/runtimeStrategies.js +416 -213
- package/dist/runtimeStrategies.mjs +1 -1
- package/dist/strategies.d.mts +32 -22
- package/dist/strategies.d.ts +32 -22
- package/dist/strategies.js +424 -221
- package/dist/strategies.mjs +1 -1
- package/package.json +5 -5
package/dist/runtimeDashboard.js
CHANGED
|
@@ -781,7 +781,7 @@ __export(runtimeDashboard_exports, {
|
|
|
781
781
|
});
|
|
782
782
|
module.exports = __toCommonJS(runtimeDashboard_exports);
|
|
783
783
|
var import_time4 = require("@tradejs/core/time");
|
|
784
|
-
var
|
|
784
|
+
var import_logger15 = require("@tradejs/infra/logger");
|
|
785
785
|
var import_runtimeDeploymentEvents = require("@tradejs/infra/runtimeDeploymentEvents");
|
|
786
786
|
var import_tradingAccounts3 = require("@tradejs/infra/tradingAccounts");
|
|
787
787
|
var import_redis4 = require("@tradejs/infra/redis");
|
|
@@ -2342,13 +2342,210 @@ var assessSignalWithJev = async ({
|
|
|
2342
2342
|
// src/strategyRuntime.ts
|
|
2343
2343
|
var import_constants7 = require("@tradejs/core/constants");
|
|
2344
2344
|
var import_strategies6 = require("@tradejs/core/strategies");
|
|
2345
|
-
var
|
|
2345
|
+
var import_logger14 = require("@tradejs/infra/logger");
|
|
2346
2346
|
|
|
2347
2347
|
// src/strategyHelpers/runtime.ts
|
|
2348
|
-
var
|
|
2348
|
+
var import_logger12 = require("@tradejs/infra/logger");
|
|
2349
2349
|
var import_constants5 = require("@tradejs/core/constants");
|
|
2350
2350
|
var import_ml2 = require("@tradejs/infra/ml");
|
|
2351
2351
|
|
|
2352
|
+
// src/strategy/entrySubmissionValidation.ts
|
|
2353
|
+
var import_logger5 = require("@tradejs/infra/logger");
|
|
2354
|
+
|
|
2355
|
+
// src/strategy/entryExecutionValidation.ts
|
|
2356
|
+
var EntrySubmissionValidationError = class extends Error {
|
|
2357
|
+
constructor() {
|
|
2358
|
+
super(...arguments);
|
|
2359
|
+
this.name = "EntrySubmissionValidationError";
|
|
2360
|
+
}
|
|
2361
|
+
};
|
|
2362
|
+
var resolveEntryExecutionLimits = (config, direction) => {
|
|
2363
|
+
const side = config[direction];
|
|
2364
|
+
const minimum = side && typeof side === "object" && "minRiskRatio" in side ? side.minRiskRatio : void 0;
|
|
2365
|
+
const maximum = config.MAX_LOSS_VALUE;
|
|
2366
|
+
if (minimum == null && maximum == null) return void 0;
|
|
2367
|
+
const minimumNetRiskRatio = minimum == null ? void 0 : Number(minimum);
|
|
2368
|
+
const maxLossValue = maximum == null ? void 0 : Number(maximum);
|
|
2369
|
+
const feeRate = Number(config.RISK_FEE_RATE ?? 0);
|
|
2370
|
+
const slippage = Number(config.RISK_SLIPPAGE_BPS ?? 0);
|
|
2371
|
+
const impact = Number(config.RISK_MARKET_IMPACT_BPS ?? 0);
|
|
2372
|
+
const slippageBps = slippage + impact;
|
|
2373
|
+
if (minimumNetRiskRatio != null && (!Number.isFinite(minimumNetRiskRatio) || minimumNetRiskRatio < 0) || maxLossValue != null && (!Number.isFinite(maxLossValue) || maxLossValue <= 0) || !Number.isFinite(feeRate) || feeRate < 0 || feeRate >= 1 || !Number.isFinite(slippage) || slippage < 0 || !Number.isFinite(impact) || impact < 0 || !Number.isFinite(slippageBps) || slippageBps < 0 || slippageBps >= 1e4)
|
|
2374
|
+
throw new Error("INVALID_ENTRY_EXECUTION_LIMITS");
|
|
2375
|
+
return { minimumNetRiskRatio, maxLossValue, feeRate, slippageBps };
|
|
2376
|
+
};
|
|
2377
|
+
var validateEntryExecution = ({
|
|
2378
|
+
direction,
|
|
2379
|
+
price,
|
|
2380
|
+
qty,
|
|
2381
|
+
stopLossPrice,
|
|
2382
|
+
takeProfitPrice,
|
|
2383
|
+
limits
|
|
2384
|
+
}) => {
|
|
2385
|
+
if (!Number.isFinite(price) || price <= 0 || !Number.isFinite(qty) || qty <= 0 || stopLossPrice == null || !Number.isFinite(stopLossPrice) || stopLossPrice <= 0 || !Number.isFinite(takeProfitPrice) || takeProfitPrice <= 0)
|
|
2386
|
+
throw new EntrySubmissionValidationError(
|
|
2387
|
+
"ENTRY_ECONOMICS_INPUTS_UNAVAILABLE"
|
|
2388
|
+
);
|
|
2389
|
+
const side = direction === "LONG" ? 1 : -1;
|
|
2390
|
+
if (side * (price - stopLossPrice) <= 0 || side * (takeProfitPrice - price) <= 0)
|
|
2391
|
+
throw new EntrySubmissionValidationError(
|
|
2392
|
+
"INVALID_ENTRY_PROTECTION_AT_SUBMISSION"
|
|
2393
|
+
);
|
|
2394
|
+
const slippage = limits.slippageBps / 1e4;
|
|
2395
|
+
const cost = (value, sign) => value * slippage + value * (1 + sign * slippage) * limits.feeRate;
|
|
2396
|
+
const entryCost = cost(price, side);
|
|
2397
|
+
const lossPerUnit = Math.abs(price - stopLossPrice) + entryCost + cost(stopLossPrice, -side);
|
|
2398
|
+
const rewardPerUnit = Math.max(
|
|
2399
|
+
0,
|
|
2400
|
+
Math.abs(takeProfitPrice - price) - entryCost - cost(takeProfitPrice, -side)
|
|
2401
|
+
);
|
|
2402
|
+
const netRiskRatio = rewardPerUnit / lossPerUnit;
|
|
2403
|
+
const plannedLossValue = qty * lossPerUnit;
|
|
2404
|
+
if (!Number.isFinite(netRiskRatio) || !Number.isFinite(plannedLossValue))
|
|
2405
|
+
throw new EntrySubmissionValidationError(
|
|
2406
|
+
"ENTRY_ECONOMICS_INPUTS_UNAVAILABLE"
|
|
2407
|
+
);
|
|
2408
|
+
if (limits.minimumNetRiskRatio != null && netRiskRatio <= limits.minimumNetRiskRatio)
|
|
2409
|
+
throw new EntrySubmissionValidationError(
|
|
2410
|
+
"ENTRY_RR_BELOW_MIN_AT_SUBMISSION"
|
|
2411
|
+
);
|
|
2412
|
+
const riskExceeded = limits.maxLossValue != null && plannedLossValue > limits.maxLossValue * (1 + 1e-9);
|
|
2413
|
+
return { netRiskRatio, plannedLossValue, riskExceeded };
|
|
2414
|
+
};
|
|
2415
|
+
|
|
2416
|
+
// src/strategy/entrySubmissionValidation.ts
|
|
2417
|
+
var MAX_ENTRY_QUOTE_AGE_MS = 5e3;
|
|
2418
|
+
var toFiniteNumberOrNull = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
2419
|
+
var getOrderArrivalSnapshot = async ({
|
|
2420
|
+
connector,
|
|
2421
|
+
symbol,
|
|
2422
|
+
requireTimestamp = false
|
|
2423
|
+
}) => {
|
|
2424
|
+
if (typeof connector.getTopOfBookTicker !== "function") {
|
|
2425
|
+
return {
|
|
2426
|
+
arrivalSnapshotTime: Date.now(),
|
|
2427
|
+
arrivalSource: "unavailable",
|
|
2428
|
+
bid: null,
|
|
2429
|
+
ask: null,
|
|
2430
|
+
arrivalMid: null,
|
|
2431
|
+
spreadBps: null
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
try {
|
|
2435
|
+
const ticker = await connector.getTopOfBookTicker(symbol);
|
|
2436
|
+
const arrivalSnapshotTime = toFiniteNumberOrNull(ticker?.timestamp);
|
|
2437
|
+
const timestampUnavailable = requireTimestamp && arrivalSnapshotTime == null;
|
|
2438
|
+
const bid = timestampUnavailable ? null : toFiniteNumberOrNull(ticker?.bidPrice);
|
|
2439
|
+
const ask = timestampUnavailable ? null : toFiniteNumberOrNull(ticker?.askPrice);
|
|
2440
|
+
const arrivalMid = bid != null && ask != null ? (bid + ask) / 2 : null;
|
|
2441
|
+
const spreadBps = bid != null && ask != null && arrivalMid != null && arrivalMid > 0 ? (ask - bid) / arrivalMid * 1e4 : null;
|
|
2442
|
+
return {
|
|
2443
|
+
arrivalSnapshotTime: arrivalSnapshotTime ?? Date.now(),
|
|
2444
|
+
arrivalSource: "top_of_book",
|
|
2445
|
+
bid,
|
|
2446
|
+
ask,
|
|
2447
|
+
arrivalMid,
|
|
2448
|
+
spreadBps
|
|
2449
|
+
};
|
|
2450
|
+
} catch (error) {
|
|
2451
|
+
import_logger5.logger.warn(
|
|
2452
|
+
"runtime order arrival snapshot failed: %s %s",
|
|
2453
|
+
symbol,
|
|
2454
|
+
error?.message || String(error)
|
|
2455
|
+
);
|
|
2456
|
+
return {
|
|
2457
|
+
arrivalSnapshotTime: Date.now(),
|
|
2458
|
+
arrivalSource: "top_of_book_error",
|
|
2459
|
+
bid: null,
|
|
2460
|
+
ask: null,
|
|
2461
|
+
arrivalMid: null,
|
|
2462
|
+
spreadBps: null
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
};
|
|
2466
|
+
var validateEntryProtectionAtArrival = ({
|
|
2467
|
+
direction,
|
|
2468
|
+
signalPrice,
|
|
2469
|
+
bid,
|
|
2470
|
+
ask,
|
|
2471
|
+
arrivalMid,
|
|
2472
|
+
takeProfits,
|
|
2473
|
+
stopLossPrice
|
|
2474
|
+
}) => {
|
|
2475
|
+
const entryReference = direction === "LONG" ? ask ?? arrivalMid ?? signalPrice : bid ?? arrivalMid ?? signalPrice;
|
|
2476
|
+
const stopReference = direction === "LONG" ? bid ?? arrivalMid ?? signalPrice : ask ?? arrivalMid ?? signalPrice;
|
|
2477
|
+
if (!Number.isFinite(entryReference) || entryReference <= 0 || !Number.isFinite(stopReference) || stopReference <= 0) {
|
|
2478
|
+
throw new Error("INVALID_ENTRY_REFERENCE_AT_ARRIVAL");
|
|
2479
|
+
}
|
|
2480
|
+
for (const takeProfit of takeProfits) {
|
|
2481
|
+
if (!Number.isFinite(takeProfit.price) || takeProfit.price <= 0 || (direction === "LONG" ? takeProfit.price <= entryReference : takeProfit.price >= entryReference)) {
|
|
2482
|
+
throw new Error("TAKE_PROFIT_CROSSED_BEFORE_ENTRY");
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
if (stopLossPrice != null && (!Number.isFinite(stopLossPrice) || stopLossPrice <= 0 || (direction === "LONG" ? stopLossPrice >= stopReference : stopLossPrice <= stopReference))) {
|
|
2486
|
+
throw new Error("STOP_LOSS_CROSSED_BEFORE_ENTRY");
|
|
2487
|
+
}
|
|
2488
|
+
};
|
|
2489
|
+
var createEntrySubmissionValidation = ({
|
|
2490
|
+
connector,
|
|
2491
|
+
symbol,
|
|
2492
|
+
direction,
|
|
2493
|
+
takeProfits,
|
|
2494
|
+
stopLossPrice,
|
|
2495
|
+
limits,
|
|
2496
|
+
onValidated
|
|
2497
|
+
}) => {
|
|
2498
|
+
if (!limits) return void 0;
|
|
2499
|
+
if (!connector.capabilities?.orderSubmissionValidation)
|
|
2500
|
+
throw new EntrySubmissionValidationError(
|
|
2501
|
+
"ENTRY_SUBMISSION_VALIDATION_UNSUPPORTED"
|
|
2502
|
+
);
|
|
2503
|
+
return async ({ qty, executionPrice }) => {
|
|
2504
|
+
const simulated = Reflect.get(connector, "__tradejsTestConnector") === true;
|
|
2505
|
+
const snapshot2 = simulated && executionPrice != null ? {
|
|
2506
|
+
arrivalSnapshotTime: Date.now(),
|
|
2507
|
+
arrivalSource: "simulation",
|
|
2508
|
+
bid: executionPrice,
|
|
2509
|
+
ask: executionPrice,
|
|
2510
|
+
arrivalMid: executionPrice,
|
|
2511
|
+
spreadBps: 0
|
|
2512
|
+
} : await getOrderArrivalSnapshot({
|
|
2513
|
+
connector,
|
|
2514
|
+
symbol,
|
|
2515
|
+
requireTimestamp: true
|
|
2516
|
+
});
|
|
2517
|
+
const age = Date.now() - snapshot2.arrivalSnapshotTime;
|
|
2518
|
+
if (snapshot2.bid == null || snapshot2.ask == null || !Number.isFinite(snapshot2.bid) || !Number.isFinite(snapshot2.ask) || snapshot2.bid <= 0 || snapshot2.ask < snapshot2.bid)
|
|
2519
|
+
throw new EntrySubmissionValidationError(
|
|
2520
|
+
"ENTRY_QUOTE_UNAVAILABLE_AT_SUBMISSION"
|
|
2521
|
+
);
|
|
2522
|
+
if (!Number.isFinite(age) || age < -MAX_ENTRY_QUOTE_AGE_MS || age > MAX_ENTRY_QUOTE_AGE_MS)
|
|
2523
|
+
throw new EntrySubmissionValidationError(
|
|
2524
|
+
"ENTRY_QUOTE_STALE_AT_SUBMISSION"
|
|
2525
|
+
);
|
|
2526
|
+
const price = direction === "LONG" ? snapshot2.ask : snapshot2.bid;
|
|
2527
|
+
validateEntryProtectionAtArrival({
|
|
2528
|
+
direction,
|
|
2529
|
+
signalPrice: price,
|
|
2530
|
+
bid: snapshot2.bid,
|
|
2531
|
+
ask: snapshot2.ask,
|
|
2532
|
+
arrivalMid: snapshot2.arrivalMid,
|
|
2533
|
+
takeProfits,
|
|
2534
|
+
stopLossPrice
|
|
2535
|
+
});
|
|
2536
|
+
const prices = takeProfits.map((tp) => tp.price);
|
|
2537
|
+
const economics2 = validateEntryExecution({
|
|
2538
|
+
direction,
|
|
2539
|
+
price,
|
|
2540
|
+
qty,
|
|
2541
|
+
stopLossPrice,
|
|
2542
|
+
takeProfitPrice: direction === "LONG" ? Math.max(...prices) : Math.min(...prices),
|
|
2543
|
+
limits
|
|
2544
|
+
});
|
|
2545
|
+
onValidated?.(snapshot2, economics2);
|
|
2546
|
+
};
|
|
2547
|
+
};
|
|
2548
|
+
|
|
2352
2549
|
// src/ai.ts
|
|
2353
2550
|
var import_aiLanguages2 = require("@tradejs/core/aiLanguages");
|
|
2354
2551
|
var import_redis2 = require("@tradejs/infra/redis");
|
|
@@ -3881,7 +4078,7 @@ var import_node_crypto = require("crypto");
|
|
|
3881
4078
|
var import_constants3 = require("@tradejs/core/constants");
|
|
3882
4079
|
var import_time3 = require("@tradejs/core/time");
|
|
3883
4080
|
var import_trade = require("@tradejs/core/trade");
|
|
3884
|
-
var
|
|
4081
|
+
var import_logger6 = require("@tradejs/infra/logger");
|
|
3885
4082
|
var import_redis3 = require("@tradejs/infra/redis");
|
|
3886
4083
|
var now = () => Date.now();
|
|
3887
4084
|
var toRandomOrderSuffix = () => (0, import_node_crypto.randomUUID)().replace(/-/g, "").slice(0, 12).toLowerCase();
|
|
@@ -3940,7 +4137,7 @@ var recordRuntimeTradeOpen = async (params) => {
|
|
|
3940
4137
|
)
|
|
3941
4138
|
]);
|
|
3942
4139
|
} catch (error) {
|
|
3943
|
-
|
|
4140
|
+
import_logger6.logger.error(
|
|
3944
4141
|
"runtime trade open journal failed: %s %s",
|
|
3945
4142
|
record.symbol,
|
|
3946
4143
|
error?.message || String(error)
|
|
@@ -4008,7 +4205,7 @@ var recordRuntimeTradeIncrease = async (params) => {
|
|
|
4008
4205
|
)
|
|
4009
4206
|
]);
|
|
4010
4207
|
} catch (error) {
|
|
4011
|
-
|
|
4208
|
+
import_logger6.logger.error(
|
|
4012
4209
|
"runtime trade increase journal failed: %s %s",
|
|
4013
4210
|
symbol,
|
|
4014
4211
|
error?.message || String(error)
|
|
@@ -4115,7 +4312,7 @@ var markRuntimeTradeClosed = async (params) => {
|
|
|
4115
4312
|
)
|
|
4116
4313
|
]);
|
|
4117
4314
|
} catch (error) {
|
|
4118
|
-
|
|
4315
|
+
import_logger6.logger.error(
|
|
4119
4316
|
"runtime trade close journal failed: %s %s",
|
|
4120
4317
|
symbol,
|
|
4121
4318
|
error?.message || String(error)
|
|
@@ -4125,11 +4322,11 @@ var markRuntimeTradeClosed = async (params) => {
|
|
|
4125
4322
|
};
|
|
4126
4323
|
|
|
4127
4324
|
// src/strategyHelpers/marketContextStages.ts
|
|
4128
|
-
var
|
|
4325
|
+
var import_logger11 = require("@tradejs/infra/logger");
|
|
4129
4326
|
|
|
4130
4327
|
// src/strategyHelpers/binanceMarketContext.ts
|
|
4131
4328
|
var import_marketContext = require("@tradejs/infra/timescale/marketContext");
|
|
4132
|
-
var
|
|
4329
|
+
var import_logger7 = require("@tradejs/infra/logger");
|
|
4133
4330
|
var import_strategies = require("@tradejs/core/strategies");
|
|
4134
4331
|
|
|
4135
4332
|
// src/binanceBreadthUniverses.ts
|
|
@@ -4493,7 +4690,7 @@ var parseEnabledFlag = (value, env) => {
|
|
|
4493
4690
|
if (normalized === "live") return env !== "BACKTEST";
|
|
4494
4691
|
return false;
|
|
4495
4692
|
};
|
|
4496
|
-
var
|
|
4693
|
+
var toFiniteNumberOrNull2 = (value) => {
|
|
4497
4694
|
const numeric = typeof value === "number" ? value : Number(value);
|
|
4498
4695
|
return Number.isFinite(numeric) ? numeric : null;
|
|
4499
4696
|
};
|
|
@@ -4618,14 +4815,14 @@ var toTradeFlowContext = (row, interval) => row ? {
|
|
|
4618
4815
|
asOfTs: row.ts.getTime(),
|
|
4619
4816
|
ageMs: row.ageMs,
|
|
4620
4817
|
stale: row.stale,
|
|
4621
|
-
trades:
|
|
4622
|
-
buyPressurePct:
|
|
4623
|
-
buyBaseVolume:
|
|
4624
|
-
sellBaseVolume:
|
|
4625
|
-
buyQuoteVolume:
|
|
4626
|
-
sellQuoteVolume:
|
|
4627
|
-
netBaseDelta:
|
|
4628
|
-
netQuoteDelta:
|
|
4818
|
+
trades: toFiniteNumberOrNull2(row.trades),
|
|
4819
|
+
buyPressurePct: toFiniteNumberOrNull2(row.buyPressurePct),
|
|
4820
|
+
buyBaseVolume: toFiniteNumberOrNull2(row.buyBaseVolume),
|
|
4821
|
+
sellBaseVolume: toFiniteNumberOrNull2(row.sellBaseVolume),
|
|
4822
|
+
buyQuoteVolume: toFiniteNumberOrNull2(row.buyQuoteVolume),
|
|
4823
|
+
sellQuoteVolume: toFiniteNumberOrNull2(row.sellQuoteVolume),
|
|
4824
|
+
netBaseDelta: toFiniteNumberOrNull2(row.netBaseDelta),
|
|
4825
|
+
netQuoteDelta: toFiniteNumberOrNull2(row.netQuoteDelta)
|
|
4629
4826
|
} : null;
|
|
4630
4827
|
var getCachedReferenceRows = ({
|
|
4631
4828
|
referenceSymbols,
|
|
@@ -4714,16 +4911,16 @@ var toMarketBreadthContext = (breadth, interval) => ({
|
|
|
4714
4911
|
asOfTs: breadth.ts.getTime(),
|
|
4715
4912
|
ageMs: breadth.ageMs,
|
|
4716
4913
|
stale: breadth.stale,
|
|
4717
|
-
symbolsCount:
|
|
4718
|
-
advancers:
|
|
4719
|
-
decliners:
|
|
4720
|
-
unchanged:
|
|
4721
|
-
advanceDeclineRatio:
|
|
4722
|
-
pctAboveMa20:
|
|
4723
|
-
pctAboveMa50:
|
|
4724
|
-
equalWeightedReturn:
|
|
4725
|
-
volumeWeightedReturn:
|
|
4726
|
-
dispersion:
|
|
4914
|
+
symbolsCount: toFiniteNumberOrNull2(breadth.symbolsCount),
|
|
4915
|
+
advancers: toFiniteNumberOrNull2(breadth.advancers),
|
|
4916
|
+
decliners: toFiniteNumberOrNull2(breadth.decliners),
|
|
4917
|
+
unchanged: toFiniteNumberOrNull2(breadth.unchanged),
|
|
4918
|
+
advanceDeclineRatio: toFiniteNumberOrNull2(breadth.advanceDeclineRatio),
|
|
4919
|
+
pctAboveMa20: toFiniteNumberOrNull2(breadth.pctAboveMa20),
|
|
4920
|
+
pctAboveMa50: toFiniteNumberOrNull2(breadth.pctAboveMa50),
|
|
4921
|
+
equalWeightedReturn: toFiniteNumberOrNull2(breadth.equalWeightedReturn),
|
|
4922
|
+
volumeWeightedReturn: toFiniteNumberOrNull2(breadth.volumeWeightedReturn),
|
|
4923
|
+
dispersion: toFiniteNumberOrNull2(breadth.dispersion)
|
|
4727
4924
|
});
|
|
4728
4925
|
var enrichSignalWithBinanceMarketContext = async (params) => {
|
|
4729
4926
|
const {
|
|
@@ -4824,46 +5021,46 @@ var enrichSignalWithBinanceMarketContext = async (params) => {
|
|
|
4824
5021
|
asOfTs: primaryBreadth.ts.getTime(),
|
|
4825
5022
|
ageMs: primaryBreadth.ageMs,
|
|
4826
5023
|
stale: primaryBreadth.stale,
|
|
4827
|
-
btcReturn1h:
|
|
5024
|
+
btcReturn1h: toFiniteNumberOrNull2(
|
|
4828
5025
|
primaryBreadth.btcReturn1h
|
|
4829
5026
|
),
|
|
4830
|
-
btcReturn4h:
|
|
5027
|
+
btcReturn4h: toFiniteNumberOrNull2(
|
|
4831
5028
|
primaryBreadth.btcReturn4h
|
|
4832
5029
|
),
|
|
4833
|
-
btcReturn24h:
|
|
5030
|
+
btcReturn24h: toFiniteNumberOrNull2(
|
|
4834
5031
|
primaryBreadth.btcReturn24h
|
|
4835
5032
|
),
|
|
4836
|
-
altBasketReturn1h:
|
|
5033
|
+
altBasketReturn1h: toFiniteNumberOrNull2(
|
|
4837
5034
|
primaryBreadth.altBasketReturn1h
|
|
4838
5035
|
),
|
|
4839
|
-
altBasketReturn4h:
|
|
5036
|
+
altBasketReturn4h: toFiniteNumberOrNull2(
|
|
4840
5037
|
primaryBreadth.altBasketReturn4h
|
|
4841
5038
|
),
|
|
4842
|
-
altBasketReturn24h:
|
|
5039
|
+
altBasketReturn24h: toFiniteNumberOrNull2(
|
|
4843
5040
|
primaryBreadth.altBasketReturn24h
|
|
4844
5041
|
),
|
|
4845
|
-
btcVsAltReturn1h:
|
|
5042
|
+
btcVsAltReturn1h: toFiniteNumberOrNull2(
|
|
4846
5043
|
primaryBreadth.btcVsAltReturn1h
|
|
4847
5044
|
),
|
|
4848
|
-
btcVsAltReturn4h:
|
|
5045
|
+
btcVsAltReturn4h: toFiniteNumberOrNull2(
|
|
4849
5046
|
primaryBreadth.btcVsAltReturn4h
|
|
4850
5047
|
),
|
|
4851
|
-
btcVsAltReturn24h:
|
|
5048
|
+
btcVsAltReturn24h: toFiniteNumberOrNull2(
|
|
4852
5049
|
primaryBreadth.btcVsAltReturn24h
|
|
4853
5050
|
),
|
|
4854
|
-
btcTurnoverShare1h:
|
|
5051
|
+
btcTurnoverShare1h: toFiniteNumberOrNull2(
|
|
4855
5052
|
primaryBreadth.btcTurnoverShare1h
|
|
4856
5053
|
),
|
|
4857
|
-
btcTurnoverShare24h:
|
|
5054
|
+
btcTurnoverShare24h: toFiniteNumberOrNull2(
|
|
4858
5055
|
primaryBreadth.btcTurnoverShare24h
|
|
4859
5056
|
),
|
|
4860
|
-
btcTurnoverShareChange24h:
|
|
5057
|
+
btcTurnoverShareChange24h: toFiniteNumberOrNull2(
|
|
4861
5058
|
primaryBreadth.btcTurnoverShareChange24h
|
|
4862
5059
|
),
|
|
4863
|
-
altVolToBtcVol24h:
|
|
5060
|
+
altVolToBtcVol24h: toFiniteNumberOrNull2(
|
|
4864
5061
|
primaryBreadth.altVolToBtcVol24h
|
|
4865
5062
|
),
|
|
4866
|
-
altDispersion24h:
|
|
5063
|
+
altDispersion24h: toFiniteNumberOrNull2(
|
|
4867
5064
|
primaryBreadth.altDispersion24h
|
|
4868
5065
|
),
|
|
4869
5066
|
regime: primaryBreadth.btcAltRegime ?? "unknown"
|
|
@@ -4880,7 +5077,7 @@ var enrichSignalWithBinanceMarketContext = async (params) => {
|
|
|
4880
5077
|
throw error;
|
|
4881
5078
|
}
|
|
4882
5079
|
binanceMarketContextUnavailable = true;
|
|
4883
|
-
|
|
5080
|
+
import_logger7.logger.warn(
|
|
4884
5081
|
"Binance market context disabled after Timescale read failure: %s",
|
|
4885
5082
|
String(error)
|
|
4886
5083
|
);
|
|
@@ -4890,7 +5087,7 @@ var enrichSignalWithBinanceMarketContext = async (params) => {
|
|
|
4890
5087
|
|
|
4891
5088
|
// src/strategyHelpers/coinMarketCapContext.ts
|
|
4892
5089
|
var import_strategies2 = require("@tradejs/core/strategies");
|
|
4893
|
-
var
|
|
5090
|
+
var import_logger8 = require("@tradejs/infra/logger");
|
|
4894
5091
|
var import_marketContext2 = require("@tradejs/infra/timescale/marketContext");
|
|
4895
5092
|
var DEFAULT_MAX_AGE_MS = 48 * 60 * 6e4;
|
|
4896
5093
|
var SOURCE_GLOBAL_DAILY = "coinmarketcap_global";
|
|
@@ -4928,7 +5125,7 @@ var asInt = (value, fallback) => {
|
|
|
4928
5125
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
4929
5126
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
4930
5127
|
};
|
|
4931
|
-
var
|
|
5128
|
+
var toFiniteNumberOrNull3 = (value) => {
|
|
4932
5129
|
const numeric = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;
|
|
4933
5130
|
return Number.isFinite(numeric) ? numeric : null;
|
|
4934
5131
|
};
|
|
@@ -5162,12 +5359,12 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5162
5359
|
const ethRow = references.get("ETHUSDT") ?? null;
|
|
5163
5360
|
const previousBtcRow = previousReferences.get("BTCUSDT") ?? null;
|
|
5164
5361
|
const previousEthRow = previousReferences.get("ETHUSDT") ?? null;
|
|
5165
|
-
const btcMarketCapUsd =
|
|
5166
|
-
const ethMarketCapUsd =
|
|
5167
|
-
const previousBtcMarketCapUsd =
|
|
5362
|
+
const btcMarketCapUsd = toFiniteNumberOrNull3(btcRow?.marketCapUsd);
|
|
5363
|
+
const ethMarketCapUsd = toFiniteNumberOrNull3(ethRow?.marketCapUsd);
|
|
5364
|
+
const previousBtcMarketCapUsd = toFiniteNumberOrNull3(
|
|
5168
5365
|
previousBtcRow?.marketCapUsd
|
|
5169
5366
|
);
|
|
5170
|
-
const previousEthMarketCapUsd =
|
|
5367
|
+
const previousEthMarketCapUsd = toFiniteNumberOrNull3(
|
|
5171
5368
|
previousEthRow?.marketCapUsd
|
|
5172
5369
|
);
|
|
5173
5370
|
const ethBtcMarketCapRatio = safeDivide(ethMarketCapUsd, btcMarketCapUsd);
|
|
@@ -5176,16 +5373,16 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5176
5373
|
previousBtcMarketCapUsd
|
|
5177
5374
|
);
|
|
5178
5375
|
const ethBtcMarketCapRatioChange24hPct = ethBtcMarketCapRatio != null && previousEthBtcMarketCapRatio != null && previousEthBtcMarketCapRatio > 0 ? (ethBtcMarketCapRatio - previousEthBtcMarketCapRatio) / previousEthBtcMarketCapRatio : null;
|
|
5179
|
-
const btcVolumeUsd =
|
|
5180
|
-
const ethVolumeUsd =
|
|
5376
|
+
const btcVolumeUsd = toFiniteNumberOrNull3(btcRow?.volumeUsd);
|
|
5377
|
+
const ethVolumeUsd = toFiniteNumberOrNull3(ethRow?.volumeUsd);
|
|
5181
5378
|
const referenceStale = btcRow?.stale === true || ethRow?.stale === true || !btcRow || !ethRow;
|
|
5182
|
-
const btcDominanceChange24hPct =
|
|
5379
|
+
const btcDominanceChange24hPct = toFiniteNumberOrNull3(
|
|
5183
5380
|
globalRow?.btcDominanceChange24hPct
|
|
5184
5381
|
);
|
|
5185
|
-
const altMarketCapChange24hPct =
|
|
5382
|
+
const altMarketCapChange24hPct = toFiniteNumberOrNull3(
|
|
5186
5383
|
globalRow?.altMarketCapChange24hPct
|
|
5187
5384
|
);
|
|
5188
|
-
const altVolumeChange24hPct =
|
|
5385
|
+
const altVolumeChange24hPct = toFiniteNumberOrNull3(
|
|
5189
5386
|
globalRow?.altVolumeChange24hPct
|
|
5190
5387
|
);
|
|
5191
5388
|
const altLiquidityRegime = globalRow ? toAltLiquidityRegime({
|
|
@@ -5196,19 +5393,19 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5196
5393
|
}) : "unknown";
|
|
5197
5394
|
const exchangeLiquidityRegime = exchangeLiquidityRow ? toExchangeLiquidityRegime({
|
|
5198
5395
|
stale: exchangeLiquidityRow.stale,
|
|
5199
|
-
totalVolumeChange24hPct:
|
|
5396
|
+
totalVolumeChange24hPct: toFiniteNumberOrNull3(
|
|
5200
5397
|
exchangeLiquidityRow.totalVolumeChange24hPct
|
|
5201
5398
|
),
|
|
5202
5399
|
fallback: exchangeLiquidityRow.liquidityRegime ?? "unknown"
|
|
5203
5400
|
}) : "unknown";
|
|
5204
5401
|
const cmc100Row = indexRows.get("cmc100") ?? null;
|
|
5205
5402
|
const cmc20Row = indexRows.get("cmc20") ?? null;
|
|
5206
|
-
const cmc100Value =
|
|
5207
|
-
const cmc20Value =
|
|
5208
|
-
const cmc100Change24hPct =
|
|
5403
|
+
const cmc100Value = toFiniteNumberOrNull3(cmc100Row?.value);
|
|
5404
|
+
const cmc20Value = toFiniteNumberOrNull3(cmc20Row?.value);
|
|
5405
|
+
const cmc100Change24hPct = toFiniteNumberOrNull3(
|
|
5209
5406
|
cmc100Row?.valueChange24hPct
|
|
5210
5407
|
);
|
|
5211
|
-
const cmc20Change24hPct =
|
|
5408
|
+
const cmc20Change24hPct = toFiniteNumberOrNull3(cmc20Row?.valueChange24hPct);
|
|
5212
5409
|
const cmc20ToCmc100Ratio = safeDivide(cmc20Value, cmc100Value);
|
|
5213
5410
|
const cmc20ToCmc100RatioChange24hPct = cmc20Change24hPct != null && cmc100Change24hPct != null ? (1 + cmc20Change24hPct) / (1 + cmc100Change24hPct) - 1 : null;
|
|
5214
5411
|
const indexStale = cmc100Row?.stale === true || cmc20Row?.stale === true || !cmc100Row || !cmc20Row;
|
|
@@ -5232,41 +5429,41 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5232
5429
|
asOfTs: globalRow.ts.getTime(),
|
|
5233
5430
|
ageMs: globalRow.ageMs,
|
|
5234
5431
|
stale: globalRow.stale,
|
|
5235
|
-
totalMarketCapUsd:
|
|
5432
|
+
totalMarketCapUsd: toFiniteNumberOrNull3(
|
|
5236
5433
|
globalRow.totalMarketCapUsd
|
|
5237
5434
|
),
|
|
5238
|
-
totalVolumeUsd:
|
|
5435
|
+
totalVolumeUsd: toFiniteNumberOrNull3(
|
|
5239
5436
|
globalRow.totalVolumeUsd
|
|
5240
5437
|
),
|
|
5241
|
-
totalVolumeReportedUsd:
|
|
5438
|
+
totalVolumeReportedUsd: toFiniteNumberOrNull3(
|
|
5242
5439
|
globalRow.totalVolumeReportedUsd
|
|
5243
5440
|
),
|
|
5244
|
-
altMarketCapUsd:
|
|
5441
|
+
altMarketCapUsd: toFiniteNumberOrNull3(
|
|
5245
5442
|
globalRow.altMarketCapUsd
|
|
5246
5443
|
),
|
|
5247
|
-
altVolumeUsd:
|
|
5248
|
-
altVolumeReportedUsd:
|
|
5444
|
+
altVolumeUsd: toFiniteNumberOrNull3(globalRow.altVolumeUsd),
|
|
5445
|
+
altVolumeReportedUsd: toFiniteNumberOrNull3(
|
|
5249
5446
|
globalRow.altVolumeReportedUsd
|
|
5250
5447
|
),
|
|
5251
|
-
btcDominancePct:
|
|
5448
|
+
btcDominancePct: toFiniteNumberOrNull3(
|
|
5252
5449
|
globalRow.btcDominancePct
|
|
5253
5450
|
),
|
|
5254
|
-
ethDominancePct:
|
|
5451
|
+
ethDominancePct: toFiniteNumberOrNull3(
|
|
5255
5452
|
globalRow.ethDominancePct
|
|
5256
5453
|
),
|
|
5257
5454
|
btcDominanceChange24hPct,
|
|
5258
|
-
ethDominanceChange24hPct:
|
|
5455
|
+
ethDominanceChange24hPct: toFiniteNumberOrNull3(
|
|
5259
5456
|
globalRow.ethDominanceChange24hPct
|
|
5260
5457
|
),
|
|
5261
5458
|
altMarketCapChange24hPct,
|
|
5262
5459
|
altVolumeChange24hPct,
|
|
5263
|
-
activeCryptocurrencies:
|
|
5460
|
+
activeCryptocurrencies: toFiniteNumberOrNull3(
|
|
5264
5461
|
globalRow.activeCryptocurrencies
|
|
5265
5462
|
),
|
|
5266
|
-
activeExchanges:
|
|
5463
|
+
activeExchanges: toFiniteNumberOrNull3(
|
|
5267
5464
|
globalRow.activeExchanges
|
|
5268
5465
|
),
|
|
5269
|
-
activeMarketPairs:
|
|
5466
|
+
activeMarketPairs: toFiniteNumberOrNull3(
|
|
5270
5467
|
globalRow.activeMarketPairs
|
|
5271
5468
|
),
|
|
5272
5469
|
altLiquidityRegime
|
|
@@ -5311,22 +5508,22 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5311
5508
|
asOfTs: exchangeLiquidityRow.ts.getTime(),
|
|
5312
5509
|
ageMs: exchangeLiquidityRow.ageMs,
|
|
5313
5510
|
stale: exchangeLiquidityRow.stale,
|
|
5314
|
-
exchangesCount:
|
|
5511
|
+
exchangesCount: toFiniteNumberOrNull3(
|
|
5315
5512
|
exchangeLiquidityRow.exchangesCount
|
|
5316
5513
|
),
|
|
5317
|
-
totalVolumeUsd:
|
|
5514
|
+
totalVolumeUsd: toFiniteNumberOrNull3(
|
|
5318
5515
|
exchangeLiquidityRow.totalVolumeUsd
|
|
5319
5516
|
),
|
|
5320
|
-
totalVolumeChange24hPct:
|
|
5517
|
+
totalVolumeChange24hPct: toFiniteNumberOrNull3(
|
|
5321
5518
|
exchangeLiquidityRow.totalVolumeChange24hPct
|
|
5322
5519
|
),
|
|
5323
|
-
binanceVolumeUsd:
|
|
5520
|
+
binanceVolumeUsd: toFiniteNumberOrNull3(
|
|
5324
5521
|
exchangeLiquidityRow.binanceVolumeUsd
|
|
5325
5522
|
),
|
|
5326
|
-
binanceVolumeShare:
|
|
5523
|
+
binanceVolumeShare: toFiniteNumberOrNull3(
|
|
5327
5524
|
exchangeLiquidityRow.binanceVolumeShare
|
|
5328
5525
|
),
|
|
5329
|
-
topExchangeVolumeShare:
|
|
5526
|
+
topExchangeVolumeShare: toFiniteNumberOrNull3(
|
|
5330
5527
|
exchangeLiquidityRow.topExchangeVolumeShare
|
|
5331
5528
|
),
|
|
5332
5529
|
liquidityRegime: exchangeLiquidityRegime
|
|
@@ -5339,11 +5536,11 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5339
5536
|
asOfTs: fearGreedRow.ts.getTime(),
|
|
5340
5537
|
ageMs: fearGreedRow.ageMs,
|
|
5341
5538
|
stale: fearGreedRow.stale,
|
|
5342
|
-
value:
|
|
5343
|
-
valueChange24h:
|
|
5539
|
+
value: toFiniteNumberOrNull3(fearGreedRow.value),
|
|
5540
|
+
valueChange24h: toFiniteNumberOrNull3(
|
|
5344
5541
|
fearGreedRow.valueChange24h
|
|
5345
5542
|
),
|
|
5346
|
-
valueChange7d:
|
|
5543
|
+
valueChange7d: toFiniteNumberOrNull3(
|
|
5347
5544
|
fearGreedRow.valueChange7d
|
|
5348
5545
|
),
|
|
5349
5546
|
classification: fearGreedRow.classification ?? "Unknown",
|
|
@@ -5363,13 +5560,13 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5363
5560
|
cmc100Value,
|
|
5364
5561
|
cmc100Change24hPct,
|
|
5365
5562
|
cmc100TopConstituentSymbol: cmc100Row?.topConstituentSymbol ?? null,
|
|
5366
|
-
cmc100TopConstituentWeightPct:
|
|
5563
|
+
cmc100TopConstituentWeightPct: toFiniteNumberOrNull3(
|
|
5367
5564
|
cmc100Row?.topConstituentWeightPct
|
|
5368
5565
|
),
|
|
5369
5566
|
cmc20Value,
|
|
5370
5567
|
cmc20Change24hPct,
|
|
5371
5568
|
cmc20TopConstituentSymbol: cmc20Row?.topConstituentSymbol ?? null,
|
|
5372
|
-
cmc20TopConstituentWeightPct:
|
|
5569
|
+
cmc20TopConstituentWeightPct: toFiniteNumberOrNull3(
|
|
5373
5570
|
cmc20Row?.topConstituentWeightPct
|
|
5374
5571
|
),
|
|
5375
5572
|
cmc20ToCmc100Ratio,
|
|
@@ -5387,7 +5584,7 @@ var enrichSignalWithCoinMarketCapContext = async (params) => {
|
|
|
5387
5584
|
throw error;
|
|
5388
5585
|
}
|
|
5389
5586
|
coinMarketCapContextUnavailable = true;
|
|
5390
|
-
|
|
5587
|
+
import_logger8.logger.warn(
|
|
5391
5588
|
"CoinMarketCap context disabled after Timescale read failure: %s",
|
|
5392
5589
|
String(error)
|
|
5393
5590
|
);
|
|
@@ -5401,7 +5598,7 @@ var import_data3 = require("@tradejs/core/data");
|
|
|
5401
5598
|
var import_strategies3 = require("@tradejs/core/strategies");
|
|
5402
5599
|
var import_constants4 = require("@tradejs/core/constants");
|
|
5403
5600
|
var import_derivatives = require("@tradejs/infra/timescale/derivatives");
|
|
5404
|
-
var
|
|
5601
|
+
var import_logger9 = require("@tradejs/infra/logger");
|
|
5405
5602
|
var STORED_INTERVALS = ["15m", "1h"];
|
|
5406
5603
|
var CONTEXT_INTERVALS = ["15m", "1h"];
|
|
5407
5604
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
@@ -5456,7 +5653,7 @@ var resolvePrimaryReferenceSymbol2 = () => PRIMARY_DERIVATIVES_REFERENCE_SYMBOL;
|
|
|
5456
5653
|
var resolveSecondaryReferenceSymbol = () => SECONDARY_DERIVATIVES_REFERENCE_SYMBOL;
|
|
5457
5654
|
var getPrimaryIntervalContext = (context) => context?.intervals["15m"] ?? context?.intervals["1h"] ?? null;
|
|
5458
5655
|
var hasDerivativesSymbolData = (context) => Object.keys(context.intervals).length > 0 && !context.summary.riskFlags.includes("missing_derivatives");
|
|
5459
|
-
var
|
|
5656
|
+
var toFiniteNumberOrNull4 = (value) => {
|
|
5460
5657
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
5461
5658
|
if (typeof value === "string" && value.trim()) {
|
|
5462
5659
|
const parsed = Number(value);
|
|
@@ -5470,8 +5667,8 @@ var roundNullable = (value, digits = 4) => {
|
|
|
5470
5667
|
return Math.round(value * multiplier) / multiplier;
|
|
5471
5668
|
};
|
|
5472
5669
|
var deltaNullable = (targetValue, referenceValue) => {
|
|
5473
|
-
const target =
|
|
5474
|
-
const reference =
|
|
5670
|
+
const target = toFiniteNumberOrNull4(targetValue);
|
|
5671
|
+
const reference = toFiniteNumberOrNull4(referenceValue);
|
|
5475
5672
|
return target == null || reference == null ? null : roundNullable(target - reference);
|
|
5476
5673
|
};
|
|
5477
5674
|
var buildTargetDerivedContext = (params) => {
|
|
@@ -5633,7 +5830,7 @@ var enrichSignalWithDerivativesContext = async (params) => {
|
|
|
5633
5830
|
throw error;
|
|
5634
5831
|
}
|
|
5635
5832
|
derivativesContextUnavailable = true;
|
|
5636
|
-
|
|
5833
|
+
import_logger9.logger.warn(
|
|
5637
5834
|
"Derivatives context disabled after Timescale read failure: %s",
|
|
5638
5835
|
String(error)
|
|
5639
5836
|
);
|
|
@@ -5645,7 +5842,7 @@ var enrichSignalWithDerivativesContext = async (params) => {
|
|
|
5645
5842
|
var import_data4 = require("@tradejs/core/data");
|
|
5646
5843
|
var import_strategies4 = require("@tradejs/core/strategies");
|
|
5647
5844
|
var import_hyperliquidWhales2 = require("@tradejs/infra/timescale/hyperliquidWhales");
|
|
5648
|
-
var
|
|
5845
|
+
var import_logger10 = require("@tradejs/infra/logger");
|
|
5649
5846
|
|
|
5650
5847
|
// src/hyperliquidWhaleUniverse.ts
|
|
5651
5848
|
var import_node_crypto3 = require("crypto");
|
|
@@ -6165,7 +6362,7 @@ var loadHyperliquidWhaleFlowContext = async (params) => {
|
|
|
6165
6362
|
throw error;
|
|
6166
6363
|
}
|
|
6167
6364
|
hyperliquidWhaleContextUnavailable = true;
|
|
6168
|
-
|
|
6365
|
+
import_logger10.logger.warn(
|
|
6169
6366
|
"Hyperliquid whale context disabled after Timescale read failure: %s",
|
|
6170
6367
|
String(error)
|
|
6171
6368
|
);
|
|
@@ -6248,7 +6445,7 @@ var runMarketContextStage = async ({
|
|
|
6248
6445
|
elapsedMs: Date.now() - startedAt
|
|
6249
6446
|
};
|
|
6250
6447
|
if (status === "timed_out") {
|
|
6251
|
-
|
|
6448
|
+
import_logger11.logger.warn(
|
|
6252
6449
|
"Market context stage timed out: %s after %sms",
|
|
6253
6450
|
stage,
|
|
6254
6451
|
result.elapsedMs
|
|
@@ -6438,79 +6635,10 @@ var enrichSignalWithAi = async ({
|
|
|
6438
6635
|
signal.aiAnalysis = analysis;
|
|
6439
6636
|
return resolveAiQuality(analysis, direction);
|
|
6440
6637
|
} catch (err) {
|
|
6441
|
-
|
|
6638
|
+
import_logger12.logger.error("AI analysis error: %s %s", symbol, formatAiError(err));
|
|
6442
6639
|
}
|
|
6443
6640
|
return void 0;
|
|
6444
6641
|
};
|
|
6445
|
-
var toFiniteNumberOrNull4 = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
6446
|
-
var getOrderArrivalSnapshot = async ({
|
|
6447
|
-
connector,
|
|
6448
|
-
symbol
|
|
6449
|
-
}) => {
|
|
6450
|
-
if (typeof connector.getTopOfBookTicker !== "function") {
|
|
6451
|
-
return {
|
|
6452
|
-
arrivalSnapshotTime: Date.now(),
|
|
6453
|
-
arrivalSource: "unavailable",
|
|
6454
|
-
bid: null,
|
|
6455
|
-
ask: null,
|
|
6456
|
-
arrivalMid: null,
|
|
6457
|
-
spreadBps: null
|
|
6458
|
-
};
|
|
6459
|
-
}
|
|
6460
|
-
try {
|
|
6461
|
-
const ticker = await connector.getTopOfBookTicker(symbol);
|
|
6462
|
-
const arrivalSnapshotTime = toFiniteNumberOrNull4(ticker?.timestamp);
|
|
6463
|
-
const bid = toFiniteNumberOrNull4(ticker?.bidPrice);
|
|
6464
|
-
const ask = toFiniteNumberOrNull4(ticker?.askPrice);
|
|
6465
|
-
const arrivalMid = bid != null && ask != null ? (bid + ask) / 2 : null;
|
|
6466
|
-
const spreadBps = bid != null && ask != null && arrivalMid != null && arrivalMid > 0 ? (ask - bid) / arrivalMid * 1e4 : null;
|
|
6467
|
-
return {
|
|
6468
|
-
arrivalSnapshotTime: arrivalSnapshotTime ?? Date.now(),
|
|
6469
|
-
arrivalSource: "top_of_book",
|
|
6470
|
-
bid,
|
|
6471
|
-
ask,
|
|
6472
|
-
arrivalMid,
|
|
6473
|
-
spreadBps
|
|
6474
|
-
};
|
|
6475
|
-
} catch (error) {
|
|
6476
|
-
import_logger11.logger.warn(
|
|
6477
|
-
"runtime order arrival snapshot failed: %s %s",
|
|
6478
|
-
symbol,
|
|
6479
|
-
error?.message || String(error)
|
|
6480
|
-
);
|
|
6481
|
-
return {
|
|
6482
|
-
arrivalSnapshotTime: Date.now(),
|
|
6483
|
-
arrivalSource: "top_of_book_error",
|
|
6484
|
-
bid: null,
|
|
6485
|
-
ask: null,
|
|
6486
|
-
arrivalMid: null,
|
|
6487
|
-
spreadBps: null
|
|
6488
|
-
};
|
|
6489
|
-
}
|
|
6490
|
-
};
|
|
6491
|
-
var validateEntryProtectionAtArrival = ({
|
|
6492
|
-
direction,
|
|
6493
|
-
signalPrice,
|
|
6494
|
-
bid,
|
|
6495
|
-
ask,
|
|
6496
|
-
arrivalMid,
|
|
6497
|
-
takeProfits,
|
|
6498
|
-
stopLossPrice
|
|
6499
|
-
}) => {
|
|
6500
|
-
const entryReference = direction === "LONG" ? ask ?? arrivalMid ?? signalPrice : bid ?? arrivalMid ?? signalPrice;
|
|
6501
|
-
const stopReference = direction === "LONG" ? bid ?? arrivalMid ?? signalPrice : ask ?? arrivalMid ?? signalPrice;
|
|
6502
|
-
if (!Number.isFinite(entryReference) || entryReference <= 0 || !Number.isFinite(stopReference) || stopReference <= 0) {
|
|
6503
|
-
throw new Error("INVALID_ENTRY_REFERENCE_AT_ARRIVAL");
|
|
6504
|
-
}
|
|
6505
|
-
for (const takeProfit of takeProfits) {
|
|
6506
|
-
if (!Number.isFinite(takeProfit.price) || takeProfit.price <= 0 || (direction === "LONG" ? takeProfit.price <= entryReference : takeProfit.price >= entryReference)) {
|
|
6507
|
-
throw new Error("TAKE_PROFIT_CROSSED_BEFORE_ENTRY");
|
|
6508
|
-
}
|
|
6509
|
-
}
|
|
6510
|
-
if (stopLossPrice != null && (!Number.isFinite(stopLossPrice) || stopLossPrice <= 0 || (direction === "LONG" ? stopLossPrice >= stopReference : stopLossPrice <= stopReference))) {
|
|
6511
|
-
throw new Error("STOP_LOSS_CROSSED_BEFORE_ENTRY");
|
|
6512
|
-
}
|
|
6513
|
-
};
|
|
6514
6642
|
var resolveRuntimeTelemetryQuality = ({
|
|
6515
6643
|
signalClosePrice,
|
|
6516
6644
|
arrivalMid,
|
|
@@ -6587,7 +6715,8 @@ var executeEntryOrder = async ({
|
|
|
6587
6715
|
signal,
|
|
6588
6716
|
beforePlaceOrder,
|
|
6589
6717
|
recordRuntimeTrade = true,
|
|
6590
|
-
leverage
|
|
6718
|
+
leverage,
|
|
6719
|
+
executionLimits
|
|
6591
6720
|
}) => {
|
|
6592
6721
|
await beforePlaceOrder?.();
|
|
6593
6722
|
const previousPosition = positionIntent === "increase" ? await connector.getPosition(symbol) : null;
|
|
@@ -6598,23 +6727,57 @@ var executeEntryOrder = async ({
|
|
|
6598
6727
|
signal.orderQty = qty;
|
|
6599
6728
|
signal.orderValue = qty * currentPrice;
|
|
6600
6729
|
signal.orderFailureReason = void 0;
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6730
|
+
let arrivalSnapshot = {
|
|
6731
|
+
arrivalSnapshotTime: Date.now(),
|
|
6732
|
+
arrivalSource: "unavailable",
|
|
6733
|
+
bid: null,
|
|
6734
|
+
ask: null,
|
|
6735
|
+
arrivalMid: null,
|
|
6736
|
+
spreadBps: null
|
|
6737
|
+
};
|
|
6738
|
+
let orderSubmitTime = Date.now();
|
|
6739
|
+
const beforeSubmit = createEntrySubmissionValidation({
|
|
6740
|
+
connector,
|
|
6741
|
+
symbol,
|
|
6742
|
+
direction,
|
|
6743
|
+
takeProfits,
|
|
6744
|
+
stopLossPrice,
|
|
6745
|
+
limits: executionLimits,
|
|
6746
|
+
onValidated: (snapshot2, economics2) => {
|
|
6747
|
+
arrivalSnapshot = snapshot2;
|
|
6748
|
+
orderSubmitTime = Date.now();
|
|
6749
|
+
if (executionLimits?.maxLossValue != null) {
|
|
6750
|
+
signal.riskDecision = {
|
|
6751
|
+
stage: "order_plan",
|
|
6752
|
+
status: economics2.riskExceeded ? "warning" : "approved",
|
|
6753
|
+
reason: economics2.riskExceeded ? "ENTRY_RISK_EXCEEDS_MAX_LOSS_AT_SUBMISSION" : "PLANNED_LOSS_WITHIN_MAX_LOSS_VALUE",
|
|
6754
|
+
plannedLossValue: economics2.plannedLossValue,
|
|
6755
|
+
maxLossValue: executionLimits.maxLossValue,
|
|
6756
|
+
limitUtilization: economics2.plannedLossValue / executionLimits.maxLossValue,
|
|
6757
|
+
enforced: false
|
|
6758
|
+
};
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
});
|
|
6762
|
+
if (!beforeSubmit) {
|
|
6763
|
+
arrivalSnapshot = await getOrderArrivalSnapshot({ connector, symbol });
|
|
6764
|
+
try {
|
|
6765
|
+
validateEntryProtectionAtArrival({
|
|
6766
|
+
direction,
|
|
6767
|
+
signalPrice: currentPrice,
|
|
6768
|
+
bid: arrivalSnapshot.bid,
|
|
6769
|
+
ask: arrivalSnapshot.ask,
|
|
6770
|
+
arrivalMid: arrivalSnapshot.arrivalMid,
|
|
6771
|
+
takeProfits,
|
|
6772
|
+
stopLossPrice
|
|
6773
|
+
});
|
|
6774
|
+
} catch (error) {
|
|
6775
|
+
signal.orderStatus = "failed";
|
|
6776
|
+
signal.orderFailureReason = error.message;
|
|
6777
|
+
throw error;
|
|
6778
|
+
}
|
|
6779
|
+
orderSubmitTime = Date.now();
|
|
6616
6780
|
}
|
|
6617
|
-
const orderSubmitTime = Date.now();
|
|
6618
6781
|
const orderPlaced = await connector.placeOrder({
|
|
6619
6782
|
symbol,
|
|
6620
6783
|
qty,
|
|
@@ -6625,7 +6788,8 @@ var executeEntryOrder = async ({
|
|
|
6625
6788
|
direction,
|
|
6626
6789
|
...typeof leverage === "number" && Number.isFinite(leverage) ? { leverage } : {},
|
|
6627
6790
|
orderId,
|
|
6628
|
-
signal
|
|
6791
|
+
signal,
|
|
6792
|
+
...beforeSubmit ? { beforeSubmit } : {}
|
|
6629
6793
|
});
|
|
6630
6794
|
const orderAckTime = Date.now();
|
|
6631
6795
|
const placedQty = typeof signal.orderQty === "number" && Number.isFinite(signal.orderQty) && signal.orderQty > 0 ? signal.orderQty : qty;
|
|
@@ -7454,7 +7618,7 @@ var canUseSharedReplayState = ({
|
|
|
7454
7618
|
}) => (env === "BACKTEST" || env === "PARITY") && Boolean(sharedReplayKey);
|
|
7455
7619
|
|
|
7456
7620
|
// src/strategy/runtimeExecution.ts
|
|
7457
|
-
var
|
|
7621
|
+
var import_logger13 = require("@tradejs/infra/logger");
|
|
7458
7622
|
var import_types = require("@tradejs/types");
|
|
7459
7623
|
var buildExitOrderSignal = ({
|
|
7460
7624
|
strategyName,
|
|
@@ -7506,7 +7670,7 @@ var handleExitDecision = async ({
|
|
|
7506
7670
|
deploymentId: connector.deploymentId
|
|
7507
7671
|
});
|
|
7508
7672
|
if (!activeTrade) {
|
|
7509
|
-
|
|
7673
|
+
import_logger13.logger.warn(
|
|
7510
7674
|
"[%s] blocked closePosition for untracked runtime position: %s",
|
|
7511
7675
|
strategyName ?? "unknown",
|
|
7512
7676
|
symbol
|
|
@@ -7514,7 +7678,7 @@ var handleExitDecision = async ({
|
|
|
7514
7678
|
return "CLOSE_BLOCKED_BY_UNTRACKED_POSITION";
|
|
7515
7679
|
}
|
|
7516
7680
|
if (!strategyName || activeTrade.strategy !== strategyName) {
|
|
7517
|
-
|
|
7681
|
+
import_logger13.logger.warn(
|
|
7518
7682
|
"[%s] blocked closePosition for foreign runtime position: %s ownedBy=%s",
|
|
7519
7683
|
strategyName ?? "unknown",
|
|
7520
7684
|
symbol,
|
|
@@ -7567,7 +7731,7 @@ var handleExitDecision = async ({
|
|
|
7567
7731
|
exitType: closedTrade?.exitType ?? "exit"
|
|
7568
7732
|
});
|
|
7569
7733
|
} catch (notificationError) {
|
|
7570
|
-
|
|
7734
|
+
import_logger13.logger.error(
|
|
7571
7735
|
"runtime close notification error: %s %s",
|
|
7572
7736
|
symbol,
|
|
7573
7737
|
notificationError
|
|
@@ -7581,7 +7745,7 @@ var handleExitDecision = async ({
|
|
|
7581
7745
|
decision,
|
|
7582
7746
|
market
|
|
7583
7747
|
});
|
|
7584
|
-
|
|
7748
|
+
import_logger13.logger.error("close order error: %s %s", symbol, err);
|
|
7585
7749
|
return "ORDER_ERROR";
|
|
7586
7750
|
}
|
|
7587
7751
|
return decision.code;
|
|
@@ -7608,7 +7772,7 @@ var handleProtectDecision = async ({
|
|
|
7608
7772
|
decision,
|
|
7609
7773
|
market
|
|
7610
7774
|
});
|
|
7611
|
-
|
|
7775
|
+
import_logger13.logger.error("protect position error: %s %s", symbol, err);
|
|
7612
7776
|
return "ORDER_ERROR";
|
|
7613
7777
|
}
|
|
7614
7778
|
return decision.code;
|
|
@@ -7674,7 +7838,11 @@ var executeEntryDecision = async ({
|
|
|
7674
7838
|
...Number.isFinite(Number(hookCtx.strategyConfig.LEVERAGE)) ? { leverage: Number(hookCtx.strategyConfig.LEVERAGE) } : {},
|
|
7675
7839
|
signal,
|
|
7676
7840
|
beforePlaceOrder,
|
|
7677
|
-
recordRuntimeTrade: recordRuntimeJournal
|
|
7841
|
+
recordRuntimeTrade: recordRuntimeJournal,
|
|
7842
|
+
executionLimits: resolveEntryExecutionLimits(
|
|
7843
|
+
hookCtx.strategyConfig,
|
|
7844
|
+
decision.entryContext.direction
|
|
7845
|
+
)
|
|
7678
7846
|
});
|
|
7679
7847
|
await invokeStageHooks(
|
|
7680
7848
|
"afterPlaceOrder",
|
|
@@ -7696,19 +7864,32 @@ var executeEntryDecision = async ({
|
|
|
7696
7864
|
return signal;
|
|
7697
7865
|
}
|
|
7698
7866
|
await beforePlaceOrder();
|
|
7699
|
-
const
|
|
7867
|
+
const beforeSubmit = createEntrySubmissionValidation({
|
|
7700
7868
|
connector,
|
|
7701
|
-
symbol
|
|
7702
|
-
});
|
|
7703
|
-
validateEntryProtectionAtArrival({
|
|
7869
|
+
symbol,
|
|
7704
7870
|
direction: decision.entryContext.direction,
|
|
7705
|
-
signalPrice: decision.entryContext.prices.currentPrice,
|
|
7706
|
-
bid: arrivalSnapshot.bid,
|
|
7707
|
-
ask: arrivalSnapshot.ask,
|
|
7708
|
-
arrivalMid: arrivalSnapshot.arrivalMid,
|
|
7709
7871
|
takeProfits: decision.orderPlan.takeProfits,
|
|
7710
|
-
stopLossPrice: decision.orderPlan.stopLossPrice
|
|
7872
|
+
stopLossPrice: decision.orderPlan.stopLossPrice,
|
|
7873
|
+
limits: resolveEntryExecutionLimits(
|
|
7874
|
+
hookCtx.strategyConfig,
|
|
7875
|
+
decision.entryContext.direction
|
|
7876
|
+
)
|
|
7711
7877
|
});
|
|
7878
|
+
if (!beforeSubmit) {
|
|
7879
|
+
const arrivalSnapshot = await getOrderArrivalSnapshot({
|
|
7880
|
+
connector,
|
|
7881
|
+
symbol
|
|
7882
|
+
});
|
|
7883
|
+
validateEntryProtectionAtArrival({
|
|
7884
|
+
direction: decision.entryContext.direction,
|
|
7885
|
+
signalPrice: decision.entryContext.prices.currentPrice,
|
|
7886
|
+
bid: arrivalSnapshot.bid,
|
|
7887
|
+
ask: arrivalSnapshot.ask,
|
|
7888
|
+
arrivalMid: arrivalSnapshot.arrivalMid,
|
|
7889
|
+
takeProfits: decision.orderPlan.takeProfits,
|
|
7890
|
+
stopLossPrice: decision.orderPlan.stopLossPrice
|
|
7891
|
+
});
|
|
7892
|
+
}
|
|
7712
7893
|
const orderPlaced = await connector.placeOrder({
|
|
7713
7894
|
symbol,
|
|
7714
7895
|
qty: decision.orderPlan.qty,
|
|
@@ -7716,6 +7897,7 @@ var executeEntryDecision = async ({
|
|
|
7716
7897
|
timestamp: decision.entryContext.timestamp,
|
|
7717
7898
|
direction: decision.entryContext.direction,
|
|
7718
7899
|
positionIntent: decision.orderPlan.positionIntent,
|
|
7900
|
+
...beforeSubmit ? { beforeSubmit } : {},
|
|
7719
7901
|
...Number.isFinite(Number(hookCtx.strategyConfig.LEVERAGE)) ? { leverage: Number(hookCtx.strategyConfig.LEVERAGE) } : {}
|
|
7720
7902
|
});
|
|
7721
7903
|
if (!orderPlaced) {
|
|
@@ -7757,6 +7939,23 @@ var executeEntryDecision = async ({
|
|
|
7757
7939
|
{ decision, entry, market }
|
|
7758
7940
|
);
|
|
7759
7941
|
} catch (err) {
|
|
7942
|
+
if (err instanceof EntrySubmissionValidationError) {
|
|
7943
|
+
if (signal) {
|
|
7944
|
+
signal.orderStatus = "skipped";
|
|
7945
|
+
signal.orderSkipReason = err.message;
|
|
7946
|
+
signal.allocatorDecision = {
|
|
7947
|
+
stage: "runtime_admission",
|
|
7948
|
+
status: "rejected",
|
|
7949
|
+
reason: err.message
|
|
7950
|
+
};
|
|
7951
|
+
}
|
|
7952
|
+
import_logger13.logger.warn(
|
|
7953
|
+
"entry rejected before submission: %s %s",
|
|
7954
|
+
symbol,
|
|
7955
|
+
err.message
|
|
7956
|
+
);
|
|
7957
|
+
return signal ?? err.message;
|
|
7958
|
+
}
|
|
7760
7959
|
if (signal) {
|
|
7761
7960
|
signal.orderStatus = "failed";
|
|
7762
7961
|
if (typeof signal.orderFailureReason !== "string" || !signal.orderFailureReason.trim()) {
|
|
@@ -7771,9 +7970,9 @@ var executeEntryDecision = async ({
|
|
|
7771
7970
|
market
|
|
7772
7971
|
});
|
|
7773
7972
|
if (err?.message === import_types.BACKTEST_WARNING_CODES.TAKE_PROFIT_CROSSED_BEFORE_ENTRY) {
|
|
7774
|
-
|
|
7973
|
+
import_logger13.logger.warn("order warning: %s %s", symbol, err);
|
|
7775
7974
|
} else {
|
|
7776
|
-
|
|
7975
|
+
import_logger13.logger.error("order error: %s %s", symbol, err);
|
|
7777
7976
|
}
|
|
7778
7977
|
return signal ?? "ORDER_ERROR";
|
|
7779
7978
|
}
|
|
@@ -7881,6 +8080,9 @@ var createStrategyRuntime = ({
|
|
|
7881
8080
|
});
|
|
7882
8081
|
const strategyPolicyProfile = getPolicyProfile();
|
|
7883
8082
|
const indicatorPeriods = (0, import_strategies6.buildDefaultIndicatorPeriods)(config);
|
|
8083
|
+
const strategyConfig = { ...config };
|
|
8084
|
+
delete strategyConfig.RECORD_RUNTIME_TRADES;
|
|
8085
|
+
delete strategyConfig.SIMULATE_ORDERS;
|
|
7884
8086
|
const hookBase = {
|
|
7885
8087
|
connector,
|
|
7886
8088
|
strategyName,
|
|
@@ -7891,7 +8093,7 @@ var createStrategyRuntime = ({
|
|
|
7891
8093
|
accountId,
|
|
7892
8094
|
deploymentId,
|
|
7893
8095
|
policyProfileId: strategyPolicyProfile?.id ?? requestedPolicyProfileId,
|
|
7894
|
-
strategyConfig
|
|
8096
|
+
strategyConfig,
|
|
7895
8097
|
env,
|
|
7896
8098
|
isConfigFromBacktest
|
|
7897
8099
|
};
|
|
@@ -7938,7 +8140,7 @@ var createStrategyRuntime = ({
|
|
|
7938
8140
|
try {
|
|
7939
8141
|
await projectHook(errorParams);
|
|
7940
8142
|
} catch (hookError) {
|
|
7941
|
-
|
|
8143
|
+
import_logger14.logger.error(
|
|
7942
8144
|
"project hook onRuntimeError failed: %s %s",
|
|
7943
8145
|
strategyName,
|
|
7944
8146
|
hookError
|
|
@@ -7952,21 +8154,21 @@ var createStrategyRuntime = ({
|
|
|
7952
8154
|
try {
|
|
7953
8155
|
await onRuntimeError(errorParams);
|
|
7954
8156
|
} catch (hookError) {
|
|
7955
|
-
|
|
8157
|
+
import_logger14.logger.error(
|
|
7956
8158
|
"runtime hook onRuntimeError failed: %s %s",
|
|
7957
8159
|
strategyName,
|
|
7958
8160
|
hookError
|
|
7959
8161
|
);
|
|
7960
8162
|
}
|
|
7961
8163
|
};
|
|
7962
|
-
const invokeHook = async (stage, hook, params, errorContext = {}) => {
|
|
8164
|
+
const invokeHook = async (stage, hook, params, errorContext = {}, failureResult) => {
|
|
7963
8165
|
if (!hook) {
|
|
7964
8166
|
return void 0;
|
|
7965
8167
|
}
|
|
7966
8168
|
try {
|
|
7967
8169
|
return await hook(params);
|
|
7968
8170
|
} catch (error) {
|
|
7969
|
-
|
|
8171
|
+
import_logger14.logger.error(
|
|
7970
8172
|
'strategy hook "%s" failed for %s: %s',
|
|
7971
8173
|
stage,
|
|
7972
8174
|
strategyName,
|
|
@@ -7979,17 +8181,18 @@ var createStrategyRuntime = ({
|
|
|
7979
8181
|
entry: errorContext.entry,
|
|
7980
8182
|
market: errorContext.market
|
|
7981
8183
|
});
|
|
7982
|
-
return
|
|
8184
|
+
return failureResult;
|
|
7983
8185
|
}
|
|
7984
8186
|
};
|
|
7985
|
-
const invokeProjectHooks = async (stage, params, errorContext = {}) => {
|
|
8187
|
+
const invokeProjectHooks = async (stage, params, errorContext = {}, failureResult) => {
|
|
7986
8188
|
const results = [];
|
|
7987
8189
|
for (const hook of getProjectHookList(stage)) {
|
|
7988
8190
|
const result = await invokeHook(
|
|
7989
8191
|
stage,
|
|
7990
8192
|
hook,
|
|
7991
8193
|
params,
|
|
7992
|
-
errorContext
|
|
8194
|
+
errorContext,
|
|
8195
|
+
failureResult
|
|
7993
8196
|
);
|
|
7994
8197
|
if (result !== void 0) {
|
|
7995
8198
|
results.push(result);
|
|
@@ -8004,10 +8207,12 @@ var createStrategyRuntime = ({
|
|
|
8004
8207
|
return invokeHook(stage, hook, params, errorContext);
|
|
8005
8208
|
};
|
|
8006
8209
|
const invokeGateHooks = async (stage, hook, params, errorContext = {}) => {
|
|
8210
|
+
const failureResult = stage === "beforeEntryGate" ? { allow: false, reason: "ERROR" } : void 0;
|
|
8007
8211
|
const projectResults = await invokeProjectHooks(
|
|
8008
8212
|
stage,
|
|
8009
8213
|
params,
|
|
8010
|
-
errorContext
|
|
8214
|
+
errorContext,
|
|
8215
|
+
failureResult
|
|
8011
8216
|
);
|
|
8012
8217
|
const projectBlock = projectResults.find(
|
|
8013
8218
|
(result) => result?.allow === false
|
|
@@ -8019,7 +8224,8 @@ var createStrategyRuntime = ({
|
|
|
8019
8224
|
stage,
|
|
8020
8225
|
hook,
|
|
8021
8226
|
params,
|
|
8022
|
-
errorContext
|
|
8227
|
+
errorContext,
|
|
8228
|
+
failureResult
|
|
8023
8229
|
);
|
|
8024
8230
|
};
|
|
8025
8231
|
const applyProjectAfterCoreDecisionHooks = async ({
|
|
@@ -8165,11 +8371,8 @@ var createStrategyRuntime = ({
|
|
|
8165
8371
|
return enrichedBaseContext;
|
|
8166
8372
|
}
|
|
8167
8373
|
});
|
|
8168
|
-
const coreConfig = { ...config };
|
|
8169
|
-
delete coreConfig.RECORD_RUNTIME_TRADES;
|
|
8170
|
-
delete coreConfig.SIMULATE_ORDERS;
|
|
8171
8374
|
const core = await createCore({
|
|
8172
|
-
config:
|
|
8375
|
+
config: strategyConfig,
|
|
8173
8376
|
data,
|
|
8174
8377
|
strategyApi,
|
|
8175
8378
|
indicatorsState
|
|
@@ -9520,7 +9723,7 @@ var loadExchangeRange = async ({
|
|
|
9520
9723
|
} catch (error) {
|
|
9521
9724
|
const message = error?.message || String(error);
|
|
9522
9725
|
errors?.push(`${label}: ${message}`);
|
|
9523
|
-
|
|
9726
|
+
import_logger15.logger.warn("strategies runtime: %s failed: %s", label, message);
|
|
9524
9727
|
return [];
|
|
9525
9728
|
}
|
|
9526
9729
|
};
|
|
@@ -9560,7 +9763,7 @@ var loadClosedPnlRows = async ({
|
|
|
9560
9763
|
} catch (error) {
|
|
9561
9764
|
const message = error?.message || String(error);
|
|
9562
9765
|
errors?.push(`getClosedPnl: ${message}`);
|
|
9563
|
-
|
|
9766
|
+
import_logger15.logger.warn("strategies runtime: getClosedPnl failed: %s", message);
|
|
9564
9767
|
return [];
|
|
9565
9768
|
}
|
|
9566
9769
|
};
|
|
@@ -9593,7 +9796,7 @@ var loadExchangeEntryRows = async ({
|
|
|
9593
9796
|
} catch (error) {
|
|
9594
9797
|
const message = error?.message || String(error);
|
|
9595
9798
|
errors?.push(`getEntryExecutions: ${message}`);
|
|
9596
|
-
|
|
9799
|
+
import_logger15.logger.warn("strategies runtime: getEntryExecutions failed: %s", message);
|
|
9597
9800
|
return [];
|
|
9598
9801
|
}
|
|
9599
9802
|
};
|
|
@@ -9609,7 +9812,7 @@ var loadOpenPositions = async (connector, errors) => {
|
|
|
9609
9812
|
} catch (error) {
|
|
9610
9813
|
const message = error?.message || String(error);
|
|
9611
9814
|
errors?.push(`getOpenPositionPnl: ${message}`);
|
|
9612
|
-
|
|
9815
|
+
import_logger15.logger.warn("strategies runtime: getOpenPositionPnl failed: %s", message);
|
|
9613
9816
|
return { positions: [], reliable: false };
|
|
9614
9817
|
}
|
|
9615
9818
|
};
|