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
@@ -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 < 20) {
691
- return { ready: false, message: `Collecting data... ${bars.length}/20 bars` };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.9.90",
3
+ "version": "2.9.92",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
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., 'MNQH5')
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
- historyConn.disconnect();
199
- if (bars.length > 0) {
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
- }, 10000);
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
- if (barObj.openPrice !== undefined) {
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.dataBarSsboe ? barObj.dataBarSsboe[0] * 1000 : Date.now(),
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) || 0,
231
+ volume: Number(barObj.volume) || 1,
221
232
  });
222
233
  }
223
234
 
224
- // Check if this is the last bar (rpCode contains "end" or empty)
225
- if (barObj.rpCode && barObj.rpCode.includes('0')) {
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 (1-minute bars)
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, // TICK_BAR
244
- barSubType: 1, // REGULAR
245
- barTypeSpecifier: '1', // 1-minute
246
- userMaxCount: barCount,
247
- direction: 2, // LAST (most recent)
248
- timeOrder: 2, // BACKWARDS
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 - strategy ready!`);
422
+ ui.addLog('system', `Loaded ${historicalBars.length} bars - ready!`);
422
423
  } else {
423
- ui.addLog('system', 'No historical bars - collecting live data...');
424
+ ui.addLog('system', 'No historical data - warming up with live bars...');
424
425
  }
425
426
  } catch (histErr) {
426
- ui.addLog('debug', `Historical data unavailable: ${histErr.message}`);
427
- ui.addLog('system', 'Collecting live data...');
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: 200, // History plant - request bar data
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: 201, // History plant - bar data response
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 (PAPER endpoint deprecated)
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