hedgequantx 2.6.58 → 2.6.59
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/package.json +1 -1
- package/src/pages/algo/one-account.js +18 -53
package/package.json
CHANGED
|
@@ -315,68 +315,53 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
315
315
|
|
|
316
316
|
positionManager.start();
|
|
317
317
|
|
|
318
|
-
// Listen for position manager events
|
|
318
|
+
// Listen for position manager events - CLEAN LOGS (no verbose order status)
|
|
319
319
|
positionManager.on('entryFilled', ({ orderTag, position, fillLatencyMs }) => {
|
|
320
320
|
stats.entryLatencies.push(fillLatencyMs);
|
|
321
321
|
stats.avgFillLatency = stats.entryLatencies.reduce((a, b) => a + b, 0) / stats.entryLatencies.length;
|
|
322
|
-
|
|
322
|
+
const side = position.side === 0 ? 'LONG' : 'SHORT';
|
|
323
|
+
algoLogger.info(ui, 'FILLED', `${side} ${position.size}x ${symbolName} @ ${position.entryPrice} | ${fillLatencyMs}ms`);
|
|
323
324
|
});
|
|
324
325
|
|
|
325
326
|
positionManager.on('exitFilled', ({ orderTag, exitPrice, pnlTicks, holdDurationMs }) => {
|
|
327
|
+
const holdSec = (holdDurationMs / 1000).toFixed(1);
|
|
326
328
|
// Calculate PnL in dollars only if tickValue is available from API
|
|
327
329
|
if (pnlTicks !== null && tickValue !== null) {
|
|
328
330
|
const pnlDollars = pnlTicks * tickValue;
|
|
329
331
|
stats.sessionPnl += pnlDollars; // Track session P&L
|
|
330
332
|
if (pnlDollars >= 0) {
|
|
331
333
|
stats.wins++;
|
|
332
|
-
algoLogger.
|
|
334
|
+
algoLogger.info(ui, 'WIN', `+$${pnlDollars.toFixed(2)} @ ${exitPrice} | ${holdSec}s`);
|
|
333
335
|
} else {
|
|
334
336
|
stats.losses++;
|
|
335
|
-
algoLogger.
|
|
337
|
+
algoLogger.info(ui, 'LOSS', `-$${Math.abs(pnlDollars).toFixed(2)} @ ${exitPrice} | ${holdSec}s`);
|
|
336
338
|
}
|
|
337
339
|
} else {
|
|
338
340
|
// Log with ticks only if tickValue unavailable
|
|
339
341
|
if (pnlTicks !== null && pnlTicks >= 0) {
|
|
340
342
|
stats.wins++;
|
|
341
|
-
algoLogger.info(ui, '
|
|
343
|
+
algoLogger.info(ui, 'WIN', `+${pnlTicks} ticks | ${holdSec}s`);
|
|
342
344
|
} else if (pnlTicks !== null) {
|
|
343
345
|
stats.losses++;
|
|
344
|
-
algoLogger.info(ui, '
|
|
346
|
+
algoLogger.info(ui, 'LOSS', `${pnlTicks} ticks | ${holdSec}s`);
|
|
345
347
|
}
|
|
346
348
|
}
|
|
347
349
|
stats.trades++;
|
|
348
350
|
currentPosition = 0;
|
|
349
351
|
stats.position = 0; // Reset UI position display
|
|
350
352
|
pendingOrder = false;
|
|
351
|
-
algoLogger.info(ui, 'HOLD TIME', `${(holdDurationMs / 1000).toFixed(1)}s`);
|
|
352
353
|
});
|
|
353
354
|
|
|
354
355
|
positionManager.on('holdComplete', ({ orderTag, position }) => {
|
|
355
|
-
algoLogger.info(ui, '
|
|
356
|
+
algoLogger.info(ui, 'READY', `Hold complete - monitoring exit`);
|
|
356
357
|
});
|
|
357
358
|
|
|
358
359
|
positionManager.on('exitOrderFired', ({ orderTag, exitReason, latencyMs }) => {
|
|
359
|
-
|
|
360
|
+
// Don't log here - exitFilled will log the result
|
|
360
361
|
});
|
|
361
362
|
|
|
362
|
-
//
|
|
363
|
-
|
|
364
|
-
algoLogger.info(ui, 'ORDER ACCEPTED', `tag=${data.orderTag} basket=${data.basketId}`);
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
service.on('orderNotification', (data) => {
|
|
368
|
-
const status = data.status || 'unknown';
|
|
369
|
-
const fillQty = data.fillQuantity || data.totalFillQuantity || 0;
|
|
370
|
-
if (fillQty > 0) {
|
|
371
|
-
algoLogger.info(ui, 'ORDER FILL', `tag=${data.orderTag} qty=${fillQty} @ ${data.avgFillPrice}`);
|
|
372
|
-
} else {
|
|
373
|
-
algoLogger.info(ui, 'ORDER STATUS', `tag=${data.orderTag} status=${status}`);
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
service.on('orderFilled', (data) => {
|
|
378
|
-
algoLogger.info(ui, 'FILL CONFIRMED', `${data.transactionType === 1 ? 'BUY' : 'SELL'} ${data.fillQuantity}x @ ${data.avgFillPrice}`);
|
|
379
|
-
});
|
|
363
|
+
// NOTE: Removed verbose DEBUG logs (ORDER ACCEPTED, ORDER STATUS, ORDER FILL, FILL CONFIRMED)
|
|
364
|
+
// Entry/Exit fills are logged by positionManager events (entryFilled, exitFilled)
|
|
380
365
|
}
|
|
381
366
|
|
|
382
367
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -539,11 +524,11 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
539
524
|
}
|
|
540
525
|
|
|
541
526
|
const riskPct = Math.round((riskAmount / maxRisk) * 100);
|
|
542
|
-
algoLogger.positionSized(ui, contracts, kelly, riskAmount, riskPct);
|
|
543
527
|
|
|
544
528
|
// Place order via API
|
|
545
529
|
pendingOrder = true;
|
|
546
530
|
const orderSide = direction === 'long' ? 0 : 1; // 0=Buy, 1=Sell
|
|
531
|
+
const sideStr = direction === 'long' ? 'LONG' : 'SHORT';
|
|
547
532
|
|
|
548
533
|
try {
|
|
549
534
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -559,49 +544,29 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
559
544
|
};
|
|
560
545
|
|
|
561
546
|
// CRITICAL: Use rithmicAccountId (original) not accountId (hash) for Rithmic orders
|
|
562
|
-
// The accountId field is hashed for display, but Rithmic API needs the original
|
|
563
547
|
if (account.rithmicAccountId) {
|
|
564
548
|
orderData.accountId = account.rithmicAccountId;
|
|
565
549
|
}
|
|
566
550
|
|
|
567
|
-
// Log
|
|
568
|
-
algoLogger.info(ui, '
|
|
551
|
+
// Log entry attempt (single line)
|
|
552
|
+
algoLogger.info(ui, 'ENTRY', `${sideStr} ${contracts}x ${symbolName} | risk: $${riskAmount} (${riskPct}%)`);
|
|
569
553
|
|
|
570
554
|
// Fire-and-forget entry (no await on fill)
|
|
571
555
|
const entryResult = service.fastEntry(orderData);
|
|
572
556
|
|
|
573
|
-
// Log the order tag for tracking
|
|
574
|
-
algoLogger.info(ui, 'ORDER TAG', `${entryResult.orderTag} | success=${entryResult.success}`);
|
|
575
|
-
|
|
576
557
|
if (entryResult.success) {
|
|
577
558
|
// Register with position manager for lifecycle tracking
|
|
578
|
-
|
|
579
|
-
const contractInfo = {
|
|
580
|
-
tickSize,
|
|
581
|
-
tickValue,
|
|
582
|
-
contractId,
|
|
583
|
-
};
|
|
559
|
+
const contractInfo = { tickSize, tickValue, contractId };
|
|
584
560
|
positionManager.registerEntry(entryResult, orderData, contractInfo);
|
|
585
561
|
|
|
586
562
|
currentPosition = direction === 'long' ? contracts : -contracts;
|
|
587
|
-
const sideStr = direction === 'long' ? 'BUY' : 'SELL';
|
|
588
|
-
|
|
589
|
-
// Log with latency
|
|
590
|
-
const latencyColor = entryResult.latencyMs < FAST_SCALPING.LATENCY_TARGET_MS
|
|
591
|
-
? chalk.green
|
|
592
|
-
: entryResult.latencyMs < FAST_SCALPING.LATENCY_WARN_MS
|
|
593
|
-
? chalk.yellow
|
|
594
|
-
: chalk.red;
|
|
595
563
|
|
|
564
|
+
// Update avg entry latency
|
|
596
565
|
stats.avgEntryLatency = stats.entryLatencies.length > 0
|
|
597
566
|
? (stats.avgEntryLatency * stats.entryLatencies.length + entryResult.latencyMs) / (stats.entryLatencies.length + 1)
|
|
598
567
|
: entryResult.latencyMs;
|
|
599
568
|
|
|
600
|
-
|
|
601
|
-
algoLogger.info(ui, 'HOLD START', `Min ${FAST_SCALPING.MIN_HOLD_MS / 1000}s before exit`);
|
|
602
|
-
|
|
603
|
-
// Note: NO bracket orders in fast path
|
|
604
|
-
// PositionManager handles exit logic after 10s hold
|
|
569
|
+
// Note: Fill confirmation logged by positionManager.on('entryFilled')
|
|
605
570
|
|
|
606
571
|
} else {
|
|
607
572
|
algoLogger.orderRejected(ui, symbolName, entryResult.error || 'Fast entry failed');
|