hedgequantx 2.6.161 → 2.6.163

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.
Files changed (57) hide show
  1. package/package.json +1 -1
  2. package/src/menus/ai-agent-connect.js +181 -0
  3. package/src/menus/ai-agent-models.js +219 -0
  4. package/src/menus/ai-agent-oauth.js +292 -0
  5. package/src/menus/ai-agent-ui.js +141 -0
  6. package/src/menus/ai-agent.js +88 -1489
  7. package/src/pages/algo/copy-engine.js +449 -0
  8. package/src/pages/algo/copy-trading.js +11 -543
  9. package/src/pages/algo/smart-logs-data.js +218 -0
  10. package/src/pages/algo/smart-logs.js +9 -214
  11. package/src/pages/algo/ui-constants.js +144 -0
  12. package/src/pages/algo/ui-summary.js +184 -0
  13. package/src/pages/algo/ui.js +42 -526
  14. package/src/pages/stats-calculations.js +191 -0
  15. package/src/pages/stats-ui.js +381 -0
  16. package/src/pages/stats.js +14 -507
  17. package/src/services/ai/client-analysis.js +194 -0
  18. package/src/services/ai/client-models.js +333 -0
  19. package/src/services/ai/client.js +6 -489
  20. package/src/services/ai/index.js +2 -257
  21. package/src/services/ai/providers/direct-providers.js +323 -0
  22. package/src/services/ai/providers/index.js +8 -472
  23. package/src/services/ai/providers/other-providers.js +104 -0
  24. package/src/services/ai/proxy-install.js +249 -0
  25. package/src/services/ai/proxy-manager.js +29 -411
  26. package/src/services/ai/proxy-remote.js +161 -0
  27. package/src/services/ai/supervisor-optimize.js +215 -0
  28. package/src/services/ai/supervisor-sync.js +178 -0
  29. package/src/services/ai/supervisor.js +50 -515
  30. package/src/services/ai/validation.js +250 -0
  31. package/src/services/hqx-server-events.js +110 -0
  32. package/src/services/hqx-server-handlers.js +217 -0
  33. package/src/services/hqx-server-latency.js +136 -0
  34. package/src/services/hqx-server.js +51 -403
  35. package/src/services/position-constants.js +28 -0
  36. package/src/services/position-exit-logic.js +174 -0
  37. package/src/services/position-manager.js +90 -629
  38. package/src/services/position-momentum.js +206 -0
  39. package/src/services/projectx/accounts.js +142 -0
  40. package/src/services/projectx/index.js +40 -289
  41. package/src/services/projectx/trading.js +180 -0
  42. package/src/services/rithmic/contracts.js +218 -0
  43. package/src/services/rithmic/handlers.js +2 -208
  44. package/src/services/rithmic/index.js +28 -712
  45. package/src/services/rithmic/latency-tracker.js +182 -0
  46. package/src/services/rithmic/market-data-decoders.js +229 -0
  47. package/src/services/rithmic/market-data.js +1 -278
  48. package/src/services/rithmic/orders-fast.js +246 -0
  49. package/src/services/rithmic/orders.js +1 -251
  50. package/src/services/rithmic/proto-decoders.js +403 -0
  51. package/src/services/rithmic/protobuf.js +7 -443
  52. package/src/services/rithmic/specs.js +146 -0
  53. package/src/services/rithmic/trade-history.js +254 -0
  54. package/src/services/strategy/hft-signal-calc.js +147 -0
  55. package/src/services/strategy/hft-tick.js +33 -133
  56. package/src/services/tradovate/index.js +6 -119
  57. package/src/services/tradovate/orders.js +145 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Rithmic Fast Orders Module
