hedgequantx 2.9.210 → 2.9.212
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
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* =============================================================================
|
|
3
|
+
* Smart Logs Context - Instrument & Strategy Specific Messages
|
|
4
|
+
* =============================================================================
|
|
5
|
+
* Messages adaptés au contexte:
|
|
6
|
+
* - Instrument (NQ/MNQ, ES/MES, CL, GC, etc.)
|
|
7
|
+
* - Stratégie (HQX Scalping = QUANT/ticks, HQX-2B = bars/zones)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// INSTRUMENT CONTEXTS - Vocabulary specific to each market
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
const INSTRUMENT_CONTEXT = {
|
|
17
|
+
// NASDAQ (NQ/MNQ) - Tech-heavy, high beta, momentum-driven
|
|
18
|
+
NQ: {
|
|
19
|
+
name: 'Nasdaq',
|
|
20
|
+
traits: ['tech-driven', 'high-beta', 'momentum'],
|
|
21
|
+
bullish: [
|
|
22
|
+
'Tech rally lifting index, FAANG leading',
|
|
23
|
+
'Risk-on sentiment, growth stocks bid',
|
|
24
|
+
'Nasdaq outperforming, tech momentum strong',
|
|
25
|
+
'Mega-caps driving index higher',
|
|
26
|
+
'Tech sector rotation bullish',
|
|
27
|
+
'Growth over value trade active',
|
|
28
|
+
'NASDAQ bid on semiconductor strength',
|
|
29
|
+
'Tech bulls in control, AI momentum',
|
|
30
|
+
'Index lifting on NVDA/AAPL strength',
|
|
31
|
+
'Risk appetite strong, tech leading',
|
|
32
|
+
],
|
|
33
|
+
bearish: [
|
|
34
|
+
'Tech weakness dragging index',
|
|
35
|
+
'Risk-off rotation out of growth',
|
|
36
|
+
'Nasdaq underperforming, rates pressure',
|
|
37
|
+
'Mega-cap selling pressure',
|
|
38
|
+
'Tech sector rotation bearish',
|
|
39
|
+
'Value over growth trade active',
|
|
40
|
+
'NASDAQ offered on chip weakness',
|
|
41
|
+
'Tech bears pressing, yields rising',
|
|
42
|
+
'Index heavy on FAANG weakness',
|
|
43
|
+
'Risk aversion hitting growth names',
|
|
44
|
+
],
|
|
45
|
+
neutral: [
|
|
46
|
+
'Tech consolidating, awaiting catalyst',
|
|
47
|
+
'Nasdaq range-bound, mixed sector action',
|
|
48
|
+
'Index digesting recent move',
|
|
49
|
+
'Tech in balance, watching yields',
|
|
50
|
+
'Mega-caps mixed, no clear direction',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// S&P 500 (ES/MES) - Broad market, institutional, balanced
|
|
55
|
+
ES: {
|
|
56
|
+
name: 'S&P 500',
|
|
57
|
+
traits: ['broad-market', 'institutional', 'balanced'],
|
|
58
|
+
bullish: [
|
|
59
|
+
'Broad market strength, risk-on',
|
|
60
|
+
'S&P breaking out, breadth improving',
|
|
61
|
+
'Institutional buying across sectors',
|
|
62
|
+
'Index bid on economic optimism',
|
|
63
|
+
'Defensive to offensive rotation',
|
|
64
|
+
'Market internals bullish',
|
|
65
|
+
'S&P above key moving averages',
|
|
66
|
+
'Broad rally, advancers leading',
|
|
67
|
+
'Index strength on volume',
|
|
68
|
+
'Risk appetite improving broadly',
|
|
69
|
+
],
|
|
70
|
+
bearish: [
|
|
71
|
+
'Broad market weakness, risk-off',
|
|
72
|
+
'S&P breaking down, breadth weak',
|
|
73
|
+
'Institutional selling pressure',
|
|
74
|
+
'Index offered on macro concerns',
|
|
75
|
+
'Offensive to defensive rotation',
|
|
76
|
+
'Market internals bearish',
|
|
77
|
+
'S&P below key support levels',
|
|
78
|
+
'Broad selling, decliners leading',
|
|
79
|
+
'Index weakness on volume',
|
|
80
|
+
'Risk aversion across sectors',
|
|
81
|
+
],
|
|
82
|
+
neutral: [
|
|
83
|
+
'S&P consolidating at key level',
|
|
84
|
+
'Broad market in balance',
|
|
85
|
+
'Index awaiting economic data',
|
|
86
|
+
'Sector rotation neutral',
|
|
87
|
+
'Market digesting Fed commentary',
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Crude Oil (CL/MCL) - Energy, geopolitical, supply/demand
|
|
92
|
+
CL: {
|
|
93
|
+
name: 'Crude Oil',
|
|
94
|
+
traits: ['energy', 'geopolitical', 'supply-demand'],
|
|
95
|
+
bullish: [
|
|
96
|
+
'Crude bid on supply concerns',
|
|
97
|
+
'Energy rally, OPEC supporting',
|
|
98
|
+
'Oil lifting on inventory draw',
|
|
99
|
+
'Geopolitical risk premium rising',
|
|
100
|
+
'Demand outlook improving',
|
|
101
|
+
'Refinery demand strong',
|
|
102
|
+
'Crude above resistance, bulls in control',
|
|
103
|
+
'Energy sector leading broader market',
|
|
104
|
+
'WTI bid on dollar weakness',
|
|
105
|
+
'Supply disruption fears lifting prices',
|
|
106
|
+
],
|
|
107
|
+
bearish: [
|
|
108
|
+
'Crude offered on demand fears',
|
|
109
|
+
'Energy selling, OPEC uncertainty',
|
|
110
|
+
'Oil dropping on inventory build',
|
|
111
|
+
'Geopolitical risk premium fading',
|
|
112
|
+
'Demand outlook weakening',
|
|
113
|
+
'Refinery maintenance weighing',
|
|
114
|
+
'Crude below support, bears pressing',
|
|
115
|
+
'Energy sector lagging market',
|
|
116
|
+
'WTI offered on dollar strength',
|
|
117
|
+
'Supply glut concerns pressuring',
|
|
118
|
+
],
|
|
119
|
+
neutral: [
|
|
120
|
+
'Crude in balance, awaiting EIA data',
|
|
121
|
+
'Energy consolidating near OPEC meeting',
|
|
122
|
+
'Oil range-bound on mixed signals',
|
|
123
|
+
'Supply/demand in equilibrium',
|
|
124
|
+
'Crude watching dollar direction',
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
// Gold (GC/MGC) - Safe haven, inflation hedge, rates sensitive
|
|
129
|
+
GC: {
|
|
130
|
+
name: 'Gold',
|
|
131
|
+
traits: ['safe-haven', 'inflation-hedge', 'rates-sensitive'],
|
|
132
|
+
bullish: [
|
|
133
|
+
'Gold bid on safe-haven demand',
|
|
134
|
+
'Precious metals rally, risk-off',
|
|
135
|
+
'Gold lifting on inflation fears',
|
|
136
|
+
'Real yields dropping, gold bullish',
|
|
137
|
+
'Flight to safety supporting gold',
|
|
138
|
+
'Central bank buying supportive',
|
|
139
|
+
'Gold above resistance, bulls active',
|
|
140
|
+
'Dollar weakness lifting gold',
|
|
141
|
+
'Geopolitical uncertainty bid',
|
|
142
|
+
'Inflation hedge demand rising',
|
|
143
|
+
],
|
|
144
|
+
bearish: [
|
|
145
|
+
'Gold offered on risk-on sentiment',
|
|
146
|
+
'Precious metals selling, yields rising',
|
|
147
|
+
'Gold dropping on Fed hawkishness',
|
|
148
|
+
'Real yields rising, gold bearish',
|
|
149
|
+
'Risk appetite reducing safe-haven demand',
|
|
150
|
+
'ETF outflows pressuring gold',
|
|
151
|
+
'Gold below support, bears in control',
|
|
152
|
+
'Dollar strength weighing on gold',
|
|
153
|
+
'Risk-on rotation out of metals',
|
|
154
|
+
'Inflation expectations cooling',
|
|
155
|
+
],
|
|
156
|
+
neutral: [
|
|
157
|
+
'Gold consolidating near key level',
|
|
158
|
+
'Precious metals in balance',
|
|
159
|
+
'Gold watching Fed commentary',
|
|
160
|
+
'Real yields stable, gold range-bound',
|
|
161
|
+
'Safe-haven demand muted',
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
// Russell 2000 (RTY/M2K) - Small caps, domestic, risk appetite
|
|
166
|
+
RTY: {
|
|
167
|
+
name: 'Russell 2000',
|
|
168
|
+
traits: ['small-cap', 'domestic', 'risk-appetite'],
|
|
169
|
+
bullish: [
|
|
170
|
+
'Small caps outperforming, risk-on',
|
|
171
|
+
'Russell leading, domestic strength',
|
|
172
|
+
'Risk appetite lifting small caps',
|
|
173
|
+
'RTY breaking out, breadth strong',
|
|
174
|
+
'Regional banks supporting index',
|
|
175
|
+
'Small cap rotation accelerating',
|
|
176
|
+
'Domestic economy optimism',
|
|
177
|
+
'Russell above key resistance',
|
|
178
|
+
'Risk-on favoring high-beta names',
|
|
179
|
+
'Small caps catching bid',
|
|
180
|
+
],
|
|
181
|
+
bearish: [
|
|
182
|
+
'Small caps underperforming, risk-off',
|
|
183
|
+
'Russell lagging, credit concerns',
|
|
184
|
+
'Risk aversion hitting small caps',
|
|
185
|
+
'RTY breaking down, breadth weak',
|
|
186
|
+
'Regional bank weakness dragging',
|
|
187
|
+
'Small cap rotation reversing',
|
|
188
|
+
'Domestic economy concerns',
|
|
189
|
+
'Russell below support, bears active',
|
|
190
|
+
'Risk-off hitting high-beta names',
|
|
191
|
+
'Small caps under pressure',
|
|
192
|
+
],
|
|
193
|
+
neutral: [
|
|
194
|
+
'Small caps consolidating',
|
|
195
|
+
'Russell in balance, watching rates',
|
|
196
|
+
'RTY range-bound, mixed signals',
|
|
197
|
+
'Small cap sentiment neutral',
|
|
198
|
+
'Regional banks mixed',
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
// Dow Jones (YM/MYM) - Blue chips, value, defensive
|
|
203
|
+
YM: {
|
|
204
|
+
name: 'Dow Jones',
|
|
205
|
+
traits: ['blue-chip', 'value', 'defensive'],
|
|
206
|
+
bullish: [
|
|
207
|
+
'Blue chips leading, value rotation',
|
|
208
|
+
'Dow outperforming, defensive strength',
|
|
209
|
+
'Industrials lifting index',
|
|
210
|
+
'Value over growth trade active',
|
|
211
|
+
'Dow breaking out, old economy bid',
|
|
212
|
+
'Blue chip accumulation',
|
|
213
|
+
'Defensive sectors leading',
|
|
214
|
+
'YM above resistance, bulls active',
|
|
215
|
+
'Dow component strength broad',
|
|
216
|
+
'Value rotation accelerating',
|
|
217
|
+
],
|
|
218
|
+
bearish: [
|
|
219
|
+
'Blue chips lagging, growth leading',
|
|
220
|
+
'Dow underperforming, cyclicals weak',
|
|
221
|
+
'Industrials dragging index',
|
|
222
|
+
'Growth over value trade active',
|
|
223
|
+
'Dow breaking down, selling pressure',
|
|
224
|
+
'Blue chip distribution',
|
|
225
|
+
'Defensive sectors under pressure',
|
|
226
|
+
'YM below support, bears pressing',
|
|
227
|
+
'Dow component weakness broad',
|
|
228
|
+
'Value rotation reversing',
|
|
229
|
+
],
|
|
230
|
+
neutral: [
|
|
231
|
+
'Blue chips consolidating',
|
|
232
|
+
'Dow in balance, rotation mixed',
|
|
233
|
+
'YM range-bound, awaiting catalyst',
|
|
234
|
+
'Value/growth neutral',
|
|
235
|
+
'Industrials mixed',
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Aliases for micro contracts
|
|
241
|
+
INSTRUMENT_CONTEXT.MNQ = INSTRUMENT_CONTEXT.NQ;
|
|
242
|
+
INSTRUMENT_CONTEXT.MES = INSTRUMENT_CONTEXT.ES;
|
|
243
|
+
INSTRUMENT_CONTEXT.MCL = INSTRUMENT_CONTEXT.CL;
|
|
244
|
+
INSTRUMENT_CONTEXT.MGC = INSTRUMENT_CONTEXT.GC;
|
|
245
|
+
INSTRUMENT_CONTEXT.M2K = INSTRUMENT_CONTEXT.RTY;
|
|
246
|
+
INSTRUMENT_CONTEXT.MYM = INSTRUMENT_CONTEXT.YM;
|
|
247
|
+
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// STRATEGY CONTEXTS - Vocabulary specific to each strategy
|
|
250
|
+
// ============================================================================
|
|
251
|
+
|
|
252
|
+
const STRATEGY_CONTEXT = {
|
|
253
|
+
// HQX Ultra Scalping - QUANT based (Z-Score, VPIN, OFI)
|
|
254
|
+
'ultra-scalping': {
|
|
255
|
+
name: 'QUANT Scalping',
|
|
256
|
+
metrics: ['Z-Score', 'VPIN', 'OFI'],
|
|
257
|
+
warmup: [
|
|
258
|
+
'QUANT models calibrating',
|
|
259
|
+
'Statistical edge computation',
|
|
260
|
+
'Factor model initialization',
|
|
261
|
+
'Z-Score baseline forming',
|
|
262
|
+
'VPIN toxicity model loading',
|
|
263
|
+
'OFI imbalance calc active',
|
|
264
|
+
'Mean reversion params init',
|
|
265
|
+
'Volatility regime detection',
|
|
266
|
+
'Microstructure analysis loading',
|
|
267
|
+
'Tick distribution fitting',
|
|
268
|
+
],
|
|
269
|
+
scanning: [
|
|
270
|
+
'Scanning for statistical edge',
|
|
271
|
+
'Z-Score within normal bounds',
|
|
272
|
+
'No mean reversion signal',
|
|
273
|
+
'VPIN clean, no toxicity',
|
|
274
|
+
'OFI balanced, no imbalance',
|
|
275
|
+
'Waiting for regime shift',
|
|
276
|
+
'Factor model neutral',
|
|
277
|
+
'Statistical noise, no alpha',
|
|
278
|
+
'Mean at fair value',
|
|
279
|
+
'No exploitable edge detected',
|
|
280
|
+
],
|
|
281
|
+
signal: [
|
|
282
|
+
'Statistical edge detected',
|
|
283
|
+
'Z-Score extreme, mean reversion due',
|
|
284
|
+
'VPIN/OFI alignment confirmed',
|
|
285
|
+
'Factor model signal active',
|
|
286
|
+
'Mean reversion setup forming',
|
|
287
|
+
'Statistical alpha opportunity',
|
|
288
|
+
'Regime shift detected',
|
|
289
|
+
'Edge exploitation window',
|
|
290
|
+
'QUANT signal triggered',
|
|
291
|
+
'Model confidence threshold met',
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
// HQX-2B Liquidity Sweep - Price action based (bars, swings, zones)
|
|
296
|
+
'hqx-2b': {
|
|
297
|
+
name: '2B Liquidity Sweep',
|
|
298
|
+
metrics: ['Swings', 'Zones', 'Sweeps'],
|
|
299
|
+
warmup: [
|
|
300
|
+
'Building swing structure',
|
|
301
|
+
'Mapping liquidity zones',
|
|
302
|
+
'Detecting pivot points',
|
|
303
|
+
'Zone formation analysis',
|
|
304
|
+
'Swing detection active',
|
|
305
|
+
'Price structure mapping',
|
|
306
|
+
'Liquidity pool scanning',
|
|
307
|
+
'Support/resistance mapping',
|
|
308
|
+
'Order block detection',
|
|
309
|
+
'Market structure loading',
|
|
310
|
+
],
|
|
311
|
+
scanning: [
|
|
312
|
+
'Monitoring swing structure',
|
|
313
|
+
'No zone in range',
|
|
314
|
+
'Waiting for sweep setup',
|
|
315
|
+
'Price away from zones',
|
|
316
|
+
'No liquidity sweep detected',
|
|
317
|
+
'Watching for pivot break',
|
|
318
|
+
'Structure intact, no setup',
|
|
319
|
+
'Zones mapped, awaiting price',
|
|
320
|
+
'Swing highs/lows holding',
|
|
321
|
+
'No 2B pattern forming',
|
|
322
|
+
],
|
|
323
|
+
signal: [
|
|
324
|
+
'Liquidity sweep detected',
|
|
325
|
+
'Zone penetration confirmed',
|
|
326
|
+
'2B reversal pattern forming',
|
|
327
|
+
'Stop hunt completed',
|
|
328
|
+
'Sweep and reject signal',
|
|
329
|
+
'Zone touch with rejection',
|
|
330
|
+
'Liquidity taken, reversing',
|
|
331
|
+
'False break confirmed',
|
|
332
|
+
'2B setup triggered',
|
|
333
|
+
'Zone sweep entry active',
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// ============================================================================
|
|
339
|
+
// MESSAGE GENERATOR
|
|
340
|
+
// ============================================================================
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get contextual message based on instrument and strategy
|
|
344
|
+
* @param {string} symbol - Contract symbol (e.g., 'MNQH6', 'ESH6')
|
|
345
|
+
* @param {string} strategyId - Strategy ID ('ultra-scalping' or 'hqx-2b')
|
|
346
|
+
* @param {string} context - Message context ('bullish', 'bearish', 'neutral', 'warmup', 'scanning', 'signal')
|
|
347
|
+
* @returns {string} Contextual message
|
|
348
|
+
*/
|
|
349
|
+
function getContextualMessage(symbol, strategyId, context) {
|
|
350
|
+
// Extract base symbol (remove contract month)
|
|
351
|
+
const baseSymbol = symbol.replace(/[FGHJKMNQUVXZ]\d{1,2}(:|$).*/, '').toUpperCase();
|
|
352
|
+
|
|
353
|
+
// Get instrument context
|
|
354
|
+
const instrument = INSTRUMENT_CONTEXT[baseSymbol] || INSTRUMENT_CONTEXT.ES; // Default to ES
|
|
355
|
+
|
|
356
|
+
// Get strategy context
|
|
357
|
+
const strategy = STRATEGY_CONTEXT[strategyId] || STRATEGY_CONTEXT['hqx-2b'];
|
|
358
|
+
|
|
359
|
+
let pool = [];
|
|
360
|
+
|
|
361
|
+
// Market direction messages (from instrument)
|
|
362
|
+
if (context === 'bullish' || context === 'bearish' || context === 'neutral') {
|
|
363
|
+
pool = instrument[context] || [];
|
|
364
|
+
}
|
|
365
|
+
// Strategy state messages
|
|
366
|
+
else if (context === 'warmup' || context === 'scanning' || context === 'signal') {
|
|
367
|
+
pool = strategy[context] || [];
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Return random message from pool, or fallback
|
|
371
|
+
if (pool.length > 0) {
|
|
372
|
+
return pool[Math.floor(Math.random() * pool.length)];
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return 'Analyzing market conditions...';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Get instrument name from symbol
|
|
380
|
+
*/
|
|
381
|
+
function getInstrumentName(symbol) {
|
|
382
|
+
const baseSymbol = symbol.replace(/[FGHJKMNQUVXZ]\d{1,2}(:|$).*/, '').toUpperCase();
|
|
383
|
+
return INSTRUMENT_CONTEXT[baseSymbol]?.name || 'Futures';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
module.exports = {
|
|
387
|
+
INSTRUMENT_CONTEXT,
|
|
388
|
+
STRATEGY_CONTEXT,
|
|
389
|
+
getContextualMessage,
|
|
390
|
+
getInstrumentName,
|
|
391
|
+
};
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const chalk = require('chalk');
|
|
16
16
|
const smartLogs = require('./smart-logs');
|
|
17
|
+
const { getContextualMessage } = require('./smart-logs-context');
|
|
17
18
|
|
|
18
19
|
const CONFIG = {
|
|
19
20
|
SESSION_LOG_INTERVAL: 10,
|
|
@@ -51,6 +52,7 @@ class SmartLogsEngine {
|
|
|
51
52
|
this.symbolCode = symbol;
|
|
52
53
|
this.counter = 0;
|
|
53
54
|
this.lastState = null;
|
|
55
|
+
this.lastHeartbeat = 0;
|
|
54
56
|
|
|
55
57
|
// State tracking for event detection (both strategies)
|
|
56
58
|
this.lastBias = null;
|
|
@@ -112,34 +114,36 @@ class SmartLogsEngine {
|
|
|
112
114
|
if (bars >= 10 && !this.warmupLogged) {
|
|
113
115
|
this.warmupLogged = true;
|
|
114
116
|
event = 'warmup';
|
|
115
|
-
|
|
117
|
+
const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
|
|
118
|
+
message = `[${sym}] 2B ready | ${bars} bars | ${warmupMsg}`;
|
|
116
119
|
logType = 'system';
|
|
117
120
|
}
|
|
118
121
|
// EVENT 2: New zone created
|
|
119
122
|
else if (zones > this.lastZones && zones > 0) {
|
|
120
123
|
event = 'new_zone';
|
|
121
|
-
const
|
|
122
|
-
message = `[${sym}] ${price} | Zone #${zones}
|
|
124
|
+
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
125
|
+
message = `[${sym}] ${price} | Zone #${zones} | ${signalMsg}`;
|
|
123
126
|
logType = 'signal';
|
|
124
127
|
}
|
|
125
128
|
// EVENT 3: New swing detected
|
|
126
129
|
else if (swings > this.lastSwings && swings > 0) {
|
|
127
130
|
event = 'new_swing';
|
|
128
|
-
const
|
|
129
|
-
message = `[${sym}] ${price} | Swing #${swings} | ${
|
|
131
|
+
const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
|
|
132
|
+
message = `[${sym}] ${price} | Swing #${swings} | ${scanMsg}`;
|
|
130
133
|
}
|
|
131
134
|
// EVENT 4: Zone approach (price near zone)
|
|
132
135
|
else if (nearZone && !this.lastNearZone && zones > 0) {
|
|
133
136
|
event = 'zone_approach';
|
|
134
|
-
const
|
|
135
|
-
message = `[${sym}] ${price} |
|
|
137
|
+
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
138
|
+
message = `[${sym}] ${price} | Zone approach | ${signalMsg}`;
|
|
136
139
|
logType = 'signal';
|
|
137
140
|
}
|
|
138
141
|
// EVENT 5: Bias flip
|
|
139
142
|
else if (this.lastBias && trend !== this.lastBias && trend !== 'neutral' && this.lastBias !== 'neutral') {
|
|
140
143
|
event = 'bias_flip';
|
|
141
144
|
const arrow = trend === 'bullish' ? chalk.green('▲') : chalk.red('▼');
|
|
142
|
-
|
|
145
|
+
const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, trend);
|
|
146
|
+
message = `[${sym}] ${arrow} ${this.lastBias} → ${trend} | ${flipMsg}`;
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
// Update state tracking
|
|
@@ -175,33 +179,38 @@ class SmartLogsEngine {
|
|
|
175
179
|
if (ticks >= CONFIG.QUANT_WARMUP_TICKS && !this.warmupLogged) {
|
|
176
180
|
this.warmupLogged = true;
|
|
177
181
|
event = 'warmup';
|
|
178
|
-
|
|
182
|
+
const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
|
|
183
|
+
message = `[${sym}] QUANT ready | ${ticks} ticks | ${warmupMsg}`;
|
|
179
184
|
logType = 'system';
|
|
180
185
|
}
|
|
181
186
|
// EVENT 2: Z-Score regime change
|
|
182
187
|
else if (this.lastZRegime !== null && zRegime !== this.lastZRegime) {
|
|
183
188
|
event = 'z_regime';
|
|
184
|
-
|
|
185
|
-
const
|
|
189
|
+
// Get instrument-specific market context message
|
|
190
|
+
const marketCtx = bias === 'bullish' ? 'bullish' : bias === 'bearish' ? 'bearish' : 'neutral';
|
|
191
|
+
const instrumentMsg = getContextualMessage(this.symbolCode, this.strategyId, marketCtx);
|
|
186
192
|
|
|
187
193
|
if (zRegime === 'extreme') {
|
|
188
194
|
logType = 'signal';
|
|
189
195
|
const dir = zScore < 0 ? 'LONG' : 'SHORT';
|
|
190
|
-
|
|
196
|
+
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
197
|
+
message = `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ | ${dir} | ${signalMsg}`;
|
|
191
198
|
} else if (zRegime === 'high') {
|
|
192
199
|
logType = 'signal';
|
|
193
|
-
message = `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ
|
|
200
|
+
message = `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ | ${instrumentMsg}`;
|
|
194
201
|
} else if (zRegime === 'building') {
|
|
195
|
-
message = `[${sym}] ${price} | Z building (${zScore.toFixed(1)}σ) | ${
|
|
202
|
+
message = `[${sym}] ${price} | Z building (${zScore.toFixed(1)}σ) | ${instrumentMsg}`;
|
|
196
203
|
} else {
|
|
197
|
-
|
|
204
|
+
const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
|
|
205
|
+
message = `[${sym}] ${price} | Z normalized | ${scanMsg}`;
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
208
|
// EVENT 3: Bias flip (OFI direction change)
|
|
201
209
|
else if (this.lastBias !== null && bias !== this.lastBias && bias !== 'neutral' && this.lastBias !== 'neutral') {
|
|
202
210
|
event = 'bias_flip';
|
|
203
211
|
const arrow = bias === 'bullish' ? chalk.green('▲') : chalk.red('▼');
|
|
204
|
-
|
|
212
|
+
const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, bias);
|
|
213
|
+
message = `[${sym}] ${arrow} OFI: ${this.lastBias} → ${bias} | ${flipMsg}`;
|
|
205
214
|
}
|
|
206
215
|
// EVENT 4: VPIN toxicity change
|
|
207
216
|
else if (this.lastVpinToxic !== null && vpinToxic !== this.lastVpinToxic) {
|
|
@@ -220,8 +229,24 @@ class SmartLogsEngine {
|
|
|
220
229
|
this.lastVpinToxic = vpinToxic;
|
|
221
230
|
|
|
222
231
|
if (event && message) {
|
|
232
|
+
this.lastHeartbeat = Date.now();
|
|
223
233
|
return { type: logType, message, logToSession: event === 'z_regime' || event === 'bias_flip' };
|
|
224
234
|
}
|
|
235
|
+
|
|
236
|
+
// HEARTBEAT: Show status every 30s when no events (proves strategy is active)
|
|
237
|
+
const now = Date.now();
|
|
238
|
+
if (this.warmupLogged && now - this.lastHeartbeat >= 30000) {
|
|
239
|
+
this.lastHeartbeat = now;
|
|
240
|
+
// Use instrument + strategy contextual message
|
|
241
|
+
const marketCtx = bias === 'bullish' ? 'bullish' : bias === 'bearish' ? 'bearish' : 'neutral';
|
|
242
|
+
const ctxMsg = getContextualMessage(this.symbolCode, this.strategyId, marketCtx);
|
|
243
|
+
return {
|
|
244
|
+
type: 'analysis',
|
|
245
|
+
message: `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ | OFI: ${(ofi * 100).toFixed(0)}% | ${ctxMsg}`,
|
|
246
|
+
logToSession: false
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
225
250
|
return null;
|
|
226
251
|
}
|
|
227
252
|
|
|
@@ -230,6 +255,7 @@ class SmartLogsEngine {
|
|
|
230
255
|
this.counter = 0;
|
|
231
256
|
this.lastBias = null;
|
|
232
257
|
this.warmupLogged = false;
|
|
258
|
+
this.lastHeartbeat = 0;
|
|
233
259
|
// HQX-2B
|
|
234
260
|
this.lastBars = 0;
|
|
235
261
|
this.lastSwings = 0;
|
|
@@ -344,20 +344,25 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
344
344
|
await marketFeed.connect(rithmicCredentials);
|
|
345
345
|
await marketFeed.subscribe(symbolCode, contract.exchange || 'CME');
|
|
346
346
|
|
|
347
|
-
// Load historical
|
|
347
|
+
// Load historical data for model warmup (optional - works with live data too)
|
|
348
348
|
if (strategy.preloadBars) {
|
|
349
|
-
ui.addLog('system', 'Loading
|
|
349
|
+
ui.addLog('system', 'Loading warmup data...');
|
|
350
350
|
try {
|
|
351
351
|
const histBars = await marketFeed.getHistoricalBars(symbolCode, contract.exchange || 'CME', 30);
|
|
352
352
|
if (histBars && histBars.length > 0) {
|
|
353
353
|
strategy.preloadBars(contractId, histBars);
|
|
354
|
-
|
|
355
|
-
|
|
354
|
+
// Different message for tick-based vs bar-based strategies
|
|
355
|
+
const isTickBased = strategyId === 'ultra-scalping';
|
|
356
|
+
const msg = isTickBased
|
|
357
|
+
? `Warmup data loaded - QUANT models initializing...`
|
|
358
|
+
: `Loaded ${histBars.length} historical bars - ready to trade!`;
|
|
359
|
+
ui.addLog('system', msg);
|
|
360
|
+
sessionLogger.log('HISTORY', `Preloaded ${histBars.length} bars for warmup`);
|
|
356
361
|
} else {
|
|
357
|
-
ui.addLog('system', 'No history
|
|
362
|
+
ui.addLog('system', 'No history - warming up with live ticks...');
|
|
358
363
|
}
|
|
359
364
|
} catch (histErr) {
|
|
360
|
-
ui.addLog('system', `
|
|
365
|
+
ui.addLog('system', `Warmup skipped - using live data`);
|
|
361
366
|
sessionLogger.log('HISTORY', `Failed: ${histErr.message}`);
|
|
362
367
|
}
|
|
363
368
|
}
|