hedgequantx 2.9.49 → 2.9.50
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 +1 -1
- package/src/lib/data.js +13 -1
- package/src/pages/algo/algo-executor.js +78 -5
package/package.json
CHANGED
package/src/lib/data.js
CHANGED
|
@@ -113,6 +113,7 @@ class MarketDataFeed extends EventEmitter {
|
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
this.subscriptions.add(key);
|
|
116
|
+
this.emit('subscribed', `${symbol}:${exchange}`);
|
|
116
117
|
} catch (e) {
|
|
117
118
|
this.emit('error', e);
|
|
118
119
|
throw e;
|
|
@@ -172,9 +173,17 @@ class MarketDataFeed extends EventEmitter {
|
|
|
172
173
|
_handleMessage(msg) {
|
|
173
174
|
const { templateId, data } = msg;
|
|
174
175
|
|
|
176
|
+
// Debug: log all message template IDs
|
|
177
|
+
if (!this._seenTemplates) this._seenTemplates = new Set();
|
|
178
|
+
if (!this._seenTemplates.has(templateId)) {
|
|
179
|
+
this._seenTemplates.add(templateId);
|
|
180
|
+
this.emit('debug', `New message type: templateId=${templateId}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
175
183
|
switch (templateId) {
|
|
176
184
|
case RES.MARKET_DATA:
|
|
177
185
|
// Subscription confirmed
|
|
186
|
+
this.emit('debug', 'Market data subscription confirmed');
|
|
178
187
|
break;
|
|
179
188
|
|
|
180
189
|
case STREAM.LAST_TRADE:
|
|
@@ -186,7 +195,10 @@ class MarketDataFeed extends EventEmitter {
|
|
|
186
195
|
break;
|
|
187
196
|
|
|
188
197
|
default:
|
|
189
|
-
//
|
|
198
|
+
// Log unknown messages for debugging
|
|
199
|
+
if (templateId && !this._seenTemplates.has(`logged_${templateId}`)) {
|
|
200
|
+
this._seenTemplates.add(`logged_${templateId}`);
|
|
201
|
+
}
|
|
190
202
|
break;
|
|
191
203
|
}
|
|
192
204
|
}
|
|
@@ -93,7 +93,20 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
93
93
|
|
|
94
94
|
// Handle strategy signals
|
|
95
95
|
strategy.on('signal', async (signal) => {
|
|
96
|
-
|
|
96
|
+
ui.addLog('info', `SIGNAL DETECTED: ${signal.direction?.toUpperCase()}`);
|
|
97
|
+
|
|
98
|
+
if (!running) {
|
|
99
|
+
ui.addLog('info', 'Signal ignored: not running');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (pendingOrder) {
|
|
103
|
+
ui.addLog('info', 'Signal ignored: order pending');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (currentPosition !== 0) {
|
|
107
|
+
ui.addLog('info', `Signal ignored: position open (${currentPosition})`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
97
110
|
|
|
98
111
|
let { direction, entry, stopLoss, takeProfit, confidence } = signal;
|
|
99
112
|
let orderSize = contracts;
|
|
@@ -185,25 +198,85 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
185
198
|
});
|
|
186
199
|
|
|
187
200
|
// Handle market data ticks
|
|
201
|
+
let lastPrice = null;
|
|
202
|
+
let lastBid = null;
|
|
203
|
+
let lastAsk = null;
|
|
204
|
+
let ticksPerSecond = 0;
|
|
205
|
+
let lastTickSecond = Math.floor(Date.now() / 1000);
|
|
206
|
+
|
|
188
207
|
marketFeed.on('tick', (tick) => {
|
|
189
208
|
tickCount++;
|
|
190
209
|
const latencyStart = Date.now();
|
|
210
|
+
const currentSecond = Math.floor(Date.now() / 1000);
|
|
211
|
+
|
|
212
|
+
// Count ticks per second
|
|
213
|
+
if (currentSecond === lastTickSecond) {
|
|
214
|
+
ticksPerSecond++;
|
|
215
|
+
} else {
|
|
216
|
+
ticksPerSecond = 1;
|
|
217
|
+
lastTickSecond = currentSecond;
|
|
218
|
+
}
|
|
191
219
|
|
|
192
220
|
aiContext.recentTicks.push(tick);
|
|
193
221
|
if (aiContext.recentTicks.length > aiContext.maxTicks) aiContext.recentTicks.shift();
|
|
194
222
|
|
|
223
|
+
// Smart logs for tick flow
|
|
224
|
+
const price = tick.price || tick.tradePrice;
|
|
225
|
+
const bid = tick.bid || tick.bidPrice;
|
|
226
|
+
const ask = tick.ask || tick.askPrice;
|
|
227
|
+
|
|
228
|
+
// Log first tick
|
|
229
|
+
if (tickCount === 1) {
|
|
230
|
+
ui.addLog('info', `First tick received @ ${price?.toFixed(2) || 'N/A'}`);
|
|
231
|
+
ui.addLog('info', `Tick type: ${tick.type || 'unknown'}`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Log price changes
|
|
235
|
+
if (price && lastPrice && price !== lastPrice) {
|
|
236
|
+
const direction = price > lastPrice ? 'UP' : 'DOWN';
|
|
237
|
+
const change = Math.abs(price - lastPrice).toFixed(2);
|
|
238
|
+
if (tickCount <= 10 || tickCount % 50 === 0) {
|
|
239
|
+
ui.addLog('info', `Price ${direction} ${change} -> ${price.toFixed(2)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Log bid/ask spread
|
|
244
|
+
if (bid && ask && (bid !== lastBid || ask !== lastAsk)) {
|
|
245
|
+
const spread = (ask - bid).toFixed(2);
|
|
246
|
+
if (tickCount <= 5) {
|
|
247
|
+
ui.addLog('info', `Spread: ${spread} (Bid: ${bid.toFixed(2)} / Ask: ${ask.toFixed(2)})`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
lastPrice = price;
|
|
252
|
+
lastBid = bid;
|
|
253
|
+
lastAsk = ask;
|
|
254
|
+
|
|
195
255
|
strategy.processTick({
|
|
196
256
|
contractId: tick.contractId || contractId,
|
|
197
|
-
price:
|
|
198
|
-
volume: tick.volume ||
|
|
257
|
+
price: price, bid: bid, ask: ask,
|
|
258
|
+
volume: tick.volume || tick.size || 1,
|
|
259
|
+
side: tick.side || tick.lastTradeSide || 'unknown',
|
|
199
260
|
timestamp: tick.timestamp || Date.now()
|
|
200
261
|
});
|
|
201
262
|
|
|
202
263
|
stats.latency = Date.now() - latencyStart;
|
|
203
|
-
|
|
264
|
+
|
|
265
|
+
// Periodic status logs
|
|
266
|
+
if (tickCount === 10) ui.addLog('info', `Receiving ticks... (${ticksPerSecond}/sec)`);
|
|
267
|
+
if (tickCount === 50) ui.addLog('info', `50 ticks processed, strategy analyzing...`);
|
|
268
|
+
if (tickCount % 200 === 0) {
|
|
269
|
+
ui.addLog('info', `Tick #${tickCount} @ ${price?.toFixed(2) || 'N/A'} | ${ticksPerSecond}/sec`);
|
|
270
|
+
}
|
|
204
271
|
});
|
|
205
272
|
|
|
206
|
-
marketFeed.on('connected', () => {
|
|
273
|
+
marketFeed.on('connected', () => {
|
|
274
|
+
stats.connected = true;
|
|
275
|
+
ui.addLog('connected', 'Market data connected!');
|
|
276
|
+
ui.addLog('info', 'Subscribing to market data...');
|
|
277
|
+
});
|
|
278
|
+
marketFeed.on('subscribed', (symbol) => ui.addLog('info', `Subscribed to ${symbol}`));
|
|
279
|
+
marketFeed.on('debug', (msg) => ui.addLog('info', msg));
|
|
207
280
|
marketFeed.on('error', (err) => ui.addLog('error', `Market: ${err.message}`));
|
|
208
281
|
marketFeed.on('disconnected', () => { stats.connected = false; ui.addLog('error', 'Market disconnected'); });
|
|
209
282
|
|