hedgequantx 2.9.29 → 2.9.31
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
package/src/config/propfirms.js
CHANGED
|
@@ -15,14 +15,6 @@ const PROPFIRMS = {
|
|
|
15
15
|
rithmicSystem: 'Apex',
|
|
16
16
|
wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443',
|
|
17
17
|
},
|
|
18
|
-
rithmic_paper: {
|
|
19
|
-
id: 'rithmic-paper',
|
|
20
|
-
name: 'Rithmic Paper Trading',
|
|
21
|
-
displayName: 'Rithmic Paper Trading',
|
|
22
|
-
platform: 'Rithmic',
|
|
23
|
-
rithmicSystem: 'Rithmic Paper Trading',
|
|
24
|
-
wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443',
|
|
25
|
-
},
|
|
26
18
|
topsteptrader: {
|
|
27
19
|
id: 'topsteptrader',
|
|
28
20
|
name: 'TopstepTrader',
|
|
@@ -142,6 +134,14 @@ const PROPFIRMS = {
|
|
|
142
134
|
platform: 'Rithmic',
|
|
143
135
|
rithmicSystem: 'tradesea',
|
|
144
136
|
wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443'
|
|
137
|
+
},
|
|
138
|
+
rithmic_paper: {
|
|
139
|
+
id: 'rithmic-paper',
|
|
140
|
+
name: 'Rithmic Paper Trading',
|
|
141
|
+
displayName: 'Rithmic Paper Trading',
|
|
142
|
+
platform: 'Rithmic',
|
|
143
|
+
rithmicSystem: 'Rithmic Paper Trading',
|
|
144
|
+
wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443'
|
|
145
145
|
}
|
|
146
146
|
};
|
|
147
147
|
|
|
@@ -154,15 +154,17 @@ const PROPFIRM_CHOICES = Object.entries(PROPFIRMS)
|
|
|
154
154
|
// Apex always first
|
|
155
155
|
if (a.name === 'Apex') return -1;
|
|
156
156
|
if (b.name === 'Apex') return 1;
|
|
157
|
-
// Rithmic Paper Trading
|
|
158
|
-
|
|
159
|
-
if (b.name === 'Rithmic Paper Trading') return 1;
|
|
160
|
-
// 4PropTrader and 10XFutures always last
|
|
161
|
-
const lastItems = ['4PropTrader', '10XFutures'];
|
|
157
|
+
// 4PropTrader, 10XFutures, Rithmic Paper Trading always last
|
|
158
|
+
const lastItems = ['4PropTrader', '10XFutures', 'Rithmic Paper Trading'];
|
|
162
159
|
const aIsLast = lastItems.includes(a.name);
|
|
163
160
|
const bIsLast = lastItems.includes(b.name);
|
|
164
161
|
if (aIsLast && !bIsLast) return 1;
|
|
165
162
|
if (!aIsLast && bIsLast) return -1;
|
|
163
|
+
// If both are last items, order them: 10XFutures, 4PropTrader, Rithmic Paper Trading
|
|
164
|
+
if (aIsLast && bIsLast) {
|
|
165
|
+
const order = ['10XFutures', '4PropTrader', 'Rithmic Paper Trading'];
|
|
166
|
+
return order.indexOf(a.name) - order.indexOf(b.name);
|
|
167
|
+
}
|
|
166
168
|
// Then alphabetical
|
|
167
169
|
return a.name.localeCompare(b.name);
|
|
168
170
|
});
|
|
@@ -5,9 +5,25 @@
|
|
|
5
5
|
|
|
6
6
|
const WebSocket = require('ws');
|
|
7
7
|
const EventEmitter = require('events');
|
|
8
|
+
const os = require('os');
|
|
8
9
|
const { proto } = require('./protobuf');
|
|
9
10
|
const { REQ, RES, INFRA_TYPE } = require('./constants');
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Get MAC address from network interfaces
|
|
14
|
+
*/
|
|
15
|
+
function getMacAddress() {
|
|
16
|
+
const interfaces = os.networkInterfaces();
|
|
17
|
+
for (const name of Object.keys(interfaces)) {
|
|
18
|
+
for (const iface of interfaces[name]) {
|
|
19
|
+
if (!iface.internal && iface.mac !== '00:00:00:00:00:00') {
|
|
20
|
+
return iface.mac;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return '00:00:00:00:00:00';
|
|
25
|
+
}
|
|
26
|
+
|
|
11
27
|
class RithmicConnection extends EventEmitter {
|
|
12
28
|
constructor() {
|
|
13
29
|
super();
|
|
@@ -108,6 +124,9 @@ class RithmicConnection extends EventEmitter {
|
|
|
108
124
|
appVersion: this.config.appVersion || '1.0.0',
|
|
109
125
|
systemName: this.config.systemName,
|
|
110
126
|
infraType: INFRA_TYPE[infraType],
|
|
127
|
+
macAddr: [getMacAddress()],
|
|
128
|
+
osVersion: os.release(),
|
|
129
|
+
osPlatform: os.platform(),
|
|
111
130
|
});
|
|
112
131
|
}
|
|
113
132
|
|
|
@@ -42,6 +42,8 @@ const PROPFIRM_CONFIGS = {
|
|
|
42
42
|
lucidtrading: { name: 'Lucid Trading', systemName: RITHMIC_SYSTEMS.LUCID_TRADING, gateway: RITHMIC_ENDPOINTS.CHICAGO },
|
|
43
43
|
thrivetrading: { name: 'Thrive Trading', systemName: RITHMIC_SYSTEMS.THRIVE_TRADING, gateway: RITHMIC_ENDPOINTS.CHICAGO },
|
|
44
44
|
legendstrading: { name: 'Legends Trading', systemName: RITHMIC_SYSTEMS.LEGENDS_TRADING, gateway: RITHMIC_ENDPOINTS.CHICAGO },
|
|
45
|
+
// Rithmic Paper Trading - uses dedicated PAPER endpoint
|
|
46
|
+
rithmic_paper: { name: 'Rithmic Paper Trading', systemName: RITHMIC_SYSTEMS.PAPER, gateway: RITHMIC_ENDPOINTS.PAPER },
|
|
45
47
|
};
|
|
46
48
|
|
|
47
49
|
/**
|
|
@@ -331,46 +331,59 @@ class ProtobufHandler {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
/**
|
|
334
|
-
* Encode a message to Buffer
|
|
334
|
+
* Encode a message to Buffer with 4-byte length prefix
|
|
335
335
|
*/
|
|
336
336
|
encode(typeName, data) {
|
|
337
337
|
if (!this.root) throw new Error('Proto not loaded');
|
|
338
338
|
|
|
339
339
|
const Type = this.root.lookupType(typeName);
|
|
340
340
|
const msg = Type.create(data);
|
|
341
|
-
|
|
341
|
+
const serialized = Buffer.from(Type.encode(msg).finish());
|
|
342
|
+
|
|
343
|
+
// Add 4-byte length prefix (big-endian, signed)
|
|
344
|
+
const lengthPrefix = Buffer.alloc(4);
|
|
345
|
+
lengthPrefix.writeInt32BE(serialized.length, 0);
|
|
346
|
+
|
|
347
|
+
return Buffer.concat([lengthPrefix, serialized]);
|
|
342
348
|
}
|
|
343
349
|
|
|
344
350
|
/**
|
|
345
|
-
* Decode a Buffer to object
|
|
351
|
+
* Decode a Buffer to object (skip 4-byte length prefix)
|
|
346
352
|
*/
|
|
347
353
|
decode(typeName, buffer) {
|
|
348
354
|
if (!this.root) throw new Error('Proto not loaded');
|
|
349
355
|
|
|
356
|
+
// Skip 4-byte length prefix if present
|
|
357
|
+
const data = buffer.length > 4 ? buffer.slice(4) : buffer;
|
|
358
|
+
|
|
350
359
|
const Type = this.root.lookupType(typeName);
|
|
351
|
-
return Type.decode(
|
|
360
|
+
return Type.decode(data);
|
|
352
361
|
}
|
|
353
362
|
|
|
354
363
|
/**
|
|
355
364
|
* Get template ID from buffer (manual decode for large field IDs)
|
|
365
|
+
* Skips 4-byte length prefix if present
|
|
356
366
|
*/
|
|
357
367
|
getTemplateId(buffer) {
|
|
358
368
|
const TEMPLATE_ID_FIELD = 154467;
|
|
359
369
|
|
|
370
|
+
// Skip 4-byte length prefix
|
|
371
|
+
const data = buffer.length > 4 ? buffer.slice(4) : buffer;
|
|
372
|
+
|
|
360
373
|
let offset = 0;
|
|
361
|
-
while (offset <
|
|
374
|
+
while (offset < data.length) {
|
|
362
375
|
try {
|
|
363
|
-
const [tag, newOffset] = readVarint(
|
|
376
|
+
const [tag, newOffset] = readVarint(data, offset);
|
|
364
377
|
const fieldNumber = tag >>> 3;
|
|
365
378
|
const wireType = tag & 0x7;
|
|
366
379
|
offset = newOffset;
|
|
367
380
|
|
|
368
381
|
if (fieldNumber === TEMPLATE_ID_FIELD && wireType === 0) {
|
|
369
|
-
const [templateId] = readVarint(
|
|
382
|
+
const [templateId] = readVarint(data, offset);
|
|
370
383
|
return templateId;
|
|
371
384
|
}
|
|
372
385
|
|
|
373
|
-
offset = skipField(
|
|
386
|
+
offset = skipField(data, offset, wireType);
|
|
374
387
|
} catch (e) {
|
|
375
388
|
break;
|
|
376
389
|
}
|
|
@@ -380,7 +393,7 @@ class ProtobufHandler {
|
|
|
380
393
|
if (this.root) {
|
|
381
394
|
try {
|
|
382
395
|
const Base = this.root.lookupType('Base');
|
|
383
|
-
const base = Base.decode(
|
|
396
|
+
const base = Base.decode(data);
|
|
384
397
|
return base.templateId;
|
|
385
398
|
} catch (e) {
|
|
386
399
|
return -1;
|