hedgequantx 2.6.63 → 2.6.64
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
CHANGED
|
@@ -961,6 +961,21 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
961
961
|
clearInterval(refreshInterval);
|
|
962
962
|
clearInterval(pnlInterval);
|
|
963
963
|
|
|
964
|
+
// EMERGENCY STOP: Cancel all orders and flatten all positions
|
|
965
|
+
if (useFastPath && service && account.rithmicAccountId) {
|
|
966
|
+
try {
|
|
967
|
+
ui.addLog('warning', 'EMERGENCY STOP - Cancelling orders & flattening positions...');
|
|
968
|
+
const stopResult = await service.emergencyStop(account.rithmicAccountId);
|
|
969
|
+
if (stopResult.success) {
|
|
970
|
+
ui.addLog('success', 'All orders cancelled, positions flattened');
|
|
971
|
+
} else {
|
|
972
|
+
ui.addLog('error', 'Emergency stop partial - check positions manually');
|
|
973
|
+
}
|
|
974
|
+
} catch (e) {
|
|
975
|
+
ui.addLog('error', `Emergency stop failed: ${e.message}`);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
964
979
|
// Stop Position Manager (fast path)
|
|
965
980
|
if (positionManager) {
|
|
966
981
|
positionManager.stop();
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
getPositions,
|
|
18
18
|
hashAccountId,
|
|
19
19
|
} = require('./accounts');
|
|
20
|
-
const { placeOrder, cancelOrder, getOrders, getOrderHistory, closePosition, fastEntry, fastExit } = require('./orders');
|
|
20
|
+
const { placeOrder, cancelOrder, cancelAllOrders, getOrders, getOrderHistory, closePosition, flattenAll, emergencyStop, fastEntry, fastExit } = require('./orders');
|
|
21
21
|
const { decodeFrontMonthContract } = require('./protobuf');
|
|
22
22
|
const { TIMEOUTS, CACHE } = require('../../config/settings');
|
|
23
23
|
const { logger } = require('../../utils/logger');
|
|
@@ -472,7 +472,10 @@ class RithmicService extends EventEmitter {
|
|
|
472
472
|
async getOrderHistory(date) { return getOrderHistory(this, date); }
|
|
473
473
|
async placeOrder(orderData) { return placeOrder(this, orderData); }
|
|
474
474
|
async cancelOrder(orderId) { return cancelOrder(this, orderId); }
|
|
475
|
+
async cancelAllOrders(accountId) { return cancelAllOrders(this, accountId); }
|
|
475
476
|
async closePosition(accountId, symbol) { return closePosition(this, accountId, symbol); }
|
|
477
|
+
async flattenAll(accountId) { return flattenAll(this, accountId); }
|
|
478
|
+
async emergencyStop(accountId) { return emergencyStop(this, accountId); }
|
|
476
479
|
|
|
477
480
|
// ==================== FAST SCALPING (Ultra-Low Latency) ====================
|
|
478
481
|
|
|
@@ -16,6 +16,9 @@ const { REQ } = require('./constants');
|
|
|
16
16
|
const { proto } = require('./protobuf');
|
|
17
17
|
const { LatencyTracker } = require('./handlers');
|
|
18
18
|
const { performance } = require('perf_hooks');
|
|
19
|
+
const { logger } = require('../../utils/logger');
|
|
20
|
+
|
|
21
|
+
const log = logger.scope('RithmicOrders');
|
|
19
22
|
|
|
20
23
|
// Debug mode - use no-op function when disabled for zero overhead
|
|
21
24
|
const DEBUG = process.env.HQX_DEBUG === '1';
|
|
@@ -447,12 +450,98 @@ const closePosition = async (service, accountId, symbol) => {
|
|
|
447
450
|
});
|
|
448
451
|
};
|
|
449
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Cancel all open orders for an account
|
|
455
|
+
* @param {RithmicService} service - The Rithmic service instance
|
|
456
|
+
* @param {string} accountId - Account ID
|
|
457
|
+
*/
|
|
458
|
+
const cancelAllOrders = async (service, accountId) => {
|
|
459
|
+
if (!service.orderConn || !service.loginInfo) {
|
|
460
|
+
return { success: false, error: 'Not connected' };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
try {
|
|
464
|
+
// Use RequestCancelAllOrders template
|
|
465
|
+
service.orderConn.send('RequestCancelAllOrders', {
|
|
466
|
+
templateId: 346, // CANCEL_ALL_ORDERS
|
|
467
|
+
userMsg: ['HQX-STOP'],
|
|
468
|
+
fcmId: service.loginInfo.fcmId,
|
|
469
|
+
ibId: service.loginInfo.ibId,
|
|
470
|
+
accountId: accountId,
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
log.info('Cancel all orders sent', { accountId });
|
|
474
|
+
return { success: true };
|
|
475
|
+
} catch (error) {
|
|
476
|
+
log.error('Cancel all orders failed', { error: error.message });
|
|
477
|
+
return { success: false, error: error.message };
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Flatten all positions for an account (close all positions)
|
|
483
|
+
* @param {RithmicService} service - The Rithmic service instance
|
|
484
|
+
* @param {string} accountId - Account ID
|
|
485
|
+
*/
|
|
486
|
+
const flattenAll = async (service, accountId) => {
|
|
487
|
+
const results = [];
|
|
488
|
+
const positions = Array.from(service.positions.values());
|
|
489
|
+
const accountPositions = positions.filter(p => p.accountId === accountId && p.quantity !== 0);
|
|
490
|
+
|
|
491
|
+
log.info('Flattening all positions', { accountId, count: accountPositions.length });
|
|
492
|
+
|
|
493
|
+
for (const position of accountPositions) {
|
|
494
|
+
try {
|
|
495
|
+
const result = await placeOrder(service, {
|
|
496
|
+
accountId,
|
|
497
|
+
symbol: position.symbol,
|
|
498
|
+
exchange: position.exchange,
|
|
499
|
+
size: Math.abs(position.quantity),
|
|
500
|
+
side: position.quantity > 0 ? 1 : 0, // Sell if long, Buy if short
|
|
501
|
+
type: 2, // Market
|
|
502
|
+
});
|
|
503
|
+
results.push({ symbol: position.symbol, ...result });
|
|
504
|
+
} catch (error) {
|
|
505
|
+
results.push({ symbol: position.symbol, success: false, error: error.message });
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return { success: true, results };
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Emergency stop - Cancel all orders and flatten all positions
|
|
514
|
+
* @param {RithmicService} service - The Rithmic service instance
|
|
515
|
+
* @param {string} accountId - Account ID
|
|
516
|
+
*/
|
|
517
|
+
const emergencyStop = async (service, accountId) => {
|
|
518
|
+
log.warn('EMERGENCY STOP initiated', { accountId });
|
|
519
|
+
|
|
520
|
+
// 1. Cancel all orders first
|
|
521
|
+
const cancelResult = await cancelAllOrders(service, accountId);
|
|
522
|
+
|
|
523
|
+
// 2. Wait a moment for cancellations to process
|
|
524
|
+
await new Promise(r => setTimeout(r, 500));
|
|
525
|
+
|
|
526
|
+
// 3. Flatten all positions
|
|
527
|
+
const flattenResult = await flattenAll(service, accountId);
|
|
528
|
+
|
|
529
|
+
return {
|
|
530
|
+
success: cancelResult.success && flattenResult.success,
|
|
531
|
+
cancelled: cancelResult,
|
|
532
|
+
flattened: flattenResult,
|
|
533
|
+
};
|
|
534
|
+
};
|
|
535
|
+
|
|
450
536
|
module.exports = {
|
|
451
537
|
placeOrder,
|
|
452
538
|
cancelOrder,
|
|
539
|
+
cancelAllOrders,
|
|
453
540
|
getOrders,
|
|
454
541
|
getOrderHistory,
|
|
455
542
|
closePosition,
|
|
543
|
+
flattenAll,
|
|
544
|
+
emergencyStop,
|
|
456
545
|
// Fast scalping - ultra-low latency
|
|
457
546
|
fastEntry,
|
|
458
547
|
fastExit,
|