hedgequantx 2.9.90 → 2.9.92
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/lib/data.jsc
CHANGED
|
Binary file
|
package/dist/lib/m/hqx-2b.js
CHANGED
|
@@ -687,8 +687,8 @@ var require_core = __commonJS({
|
|
|
687
687
|
const bars = this.barHistory.get(contractId) || [];
|
|
688
688
|
const zones = this.liquidityZones.get(contractId) || [];
|
|
689
689
|
const swings = this.swingPoints.get(contractId) || [];
|
|
690
|
-
if (bars.length <
|
|
691
|
-
return { ready: false, message: `Collecting data... ${bars.length}/
|
|
690
|
+
if (bars.length < 5) {
|
|
691
|
+
return { ready: false, message: `Collecting data... ${bars.length}/5 bars` };
|
|
692
692
|
}
|
|
693
693
|
const sortedZones = zones.map((z) => ({ zone: z, distance: Math.abs(currentPrice - z.getLevel()) })).sort((a, b) => a.distance - b.distance);
|
|
694
694
|
const nearestResistance = sortedZones.find((z) => z.zone.type === ZoneType2.RESISTANCE);
|
|
Binary file
|
package/package.json
CHANGED
package/src/lib/data.js
CHANGED
|
@@ -171,11 +171,11 @@ class MarketDataFeed extends EventEmitter {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
|
-
* Get historical bars from HISTORY_PLANT
|
|
175
|
-
* @param {string} symbol - Symbol (e.g., '
|
|
174
|
+
* Get historical tick bars from HISTORY_PLANT
|
|
175
|
+
* @param {string} symbol - Symbol (e.g., 'MNQH6')
|
|
176
176
|
* @param {string} exchange - Exchange (default: 'CME')
|
|
177
177
|
* @param {number} barCount - Number of bars to fetch (default: 30)
|
|
178
|
-
* @returns {Promise<Array>} Array of bar objects {timestamp, open, high, low, close, volume}
|
|
178
|
+
* @returns {Promise<Array>} Array of tick bar objects {timestamp, open, high, low, close, volume}
|
|
179
179
|
*/
|
|
180
180
|
async getHistoricalBars(symbol, exchange = 'CME', barCount = 30) {
|
|
181
181
|
if (!this.credentials) {
|
|
@@ -194,36 +194,48 @@ class MarketDataFeed extends EventEmitter {
|
|
|
194
194
|
|
|
195
195
|
return new Promise((resolve, reject) => {
|
|
196
196
|
const bars = [];
|
|
197
|
+
let isComplete = false;
|
|
198
|
+
|
|
197
199
|
const timeout = setTimeout(() => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
if (!isComplete) {
|
|
201
|
+
historyConn.disconnect();
|
|
202
|
+
// Return what we have even on timeout
|
|
200
203
|
resolve(bars);
|
|
201
|
-
} else {
|
|
202
|
-
reject(new Error('History request timeout'));
|
|
203
204
|
}
|
|
204
|
-
},
|
|
205
|
+
}, 15000);
|
|
205
206
|
|
|
206
|
-
// Listen for bar data
|
|
207
|
+
// Listen for bar data (template 207)
|
|
207
208
|
historyConn.on('message', (msg) => {
|
|
208
209
|
if (msg.templateId === RES.TICK_BAR_REPLAY) {
|
|
209
210
|
try {
|
|
210
211
|
const data = proto.decode('ResponseTickBarReplay', msg.data);
|
|
211
212
|
const barObj = data.toJSON ? data.toJSON() : data;
|
|
212
213
|
|
|
213
|
-
|
|
214
|
+
// Check for error response
|
|
215
|
+
if (barObj.rpCode && barObj.rpCode[0] !== '0') {
|
|
216
|
+
clearTimeout(timeout);
|
|
217
|
+
isComplete = true;
|
|
218
|
+
historyConn.disconnect();
|
|
219
|
+
reject(new Error(`History request failed: ${barObj.rpCode.join(' - ')}`));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Add bar if it has price data (OHLCV format)
|
|
224
|
+
if (barObj.closePrice !== undefined) {
|
|
214
225
|
bars.push({
|
|
215
|
-
timestamp: barObj.
|
|
216
|
-
open: Number(barObj.openPrice),
|
|
217
|
-
high: Number(barObj.highPrice),
|
|
218
|
-
low: Number(barObj.lowPrice),
|
|
226
|
+
timestamp: barObj.ssboe ? barObj.ssboe * 1000 : Date.now(),
|
|
227
|
+
open: Number(barObj.openPrice) || Number(barObj.closePrice),
|
|
228
|
+
high: Number(barObj.highPrice) || Number(barObj.closePrice),
|
|
229
|
+
low: Number(barObj.lowPrice) || Number(barObj.closePrice),
|
|
219
230
|
close: Number(barObj.closePrice),
|
|
220
|
-
volume: Number(barObj.volume) ||
|
|
231
|
+
volume: Number(barObj.volume) || 1,
|
|
221
232
|
});
|
|
222
233
|
}
|
|
223
234
|
|
|
224
|
-
// Check if this is the
|
|
225
|
-
if (barObj.rpCode && barObj.rpCode
|
|
235
|
+
// Check if this is the final response (rpCode = ['0'])
|
|
236
|
+
if (barObj.rpCode && barObj.rpCode[0] === '0' && barObj.closePrice === undefined) {
|
|
226
237
|
clearTimeout(timeout);
|
|
238
|
+
isComplete = true;
|
|
227
239
|
historyConn.disconnect();
|
|
228
240
|
resolve(bars);
|
|
229
241
|
}
|
|
@@ -235,17 +247,25 @@ class MarketDataFeed extends EventEmitter {
|
|
|
235
247
|
|
|
236
248
|
// Login to HISTORY_PLANT
|
|
237
249
|
historyConn.once('loggedIn', () => {
|
|
238
|
-
// Request tick bar replay
|
|
250
|
+
// Request tick bar replay - limited count, most recent bars
|
|
251
|
+
// startIndex/finishIndex are required, but userMaxCount + direction=LAST
|
|
252
|
+
// will return only the most recent barCount bars
|
|
253
|
+
const now = Math.floor(Date.now() / 1000);
|
|
254
|
+
const startTime = now - (24 * 60 * 60); // 24 hours ago (wide range)
|
|
255
|
+
|
|
239
256
|
historyConn.send('RequestTickBarReplay', {
|
|
240
|
-
templateId: REQ.TICK_BAR_REPLAY,
|
|
257
|
+
templateId: REQ.TICK_BAR_REPLAY, // 206
|
|
258
|
+
userMsg: ['hqx-history'],
|
|
241
259
|
symbol: symbol,
|
|
242
260
|
exchange: exchange,
|
|
243
|
-
barType: 1,
|
|
244
|
-
barSubType: 1,
|
|
245
|
-
barTypeSpecifier: '1',
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
261
|
+
barType: 1, // TICK_BAR
|
|
262
|
+
barSubType: 1, // REGULAR
|
|
263
|
+
barTypeSpecifier: '1', // 1 tick per bar
|
|
264
|
+
startIndex: startTime, // Required by Rithmic
|
|
265
|
+
finishIndex: now, // Required by Rithmic
|
|
266
|
+
userMaxCount: barCount, // Limit to barCount bars
|
|
267
|
+
direction: 2, // LAST (most recent bars first)
|
|
268
|
+
timeOrder: 1, // FORWARDS (return in chronological order)
|
|
249
269
|
});
|
|
250
270
|
});
|
|
251
271
|
|
|
@@ -412,19 +412,20 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
412
412
|
await marketFeed.subscribe(symbolCode, contract.exchange || 'CME');
|
|
413
413
|
|
|
414
414
|
// Preload historical bars for HQX-2B strategy only (bar-based strategy)
|
|
415
|
+
// Note: HISTORY_PLANT may not be available on all accounts (e.g., paper trading)
|
|
415
416
|
if (strategyId === 'hqx-2b' && strategy.preloadBars) {
|
|
416
|
-
ui.addLog('system', 'Loading historical bars...');
|
|
417
417
|
try {
|
|
418
|
+
ui.addLog('system', 'Loading historical bars...');
|
|
418
419
|
const historicalBars = await marketFeed.getHistoricalBars(symbolCode, contract.exchange || 'CME', 30);
|
|
419
420
|
if (historicalBars && historicalBars.length > 0) {
|
|
420
421
|
strategy.preloadBars(contractId, historicalBars);
|
|
421
|
-
ui.addLog('system', `Loaded ${historicalBars.length} bars -
|
|
422
|
+
ui.addLog('system', `Loaded ${historicalBars.length} bars - ready!`);
|
|
422
423
|
} else {
|
|
423
|
-
ui.addLog('system', 'No historical
|
|
424
|
+
ui.addLog('system', 'No historical data - warming up with live bars...');
|
|
424
425
|
}
|
|
425
426
|
} catch (histErr) {
|
|
426
|
-
|
|
427
|
-
ui.addLog('system', '
|
|
427
|
+
// HISTORY_PLANT not available (common on paper accounts)
|
|
428
|
+
ui.addLog('system', 'Historical data not available - warming up with live bars...');
|
|
428
429
|
}
|
|
429
430
|
}
|
|
430
431
|
} catch (e) {
|
|
@@ -60,7 +60,7 @@ const REQ = {
|
|
|
60
60
|
MARKET_DATA: 100,
|
|
61
61
|
PRODUCT_CODES: 111,
|
|
62
62
|
FRONT_MONTH_CONTRACT: 113,
|
|
63
|
-
TICK_BAR_REPLAY:
|
|
63
|
+
TICK_BAR_REPLAY: 206, // History plant - request tick bar replay
|
|
64
64
|
LOGIN_INFO: 300,
|
|
65
65
|
ACCOUNT_LIST: 302,
|
|
66
66
|
ACCOUNT_RMS: 304,
|
|
@@ -89,7 +89,7 @@ const RES = {
|
|
|
89
89
|
MARKET_DATA: 101,
|
|
90
90
|
PRODUCT_CODES: 112,
|
|
91
91
|
FRONT_MONTH_CONTRACT: 114,
|
|
92
|
-
TICK_BAR_REPLAY:
|
|
92
|
+
TICK_BAR_REPLAY: 207, // History plant - tick bar replay response
|
|
93
93
|
LOGIN_INFO: 301,
|
|
94
94
|
ACCOUNT_LIST: 303,
|
|
95
95
|
ACCOUNT_RMS: 305,
|
|
@@ -42,7 +42,7 @@ 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 CHICAGO endpoint
|
|
45
|
+
// Rithmic Paper Trading - uses CHICAGO endpoint
|
|
46
46
|
rithmic_paper: { name: 'Rithmic Paper Trading', systemName: RITHMIC_SYSTEMS.PAPER, gateway: RITHMIC_ENDPOINTS.CHICAGO },
|
|
47
47
|
};
|
|
48
48
|
|