hedgequantx 2.9.53 → 2.9.55

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.9.53",
3
+ "version": "2.9.55",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
package/src/lib/data.js CHANGED
@@ -209,30 +209,36 @@ class MarketDataFeed extends EventEmitter {
209
209
  _handleLastTrade(data) {
210
210
  try {
211
211
  const trade = proto.decode('LastTrade', data);
212
+ const tradeObj = trade.toJSON ? trade.toJSON() : trade;
212
213
 
213
- // Debug: log first trade to see structure
214
- if (!this._loggedFirstTrade) {
215
- this._loggedFirstTrade = true;
216
- this.emit('debug', `Trade fields: ${Object.keys(trade).join(', ')}`);
217
- this.emit('debug', `Trade price: ${trade.tradePrice || trade.trade_price || trade.price}`);
218
- }
214
+ // protobufjs converts to camelCase and enums to strings
215
+ const price = tradeObj.tradePrice;
216
+ const size = Number(tradeObj.tradeSize) || 1;
217
+ const volume = Number(tradeObj.volume) || size;
218
+
219
+ // aggressor can be 1, 2, "BUY", "SELL"
220
+ const agg = tradeObj.aggressor;
221
+ const side = (agg === 1 || agg === 'BUY') ? 'buy' :
222
+ (agg === 2 || agg === 'SELL') ? 'sell' : 'unknown';
223
+
224
+ if (price === undefined || price === null) return;
219
225
 
220
226
  const tick = {
221
227
  type: 'trade',
222
- symbol: trade.symbol,
223
- exchange: trade.exchange,
224
- price: trade.tradePrice || trade.trade_price || trade.price,
225
- size: trade.tradeSize || trade.trade_size || trade.size || 1,
226
- volume: trade.volume || 1,
227
- side: trade.aggressor === 1 ? 'buy' : trade.aggressor === 2 ? 'sell' : 'unknown',
228
+ symbol: tradeObj.symbol,
229
+ exchange: tradeObj.exchange,
230
+ price: Number(price),
231
+ size: size,
232
+ volume: volume,
233
+ side: side,
228
234
  timestamp: Date.now(),
229
- ssboe: trade.ssboe,
230
- usecs: trade.usecs,
235
+ ssboe: tradeObj.ssboe,
236
+ usecs: tradeObj.usecs,
231
237
  };
232
238
 
233
239
  this.emit('tick', tick);
234
240
  } catch (e) {
235
- // Ignore decode errors
241
+ // Silent - don't spam errors
236
242
  }
237
243
  }
238
244
 
@@ -242,19 +248,31 @@ class MarketDataFeed extends EventEmitter {
242
248
  _handleBBO(data) {
243
249
  try {
244
250
  const bbo = proto.decode('BestBidOffer', data);
251
+ const bboObj = bbo.toJSON ? bbo.toJSON() : bbo;
252
+
253
+ // protobufjs converts to camelCase
254
+ const bid = bboObj.bidPrice;
255
+ const ask = bboObj.askPrice;
256
+ const bidSize = Number(bboObj.bidSize) || 0;
257
+ const askSize = Number(bboObj.askSize) || 0;
258
+
259
+ // Calculate mid price
260
+ const price = (bid && ask) ? (Number(bid) + Number(ask)) / 2 : (bid || ask || null);
261
+
262
+ if (price === null) return;
245
263
 
246
264
  const tick = {
247
265
  type: 'quote',
248
- symbol: bbo.symbol,
249
- exchange: bbo.exchange,
250
- bid: bbo.bidPrice,
251
- bidSize: bbo.bidSize,
252
- ask: bbo.askPrice,
253
- askSize: bbo.askSize,
254
- price: bbo.bidPrice && bbo.askPrice ? (bbo.bidPrice + bbo.askPrice) / 2 : null,
266
+ symbol: bboObj.symbol,
267
+ exchange: bboObj.exchange,
268
+ bid: bid ? Number(bid) : null,
269
+ bidSize: bidSize,
270
+ ask: ask ? Number(ask) : null,
271
+ askSize: askSize,
272
+ price: Number(price),
255
273
  timestamp: Date.now(),
256
- ssboe: bbo.ssboe,
257
- usecs: bbo.usecs,
274
+ ssboe: bboObj.ssboe,
275
+ usecs: bboObj.usecs,
258
276
  };
259
277
 
260
278
  this.emit('tick', tick);
@@ -234,12 +234,12 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
234
234
  aiContext.recentTicks.push(tick);
235
235
  if (aiContext.recentTicks.length > aiContext.maxTicks) aiContext.recentTicks.shift();
236
236
 
237
- const price = tick.price || tick.tradePrice;
238
- const bid = tick.bid || tick.bidPrice;
239
- const ask = tick.ask || tick.askPrice;
240
- const volume = tick.volume || tick.size || 1;
237
+ const price = Number(tick.price) || Number(tick.tradePrice) || null;
238
+ const bid = Number(tick.bid) || Number(tick.bidPrice) || null;
239
+ const ask = Number(tick.ask) || Number(tick.askPrice) || null;
240
+ const volume = Number(tick.volume) || Number(tick.size) || 1;
241
241
 
242
- // Track buy/sell volume
242
+ // Track buy/sell volume (ensure numeric addition)
243
243
  if (tick.side === 'buy' || tick.aggressor === 1) buyVolume += volume;
244
244
  else if (tick.side === 'sell' || tick.aggressor === 2) sellVolume += volume;
245
245
  else if (price && lastPrice) {