3
+ * @module services/rithmic/orders-fast
4
+ *
5
+ * Ultra-low latency order entry/exit for scalping
6
+ * Target: < 5ms local processing (network latency separate)
7
+ *
8
+ * OPTIMIZATIONS:
9
+ * - Pre-allocated order template objects
10
+ * - Fast orderTag generation (no Date.now in hot path)
11
+ * - Direct proto encoding with cached types
12
+ * - Minimal object creation
13
+ */
14
+
15
+ const { REQ } = require('./constants');
16
+ const { proto } = require('./protobuf');
17
+ const { LatencyTracker } = require('./latency-tracker');
18
+ const { performance } = require('perf_hooks');
19
+
20
+ // Debug mode - use no-op function when disabled for zero overhead
21
+ const DEBUG = process.env.HQX_DEBUG === '1';
22
+ const debug = DEBUG ? (...args) => console.log('[Rithmic:Orders]', ...args) : () => {};
23
+
24
+ // ==================== FAST ORDER TAG ====================
25
+ // Pre-generate prefix once at module load (not per-order)
26
+ const ORDER_TAG_PREFIX = `HQX${process.pid}-`;
27
+ let orderIdCounter = 0;
28
+
29
+ /**
30
+ * Ultra-fast order tag generation
31
+ * Avoids Date.now() and string interpolation in hot path
32
+ * @returns {string}
33
+ */
34
+ const generateOrderTag = () => ORDER_TAG_PREFIX + (++orderIdCounter);
35
+
36
+ // ==================== PRE-ALLOCATED ORDER TEMPLATES ====================
37
+
38
+ /**
39
+ * Order object pool for zero-allocation hot path
40
+ */
41
+ const OrderPool = {
42
+ // Pre-allocated order template
43
+ _template: {
44
+ templateId: REQ.NEW_ORDER,
45
+ userMsg: [''],
46
+ userTag: '',
47
+ fcmId: '',
48
+ ibId: '',
49
+ accountId: '',
50
+ symbol: '',
51
+ exchange: 'CME',
52
+ quantity: 0,
53
+ transactionType: 1,
54
+ duration: 1,
55
+ priceType: 2, // priceType 2 = MARKET order
56
+ manualOrAuto: 2,
57
+ tradeRoute: '',
58
+ },
59
+
60
+ /**
61
+ * Get order object with values filled in
62
+ * @param {string} orderTag
63
+ * @param {Object} loginInfo - { fcmId, ibId }
64
+ * @param {Object} orderData - { accountId, symbol, exchange, size, side, tradeRoute }
65
+ */
66
+ fill(orderTag, loginInfo, orderData) {
67
+ const o = this._template;
68
+ o.userMsg[0] = orderTag;
69
+ o.userTag = orderTag;
70
+ o.fcmId = loginInfo.fcmId;
71
+ o.ibId = loginInfo.ibId;
72
+ o.accountId = orderData.accountId;
73
+ o.symbol = orderData.symbol;
74
+ o.exchange = orderData.exchange || 'CME';
75
+ o.quantity = orderData.size;
76
+ o.transactionType = orderData.side === 0 ? 1 : 2;
77
+ o.tradeRoute = orderData.tradeRoute || '';
78
+ return o;
79
+ }
80
+ };
81
+
82
+ /**
83
+ * Get effective login info for account
84
+ * @param {RithmicService} service
85
+ * @param {string} accountId
86
+ * @returns {{ fcmId: string, ibId: string }}
87
+ */
88
+ function getEffectiveLoginInfo(service, accountId) {
89
+ const account = service.accounts?.find(a =>
90
+ a.accountId === accountId || a.rithmicAccountId === accountId
91
+ );
92
+ return {
93
+ fcmId: account?.fcmId || service.loginInfo.fcmId,
94
+ ibId: account?.ibId || service.loginInfo.ibId,
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Send order buffer via optimized path
100
+ * @param {Object} conn - Order connection
101
+ * @param {Buffer} buffer
102
+ */
103
+ function sendOrderBuffer(conn, buffer) {
104
+ const sent = conn.ultraSend
105
+ ? conn.ultraSend(buffer)
106
+ : (conn.fastSend(buffer), true);
107
+
108
+ if (!sent) {
109
+ conn.fastSend(buffer);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Ultra-fast market order entry - HOT PATH
115
+ * NO SL/TP, NO await confirmation, fire-and-forget
116
+ *
117
+ * @param {RithmicService} service
118
+ * @param {Object} orderData - { accountId, symbol, exchange, size, side }
119
+ * @returns {{ success: boolean, orderTag: string, entryTime: number, latencyMs: number }}
120
+ */
121
+ const fastEntry = (service, orderData) => {
122
+ const startTime = performance.now();
123
+ const orderTag = generateOrderTag();
124
+ const entryTime = Date.now();
125
+
126
+ if (!service.orderConn?.isConnected || !service.loginInfo) {
127
+ return {
128
+ success: false,
129
+ error: 'Not connected',
130
+ orderTag,
131
+ entryTime,
132
+ latencyMs: performance.now() - startTime,
133
+ };
134
+ }
135
+
136
+ try {
137
+ const effectiveLoginInfo = getEffectiveLoginInfo(service, orderData.accountId);
138
+
139
+ const exchange = orderData.exchange || 'CME';
140
+ const tradeRoute = service.getTradeRoute?.(exchange);
141
+ if (!tradeRoute) {
142
+ return {
143
+ success: false,
144
+ error: `No trade route for exchange ${exchange}`,
145
+ orderTag,
146
+ entryTime,
147
+ latencyMs: performance.now() - startTime,
148
+ };
149
+ }
150
+
151
+ const orderWithRoute = { ...orderData, tradeRoute };
152
+ const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderWithRoute);
153
+
154
+ debug('ORDER Sending:', orderTag, orderData.side === 0 ? 'BUY' : 'SELL', orderData.size, 'x', orderData.symbol);
155
+
156
+ const buffer = proto.fastEncode('RequestNewOrder', order);
157
+ sendOrderBuffer(service.orderConn, buffer);
158
+
159
+ debug('ORDER Sent to Rithmic:', orderTag, 'buffer:', buffer.length, 'bytes');
160
+
161
+ LatencyTracker.recordEntry(orderTag, entryTime);
162
+
163
+ return {
164
+ success: true,
165
+ orderTag,
166
+ entryTime,
167
+ latencyMs: performance.now() - startTime,
168
+ };
169
+ } catch (error) {
170
+ return {
171
+ success: false,
172
+ error: error.message,
173
+ orderTag,
174
+ entryTime,
175
+ latencyMs: performance.now() - startTime,
176
+ };
177
+ }
178
+ };
179
+
180
+ /**
181
+ * Ultra-fast market exit - for position closing
182
+ *
183
+ * @param {RithmicService} service
184
+ * @param {Object} orderData - { accountId, symbol, exchange, size, side }
185
+ * @returns {{ success: boolean, orderTag: string, exitTime: number, latencyMs: number }}
186
+ */
187
+ const fastExit = (service, orderData) => {
188
+ const startTime = performance.now();
189
+ const orderTag = generateOrderTag();
190
+ const exitTime = Date.now();
191
+
192
+ if (!service.orderConn?.isConnected || !service.loginInfo) {
193
+ return {
194
+ success: false,
195
+ error: 'Not connected',
196
+ orderTag,
197
+ exitTime,
198
+ latencyMs: performance.now() - startTime,
199
+ };
200
+ }
201
+
202
+ try {
203
+ const effectiveLoginInfo = getEffectiveLoginInfo(service, orderData.accountId);
204
+
205
+ const exchange = orderData.exchange || 'CME';
206
+ const tradeRoute = service.getTradeRoute?.(exchange);
207
+ if (!tradeRoute) {
208
+ return {
209
+ success: false,
210
+ error: `No trade route for exchange ${exchange}`,
211
+ orderTag,
212
+ exitTime,
213
+ latencyMs: performance.now() - startTime,
214
+ };
215
+ }
216
+
217
+ const orderWithRoute = { ...orderData, tradeRoute };
218
+ const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderWithRoute);
219
+
220
+ const buffer = proto.fastEncode('RequestNewOrder', order);
221
+ sendOrderBuffer(service.orderConn, buffer);
222
+
223
+ return {
224
+ success: true,
225
+ orderTag,
226
+ exitTime,
227
+ latencyMs: performance.now() - startTime,
228
+ };
229
+ } catch (error) {
230
+ return {
231
+ success: false,
232
+ error: error.message,
233
+ orderTag,
234
+ exitTime,
235
+ latencyMs: performance.now() - startTime,
236
+ };
237
+ }
238
+ };
239
+
240
+ module.exports = {
241
+ generateOrderTag,
242
+ OrderPool,
243
+ getEffectiveLoginInfo,
244
+ fastEntry,
245
+ fastExit,
246
+ };
@@ -1,264 +1,14 @@
1
1
  /**
2
2
  * Rithmic Orders Module
3
3
  * Order placement, cancellation, and history
4
- *
5
- * FAST SCALPING: fastEntry() and fastExit() for ultra-low latency execution
6
- * Target: < 5ms local processing (network latency separate)
7
- *
8
- * OPTIMIZATIONS:
9
- * - Pre-allocated order template objects
10
- * - Fast orderTag generation (no Date.now in hot path)
11
- * - Direct proto encoding with cached types
12
- * - Minimal object creation
13
4
  */
14
5
 
15
6
  const { REQ } = require('./constants');
16
- const { proto } = require('./protobuf');
17
- const { LatencyTracker } = require('./handlers');
18
- const { performance } = require('perf_hooks');
19
7
  const { logger } = require('../../utils/logger');
8
+ const { fastEntry, fastExit, getEffectiveLoginInfo } = require('./orders-fast');
20
9
 
21
10
  const log = logger.scope('RithmicOrders');
22
11
 
23
- // Debug mode - use no-op function when disabled for zero overhead
24
- const DEBUG = process.env.HQX_DEBUG === '1';
25
- const debug = DEBUG ? (...args) => console.log('[Rithmic:Orders]', ...args) : () => {};
26
-
27
- // ==================== FAST ORDER TAG ====================
28
- // Pre-generate prefix once at module load (not per-order)
29
- const ORDER_TAG_PREFIX = `HQX${process.pid}-`;
30
- let orderIdCounter = 0;
31
-
32
- /**
33
- * Ultra-fast order tag generation
34
- * Avoids Date.now() and string interpolation in hot path
35
- * @returns {string}
36
- */
37
- const generateOrderTag = () => ORDER_TAG_PREFIX + (++orderIdCounter);
38
-
39
- // ==================== PRE-ALLOCATED ORDER TEMPLATES ====================
40
- // Reusable order object to minimize GC pressure
41
-
42
- /**
43
- * Order object pool for zero-allocation hot path
44
- */
45
- const OrderPool = {
46
- // Pre-allocated order template
47
- _template: {
48
- templateId: REQ.NEW_ORDER,
49
- userMsg: [''],
50
- userTag: '', // Our order tag - returned in RithmicOrderNotification
51
- fcmId: '',
52
- ibId: '',
53
- accountId: '',
54
- symbol: '',
55
- exchange: 'CME',
56
- quantity: 0,
57
- transactionType: 1,
58
- duration: 1,
59
- priceType: 2, // priceType 2 = MARKET order
60
- manualOrAuto: 2,
61
- tradeRoute: '', // Required by Rithmic API - fetched from RequestTradeRoutes
62
- },
63
-
64
- /**
65
- * Get order object with values filled in
66
- * Reuses same object to avoid allocation
67
- * @param {string} orderTag - Unique order tag
68
- * @param {Object} loginInfo - { fcmId, ibId }
69
- * @param {Object} orderData - { accountId, symbol, exchange, size, side, tradeRoute }
70
- */
71
- fill(orderTag, loginInfo, orderData) {
72
- const o = this._template;
73
- o.userMsg[0] = orderTag;
74
- o.userTag = orderTag; // Set userTag for notification tracking
75
- o.fcmId = loginInfo.fcmId;
76
- o.ibId = loginInfo.ibId;
77
- o.accountId = orderData.accountId;
78
- o.symbol = orderData.symbol;
79
- o.exchange = orderData.exchange || 'CME';
80
- o.quantity = orderData.size;
81
- o.transactionType = orderData.side === 0 ? 1 : 2;
82
- o.tradeRoute = orderData.tradeRoute || ''; // From API via service.getTradeRoute()
83
- return o;
84
- }
85
- };
86
-
87
- /**
88
- * Ultra-fast market order entry - HOT PATH
89
- * NO SL/TP, NO await confirmation, fire-and-forget
90
- * Target latency: < 5ms local processing
91
- *
92
- * OPTIMIZATIONS:
93
- * - Reuses pre-allocated order object
94
- * - Fast orderTag (no Date.now)
95
- * - Uses fastEncode for cached protobuf type
96
- * - Minimal branching
97
- *
98
- * @param {RithmicService} service - The Rithmic service instance
99
- * @param {Object} orderData - { accountId, symbol, exchange, size, side }
100
- * @returns {{ success: boolean, orderTag: string, entryTime: number, latencyMs: number }}
101
- */
102
- const fastEntry = (service, orderData) => {
103
- const startTime = performance.now();
104
- const orderTag = generateOrderTag();
105
- const entryTime = Date.now();
106
-
107
- // Fast connection check
108
- if (!service.orderConn?.isConnected || !service.loginInfo) {
109
- return {
110
- success: false,
111
- error: 'Not connected',
112
- orderTag,
113
- entryTime,
114
- latencyMs: performance.now() - startTime,
115
- };
116
- }
117
-
118
- try {
119
- // FIXED: Use account-specific fcmId/ibId if available (some prop firms have different IDs per account)
120
- const account = service.accounts?.find(a =>
121
- a.accountId === orderData.accountId || a.rithmicAccountId === orderData.accountId
122
- );
123
- const effectiveLoginInfo = {
124
- fcmId: account?.fcmId || service.loginInfo.fcmId,
125
- ibId: account?.ibId || service.loginInfo.ibId,
126
- };
127
-
128
- // Get trade route from API (required by Rithmic)
129
- const exchange = orderData.exchange || 'CME';
130
- const tradeRoute = service.getTradeRoute?.(exchange);
131
- if (!tradeRoute) {
132
- return {
133
- success: false,
134
- error: `No trade route for exchange ${exchange}`,
135
- orderTag,
136
- entryTime,
137
- latencyMs: performance.now() - startTime,
138
- };
139
- }
140
-
141
- // OPTIMIZED: Use pre-allocated order object
142
- const orderWithRoute = { ...orderData, tradeRoute };
143
- const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderWithRoute);
144
-
145
- // Debug only - UI handles display via events
146
- debug('ORDER Sending:', orderTag, orderData.side === 0 ? 'BUY' : 'SELL', orderData.size, 'x', orderData.symbol, 'acct:', orderData.accountId, 'route:', tradeRoute);
147
-
148
- // OPTIMIZED: Use fastEncode with cached type
149
- const buffer = proto.fastEncode('RequestNewOrder', order);
150
-
151
- // ULTRA-OPTIMIZED: Try direct socket write first, fallback to fastSend
152
- const sent = service.orderConn.ultraSend
153
- ? service.orderConn.ultraSend(buffer)
154
- : (service.orderConn.fastSend(buffer), true);
155
-
156
- if (!sent) {
157
- service.orderConn.fastSend(buffer);
158
- }
159
-
160
- debug('ORDER Sent to Rithmic:', orderTag, 'buffer:', buffer.length, 'bytes');
161
-
162
- // Track for round-trip latency measurement
163
- LatencyTracker.recordEntry(orderTag, entryTime);
164
-
165
- return {
166
- success: true,
167
- orderTag,
168
- entryTime,
169
- latencyMs: performance.now() - startTime,
170
- };
171
- } catch (error) {
172
- return {
173
- success: false,
174
- error: error.message,
175
- orderTag,
176
- entryTime,
177
- latencyMs: performance.now() - startTime,
178
- };
179
- }
180
- };
181
-
182
- /**
183
- * Ultra-fast market exit - for position closing
184
- * Fire-and-forget like fastEntry
185
- * Same optimizations as fastEntry
186
- *
187
- * @param {RithmicService} service - The Rithmic service instance
188
- * @param {Object} orderData - { accountId, symbol, exchange, size, side }
189
- * @returns {{ success: boolean, orderTag: string, exitTime: number, latencyMs: number }}
190
- */
191
- const fastExit = (service, orderData) => {
192
- const startTime = performance.now();
193
- const orderTag = generateOrderTag();
194
- const exitTime = Date.now();
195
-
196
- if (!service.orderConn?.isConnected || !service.loginInfo) {
197
- return {
198
- success: false,
199
- error: 'Not connected',
200
- orderTag,
201
- exitTime,
202
- latencyMs: performance.now() - startTime,
203
- };
204
- }
205
-
206
- try {
207
- // FIXED: Use account-specific fcmId/ibId if available
208
- const account = service.accounts?.find(a =>
209
- a.accountId === orderData.accountId || a.rithmicAccountId === orderData.accountId
210
- );
211
- const effectiveLoginInfo = {
212
- fcmId: account?.fcmId || service.loginInfo.fcmId,
213
- ibId: account?.ibId || service.loginInfo.ibId,
214
- };
215
-
216
- // Get trade route from API (required by Rithmic)
217
- const exchange = orderData.exchange || 'CME';
218
- const tradeRoute = service.getTradeRoute?.(exchange);
219
- if (!tradeRoute) {
220
- return {
221
- success: false,
222
- error: `No trade route for exchange ${exchange}`,
223
- orderTag,
224
- exitTime,
225
- latencyMs: performance.now() - startTime,
226
- };
227
- }
228
-
229
- // OPTIMIZED: Use pre-allocated order object
230
- const orderWithRoute = { ...orderData, tradeRoute };
231
- const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderWithRoute);
232
-
233
- // OPTIMIZED: Use fastEncode with cached type
234
- const buffer = proto.fastEncode('RequestNewOrder', order);
235
-
236
- // ULTRA-OPTIMIZED: Try direct socket write first, fallback to fastSend
237
- const sent = service.orderConn.ultraSend
238
- ? service.orderConn.ultraSend(buffer)
239
- : (service.orderConn.fastSend(buffer), true);
240
-
241
- if (!sent) {
242
- service.orderConn.fastSend(buffer);
243
- }
244
-
245
- return {
246
- success: true,
247
- orderTag,
248
- exitTime,
249
- latencyMs: performance.now() - startTime,
250
- };
251
- } catch (error) {
252
- return {
253
- success: false,
254
- error: error.message,
255
- orderTag,
256
- exitTime,
257
- latencyMs: performance.now() - startTime,
258
- };
259
- }
260
- };
261
-
262
12
  /**
263
13
  * Place order via ORDER_PLANT
264
14
  * @param {RithmicService} service - The Rithmic service instance