@tradejs/cli 3.1.29-beta.290 → 3.1.29-beta.291
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2337 -1168
- package/dist/lib/aiPocketSearch.js +37 -3
- package/dist/lib/aiTrainDataset.js +1 -0
- package/dist/lib/aiTrainEvaluationDump.js +7 -2
- package/dist/lib/aiTrainResearch.js +11 -7
- package/dist/lib/coreResearch.js +12 -4
- package/dist/lib/researchMetricSnapshot.js +74 -0
- package/dist/lib/researchVisuals.js +910 -0
- package/dist/lib/strategyRelease.js +8 -2
- package/dist/lib/strategyResearch.js +133 -33
- package/dist/lib/tickerProfiles.js +76 -0
- package/dist/scripts/aiPocketSearch.js +38 -3
- package/dist/scripts/aiTrain.js +29 -17
- package/dist/scripts/coreResearch.js +12 -4
- package/dist/scripts/replay.js +53 -4
- package/dist/scripts/replayRunner.js +53 -4
- package/dist/scripts/researchVisuals.js +955 -0
- package/dist/scripts/strategyRelease.js +59 -7
- package/dist/scripts/strategyResearch.js +136 -36
- package/dist/scripts/tickerProfiles.js +114 -0
- package/package.json +8 -7
package/dist/scripts/aiTrain.js
CHANGED
|
@@ -827,7 +827,9 @@ var BASE_CONTEXT_FEATURE_SECTIONS = [
|
|
|
827
827
|
"relative",
|
|
828
828
|
"derivatives",
|
|
829
829
|
"mtf",
|
|
830
|
-
"gateFeatures"
|
|
830
|
+
"gateFeatures",
|
|
831
|
+
"tickerProfile",
|
|
832
|
+
"portfolioContext"
|
|
831
833
|
];
|
|
832
834
|
var asRecord = (value) => typeof value === "object" && value != null && !Array.isArray(value) ? value : null;
|
|
833
835
|
var collectStrategyGateFeatures = (baseContext) => {
|
|
@@ -844,6 +846,7 @@ var pickBaseContextFeatureSections = (baseContext) => Object.fromEntries(
|
|
|
844
846
|
);
|
|
845
847
|
var buildAiTrainEvaluationFeatureSnapshot = ({
|
|
846
848
|
additionalIndicators,
|
|
849
|
+
featureSnapshot,
|
|
847
850
|
mode
|
|
848
851
|
}) => {
|
|
849
852
|
if (mode === "none") {
|
|
@@ -853,12 +856,14 @@ var buildAiTrainEvaluationFeatureSnapshot = ({
|
|
|
853
856
|
const baseContext = asRecord(additional?.baseContext);
|
|
854
857
|
if (!baseContext) {
|
|
855
858
|
return {
|
|
856
|
-
baseContextAvailable: false
|
|
859
|
+
baseContextAvailable: false,
|
|
860
|
+
...featureSnapshot ? { featureSnapshot } : {}
|
|
857
861
|
};
|
|
858
862
|
}
|
|
859
863
|
const strategyGateFeatures = collectStrategyGateFeatures(baseContext);
|
|
860
864
|
const snapshot = {
|
|
861
865
|
baseContextAvailable: true,
|
|
866
|
+
...featureSnapshot ? { featureSnapshot } : {},
|
|
862
867
|
gateFeatures: baseContext.gateFeatures ?? null,
|
|
863
868
|
...strategyGateFeatures ? { strategyGateFeatures } : {}
|
|
864
869
|
};
|
|
@@ -1059,6 +1064,8 @@ var RESEARCH_CONTEXT_ENV_KEYS = [
|
|
|
1059
1064
|
"INTERVAL",
|
|
1060
1065
|
"DERIVATIVES_CONTEXT_ENABLED",
|
|
1061
1066
|
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
1067
|
+
"TICKER_PROFILES_PROVIDER",
|
|
1068
|
+
"TICKER_PROFILES_UNIVERSE",
|
|
1062
1069
|
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
1063
1070
|
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
1064
1071
|
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|
|
@@ -1093,13 +1100,15 @@ var writeAiTrainResearchSnapshot = async ({
|
|
|
1093
1100
|
}) => {
|
|
1094
1101
|
const resolvedPath = import_node_path2.default.resolve(outputPath);
|
|
1095
1102
|
await import_promises2.default.mkdir(import_node_path2.default.dirname(resolvedPath), { recursive: true });
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
"
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
+
const bytes = `${JSON.stringify(result)}
|
|
1104
|
+
`;
|
|
1105
|
+
await import_promises2.default.writeFile(resolvedPath, bytes, "utf8");
|
|
1106
|
+
return {
|
|
1107
|
+
schema: "tradejs-research-report-receipt/v1",
|
|
1108
|
+
path: resolvedPath,
|
|
1109
|
+
bytes: Buffer.byteLength(bytes),
|
|
1110
|
+
sha256: (0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex")
|
|
1111
|
+
};
|
|
1103
1112
|
};
|
|
1104
1113
|
var normalizeForStableJson = (value) => {
|
|
1105
1114
|
if (Array.isArray(value)) {
|
|
@@ -1416,6 +1425,7 @@ var extractSignalFromAiDatasetRow = (row) => {
|
|
|
1416
1425
|
const { payload } = row;
|
|
1417
1426
|
return {
|
|
1418
1427
|
...payload.signal,
|
|
1428
|
+
aiFeatureReplay: { snapshot: payload.featureSnapshot ?? null },
|
|
1419
1429
|
strategy: payload.signal.strategy,
|
|
1420
1430
|
figures: payload.figures ?? {},
|
|
1421
1431
|
indicators: payload.indicators ?? {},
|
|
@@ -1474,7 +1484,11 @@ import_args.default.option(
|
|
|
1474
1484
|
"Save compact AI approval chart data for the strategies UI",
|
|
1475
1485
|
false
|
|
1476
1486
|
);
|
|
1477
|
-
import_args.default.option(
|
|
1487
|
+
import_args.default.option(
|
|
1488
|
+
["j", "json"],
|
|
1489
|
+
"Print full JSON without --output; otherwise print its receipt",
|
|
1490
|
+
false
|
|
1491
|
+
);
|
|
1478
1492
|
import_args.default.option(
|
|
1479
1493
|
["O", "output"],
|
|
1480
1494
|
"Write the structured JSON summary to a file and suppress table output",
|
|
@@ -1938,6 +1952,7 @@ var main = async () => {
|
|
|
1938
1952
|
const isCorrect = aiApproved === profitableTrade;
|
|
1939
1953
|
const features = buildAiTrainEvaluationFeatureSnapshot({
|
|
1940
1954
|
additionalIndicators: payload.additionalIndicators,
|
|
1955
|
+
featureSnapshot: payload.featureSnapshot,
|
|
1941
1956
|
mode: dumpFeatureMode
|
|
1942
1957
|
});
|
|
1943
1958
|
evaluations.push({
|
|
@@ -2182,14 +2197,11 @@ var main = async () => {
|
|
|
2182
2197
|
ttlMs: import_constants.TTL_1M
|
|
2183
2198
|
});
|
|
2184
2199
|
}
|
|
2185
|
-
|
|
2186
|
-
await writeAiTrainResearchSnapshot({
|
|
2187
|
-
outputPath: jsonOutputPath,
|
|
2188
|
-
result
|
|
2189
|
-
});
|
|
2190
|
-
}
|
|
2200
|
+
const reportReceipt = jsonOutputPath ? await writeAiTrainResearchSnapshot({ outputPath: jsonOutputPath, result }) : null;
|
|
2191
2201
|
if (jsonOutput) {
|
|
2192
|
-
if (
|
|
2202
|
+
if (reportReceipt) {
|
|
2203
|
+
console.log(JSON.stringify(reportReceipt));
|
|
2204
|
+
} else if (printJsonOutput) {
|
|
2193
2205
|
console.log(JSON.stringify(result));
|
|
2194
2206
|
}
|
|
2195
2207
|
process.exit(failed === selectedRows ? 1 : 0);
|
|
@@ -46,7 +46,7 @@ var import_node_path = __toESM(require("path"));
|
|
|
46
46
|
|
|
47
47
|
// src/lib/coreResearch/types.ts
|
|
48
48
|
var CORE_RESEARCH_SCHEMA = "tradejs-core-research/v1";
|
|
49
|
-
var CORE_RESEARCH_RESULT_SCHEMA = "tradejs-core-research-result/
|
|
49
|
+
var CORE_RESEARCH_RESULT_SCHEMA = "tradejs-core-research-result/v2";
|
|
50
50
|
var CORE_RESEARCH_LEDGER_SCHEMA = "tradejs-core-research-ledger/v1";
|
|
51
51
|
|
|
52
52
|
// src/lib/coreResearch/io.ts
|
|
@@ -731,6 +731,14 @@ var writeCoreResearchTrades = async (params) => {
|
|
|
731
731
|
}
|
|
732
732
|
await closeOutput(output);
|
|
733
733
|
};
|
|
734
|
+
var summarizeCoreResearchComparison = (comparison) => {
|
|
735
|
+
const { matchedPairs, ...summary } = comparison;
|
|
736
|
+
return {
|
|
737
|
+
...summary,
|
|
738
|
+
exitReasonChanges: matchedPairs.filter((pair) => pair.exitReasonChanged).length,
|
|
739
|
+
exitCodeChanges: matchedPairs.filter((pair) => pair.exitCodeChanged).length
|
|
740
|
+
};
|
|
741
|
+
};
|
|
734
742
|
|
|
735
743
|
// src/lib/coreResearch/metrics.ts
|
|
736
744
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -1806,7 +1814,7 @@ var buildCurveSvg = (tradesByVariant, cohort, curve) => {
|
|
|
1806
1814
|
)}</svg><div class="legend">${series.map((entry) => `<span><i style="background:${entry.color}"></i>${escapeHtml(entry.id)}</span>`).join("")}</div>`;
|
|
1807
1815
|
};
|
|
1808
1816
|
var comparisonCards = (comparisons) => comparisons.map(
|
|
1809
|
-
(comparison) => `<article class="card"><h3>${escapeHtml(comparison.candidateId)} vs ${escapeHtml(comparison.controlId)}</h3><p class="verdict ${comparison.selection.passed ? "positive" : "negative"}">${comparison.selection.passed ? "PASS selection" : "REJECT selection"}</p><dl><dt>Matched</dt><dd>${comparison.matched}</dd><dt>Control only</dt><dd>${comparison.controlOnly}</dd><dt>Candidate only</dt><dd>${comparison.candidateOnly}</dd><dt>Identity retained</dt><dd>${format(comparison.matchedIdentityPctOfControl)}%</dd><dt>Exit reason changes</dt><dd>${comparison.
|
|
1817
|
+
(comparison) => `<article class="card"><h3>${escapeHtml(comparison.candidateId)} vs ${escapeHtml(comparison.controlId)}</h3><p class="verdict ${comparison.selection.passed ? "positive" : "negative"}">${comparison.selection.passed ? "PASS selection" : "REJECT selection"}</p><dl><dt>Matched</dt><dd>${comparison.matched}</dd><dt>Control only</dt><dd>${comparison.controlOnly}</dd><dt>Candidate only</dt><dd>${comparison.candidateOnly}</dd><dt>Identity retained</dt><dd>${format(comparison.matchedIdentityPctOfControl)}%</dd><dt>Exit reason changes</dt><dd>${comparison.exitReasonChanges}</dd><dt>Exit code changes</dt><dd>${comparison.exitCodeChanges}</dd><dt>Matched \u0394PnL</dt><dd>${format(comparison.cohorts.ALL.matchedPnlDelta)}</dd><dt>Removed control PnL</dt><dd>${format(comparison.cohorts.ALL.controlOnlyPnl)}</dd><dt>Added candidate PnL</dt><dd>${format(comparison.cohorts.ALL.candidateOnlyPnl)}</dd><dt>Aggregate \u0394PnL</dt><dd>${format(comparison.cohorts.ALL.delta.pnl)}</dd><dt>Aggregate \u0394DD</dt><dd>${format(comparison.cohorts.ALL.delta.realizedMaxDrawdown)}</dd><dt>Bootstrap P(\u0394>0)</dt><dd>${format(comparison.bootstrap.probabilityPositive, 4)}</dd><dt>Holm p</dt><dd>${format(comparison.bootstrap.holmAdjustedPValue, 4)}</dd></dl><p>${comparison.selection.failedRules.length ? escapeHtml(comparison.selection.failedRules.map((rule) => `${rule.scope}.${rule.metric} ${rule.expected}`).join("; ")) : "All preregistered rules passed."}</p></article>`
|
|
1810
1818
|
).join("");
|
|
1811
1819
|
var regimeRows = (variants) => {
|
|
1812
1820
|
const keys = [
|
|
@@ -2491,7 +2499,7 @@ var analyzeCoreResearchPrepared = async (spec, options = {}) => {
|
|
|
2491
2499
|
regimeCausality: "signal-time payload.additionalIndicators.baseContext only"
|
|
2492
2500
|
},
|
|
2493
2501
|
variants: analyses,
|
|
2494
|
-
comparisons,
|
|
2502
|
+
comparisons: comparisons.map(summarizeCoreResearchComparison),
|
|
2495
2503
|
multipleTesting: {
|
|
2496
2504
|
family: spec.hypothesis.family,
|
|
2497
2505
|
hypotheses: Math.max(comparisons.length, familyHypotheses),
|
|
@@ -2524,7 +2532,7 @@ var analyzeCoreResearchPrepared = async (spec, options = {}) => {
|
|
|
2524
2532
|
artifactHashes: sourceHashes
|
|
2525
2533
|
};
|
|
2526
2534
|
await writeJsonAtomic(paths.resultPath, result);
|
|
2527
|
-
await writeJsonAtomic(paths.comparisonPath, comparisons);
|
|
2535
|
+
await writeJsonAtomic(paths.comparisonPath, result.comparisons);
|
|
2528
2536
|
await writeCoreResearchMatches({ filePath: paths.matchesPath, comparisons });
|
|
2529
2537
|
await writeCoreResearchTrades({
|
|
2530
2538
|
filePath: paths.tradesPath,
|
package/dist/scripts/replay.js
CHANGED
|
@@ -5183,6 +5183,9 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5183
5183
|
let executionTimestamp = null;
|
|
5184
5184
|
const positionsBySymbol = /* @__PURE__ */ new Map();
|
|
5185
5185
|
const currentPriceBySymbol = /* @__PURE__ */ new Map();
|
|
5186
|
+
const markedAtBySymbol = /* @__PURE__ */ new Map();
|
|
5187
|
+
const entryFacts = /* @__PURE__ */ new Map();
|
|
5188
|
+
let portfolioObserved = false;
|
|
5186
5189
|
const orderLog = [];
|
|
5187
5190
|
const positionLog = [];
|
|
5188
5191
|
const orderLogByStrategy = /* @__PURE__ */ new Map();
|
|
@@ -5420,14 +5423,51 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5420
5423
|
const { strategyName: _strategyName, ...nextPosition } = position;
|
|
5421
5424
|
return nextPosition;
|
|
5422
5425
|
}),
|
|
5426
|
+
getPortfolioObservation: async (asOf, reservations) => {
|
|
5427
|
+
portfolioObserved = true;
|
|
5428
|
+
const pendingIds = new Set(reservations.map((r) => r.id));
|
|
5429
|
+
for (const id of entryFacts.keys())
|
|
5430
|
+
if (!pendingIds.has(id)) entryFacts.delete(id);
|
|
5431
|
+
return {
|
|
5432
|
+
asOf,
|
|
5433
|
+
positions: Array.from(positionsBySymbol.values()).map(
|
|
5434
|
+
({ position, stopLossPrice }) => ({
|
|
5435
|
+
id: position.orderId ?? `${position.strategyName}:${position.symbol}:${position.timestamp}`,
|
|
5436
|
+
strategy: position.strategyName === UNKNOWN_STRATEGY ? null : position.strategyName,
|
|
5437
|
+
symbol: position.symbol,
|
|
5438
|
+
direction: position.direction,
|
|
5439
|
+
qty: position.qty,
|
|
5440
|
+
entryPrice: position.price,
|
|
5441
|
+
markPrice: currentPriceBySymbol.get(position.symbol) ?? null,
|
|
5442
|
+
markedAt: markedAtBySymbol.get(position.symbol) ?? null,
|
|
5443
|
+
stopLossPrice
|
|
5444
|
+
})
|
|
5445
|
+
),
|
|
5446
|
+
orders: reservations.map(
|
|
5447
|
+
(r) => entryFacts.get(r.id) ?? {
|
|
5448
|
+
id: r.id,
|
|
5449
|
+
status: "pending",
|
|
5450
|
+
filledQty: 0
|
|
5451
|
+
}
|
|
5452
|
+
)
|
|
5453
|
+
};
|
|
5454
|
+
},
|
|
5423
5455
|
getOpenPositionPnl: async () => Array.from(positionsBySymbol.values()).map(
|
|
5424
|
-
({ position }) =>
|
|
5425
|
-
|
|
5426
|
-
|
|
5456
|
+
({ position, stopLossPrice }) => ({
|
|
5457
|
+
...getPositionPnlSnapshot({
|
|
5458
|
+
position,
|
|
5459
|
+
currentPrice: currentPriceBySymbol.get(position.symbol) ?? position.price
|
|
5460
|
+
}),
|
|
5461
|
+
observedAt: markedAtBySymbol.get(position.symbol),
|
|
5462
|
+
stopLossPrice
|
|
5427
5463
|
})
|
|
5428
5464
|
),
|
|
5429
5465
|
placeOrder: async (order) => {
|
|
5430
|
-
const {
|
|
5466
|
+
const {
|
|
5467
|
+
beforeSubmit,
|
|
5468
|
+
onRejected: _onRejected,
|
|
5469
|
+
...submittedOrder
|
|
5470
|
+
} = order;
|
|
5431
5471
|
if (positionsBySymbol.has(order.symbol)) {
|
|
5432
5472
|
return false;
|
|
5433
5473
|
}
|
|
@@ -5471,6 +5511,14 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5471
5511
|
stopLossPrice: null
|
|
5472
5512
|
};
|
|
5473
5513
|
positionsBySymbol.set(order.symbol, positionState);
|
|
5514
|
+
markedAtBySymbol.set(order.symbol, executionTimestamp ?? order.timestamp);
|
|
5515
|
+
if (portfolioObserved && order.orderId)
|
|
5516
|
+
entryFacts.set(order.orderId, {
|
|
5517
|
+
id: order.orderId,
|
|
5518
|
+
status: "filled",
|
|
5519
|
+
filledQty: order.qty,
|
|
5520
|
+
positionId: order.orderId
|
|
5521
|
+
});
|
|
5474
5522
|
logOrder({
|
|
5475
5523
|
positionState,
|
|
5476
5524
|
data: {
|
|
@@ -5554,6 +5602,7 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5554
5602
|
getTickers: connector.getTickers,
|
|
5555
5603
|
advanceMarket: async ({ symbol, candle }) => {
|
|
5556
5604
|
executionTimestamp = candle.timestamp;
|
|
5605
|
+
markedAtBySymbol.set(symbol, candle.timestamp);
|
|
5557
5606
|
currentPriceBySymbol.set(symbol, candle.close);
|
|
5558
5607
|
await checkSl({ symbol, candle });
|
|
5559
5608
|
await checkTp({ symbol, candle });
|
|
@@ -5188,6 +5188,9 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5188
5188
|
let executionTimestamp = null;
|
|
5189
5189
|
const positionsBySymbol = /* @__PURE__ */ new Map();
|
|
5190
5190
|
const currentPriceBySymbol = /* @__PURE__ */ new Map();
|
|
5191
|
+
const markedAtBySymbol = /* @__PURE__ */ new Map();
|
|
5192
|
+
const entryFacts = /* @__PURE__ */ new Map();
|
|
5193
|
+
let portfolioObserved = false;
|
|
5191
5194
|
const orderLog = [];
|
|
5192
5195
|
const positionLog = [];
|
|
5193
5196
|
const orderLogByStrategy = /* @__PURE__ */ new Map();
|
|
@@ -5425,14 +5428,51 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5425
5428
|
const { strategyName: _strategyName, ...nextPosition } = position;
|
|
5426
5429
|
return nextPosition;
|
|
5427
5430
|
}),
|
|
5431
|
+
getPortfolioObservation: async (asOf, reservations) => {
|
|
5432
|
+
portfolioObserved = true;
|
|
5433
|
+
const pendingIds = new Set(reservations.map((r) => r.id));
|
|
5434
|
+
for (const id of entryFacts.keys())
|
|
5435
|
+
if (!pendingIds.has(id)) entryFacts.delete(id);
|
|
5436
|
+
return {
|
|
5437
|
+
asOf,
|
|
5438
|
+
positions: Array.from(positionsBySymbol.values()).map(
|
|
5439
|
+
({ position, stopLossPrice }) => ({
|
|
5440
|
+
id: position.orderId ?? `${position.strategyName}:${position.symbol}:${position.timestamp}`,
|
|
5441
|
+
strategy: position.strategyName === UNKNOWN_STRATEGY ? null : position.strategyName,
|
|
5442
|
+
symbol: position.symbol,
|
|
5443
|
+
direction: position.direction,
|
|
5444
|
+
qty: position.qty,
|
|
5445
|
+
entryPrice: position.price,
|
|
5446
|
+
markPrice: currentPriceBySymbol.get(position.symbol) ?? null,
|
|
5447
|
+
markedAt: markedAtBySymbol.get(position.symbol) ?? null,
|
|
5448
|
+
stopLossPrice
|
|
5449
|
+
})
|
|
5450
|
+
),
|
|
5451
|
+
orders: reservations.map(
|
|
5452
|
+
(r) => entryFacts.get(r.id) ?? {
|
|
5453
|
+
id: r.id,
|
|
5454
|
+
status: "pending",
|
|
5455
|
+
filledQty: 0
|
|
5456
|
+
}
|
|
5457
|
+
)
|
|
5458
|
+
};
|
|
5459
|
+
},
|
|
5428
5460
|
getOpenPositionPnl: async () => Array.from(positionsBySymbol.values()).map(
|
|
5429
|
-
({ position }) =>
|
|
5430
|
-
|
|
5431
|
-
|
|
5461
|
+
({ position, stopLossPrice }) => ({
|
|
5462
|
+
...getPositionPnlSnapshot({
|
|
5463
|
+
position,
|
|
5464
|
+
currentPrice: currentPriceBySymbol.get(position.symbol) ?? position.price
|
|
5465
|
+
}),
|
|
5466
|
+
observedAt: markedAtBySymbol.get(position.symbol),
|
|
5467
|
+
stopLossPrice
|
|
5432
5468
|
})
|
|
5433
5469
|
),
|
|
5434
5470
|
placeOrder: async (order) => {
|
|
5435
|
-
const {
|
|
5471
|
+
const {
|
|
5472
|
+
beforeSubmit,
|
|
5473
|
+
onRejected: _onRejected,
|
|
5474
|
+
...submittedOrder
|
|
5475
|
+
} = order;
|
|
5436
5476
|
if (positionsBySymbol.has(order.symbol)) {
|
|
5437
5477
|
return false;
|
|
5438
5478
|
}
|
|
@@ -5476,6 +5516,14 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5476
5516
|
stopLossPrice: null
|
|
5477
5517
|
};
|
|
5478
5518
|
positionsBySymbol.set(order.symbol, positionState);
|
|
5519
|
+
markedAtBySymbol.set(order.symbol, executionTimestamp ?? order.timestamp);
|
|
5520
|
+
if (portfolioObserved && order.orderId)
|
|
5521
|
+
entryFacts.set(order.orderId, {
|
|
5522
|
+
id: order.orderId,
|
|
5523
|
+
status: "filled",
|
|
5524
|
+
filledQty: order.qty,
|
|
5525
|
+
positionId: order.orderId
|
|
5526
|
+
});
|
|
5479
5527
|
logOrder({
|
|
5480
5528
|
positionState,
|
|
5481
5529
|
data: {
|
|
@@ -5559,6 +5607,7 @@ var createPortfolioReplayConnector = (connector) => {
|
|
|
5559
5607
|
getTickers: connector.getTickers,
|
|
5560
5608
|
advanceMarket: async ({ symbol, candle }) => {
|
|
5561
5609
|
executionTimestamp = candle.timestamp;
|
|
5610
|
+
markedAtBySymbol.set(symbol, candle.timestamp);
|
|
5562
5611
|
currentPriceBySymbol.set(symbol, candle.close);
|
|
5563
5612
|
await checkSl({ symbol, candle });
|
|
5564
5613
|
await checkTp({ symbol, candle });
|