hedgequantx 2.9.214 → 2.9.216

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.214",
3
+ "version": "2.9.216",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -8,6 +8,16 @@
8
8
  * - Uses smartLogs.getLiveAnalysisLog() for varied, non-repetitive messages
9
9
  *
10
10
  * Only logs when something SIGNIFICANT happens - no spam, no repetitive messages
11
+ *
12
+ * COLOR SCHEME:
13
+ * - Symbols: cyan (NQ, ES, CL, GC)
14
+ * - Prices: white bold
15
+ * - Bullish/Long: green
16
+ * - Bearish/Short: red
17
+ * - Neutral/System: gray/dim
18
+ * - Signals: yellow/magenta
19
+ * - Risk/Warnings: red bold
20
+ * - Values: blue (Z-Score, VPIN, OFI numbers)
11
21
  */
12
22
 
13
23
  'use strict';
@@ -16,6 +26,39 @@ const chalk = require('chalk');
16
26
  const smartLogs = require('./smart-logs');
17
27
  const { getContextualMessage } = require('./smart-logs-context');
18
28
 
29
+ // Color helpers for consistent styling
30
+ const C = {
31
+ // Symbols & identifiers
32
+ sym: (s) => chalk.cyan.bold(s),
33
+
34
+ // Prices
35
+ price: (p) => chalk.white.bold(p),
36
+
37
+ // Direction
38
+ long: (s) => chalk.green.bold(s),
39
+ short: (s) => chalk.red.bold(s),
40
+ bull: (s) => chalk.green(s),
41
+ bear: (s) => chalk.red(s),
42
+
43
+ // Values & metrics
44
+ val: (v) => chalk.blue(v),
45
+ valHigh: (v) => chalk.magenta.bold(v),
46
+
47
+ // Status
48
+ ok: (s) => chalk.green(s),
49
+ warn: (s) => chalk.yellow(s),
50
+ danger: (s) => chalk.red.bold(s),
51
+
52
+ // System/neutral
53
+ dim: (s) => chalk.dim(s),
54
+ info: (s) => chalk.gray(s),
55
+
56
+ // Special
57
+ signal: (s) => chalk.yellow.bold(s),
58
+ zone: (s) => chalk.magenta(s),
59
+ regime: (s) => chalk.cyan(s),
60
+ };
61
+
19
62
  const CONFIG = {
20
63
  SESSION_LOG_INTERVAL: 10,
21
64
  // HQX-2B thresholds
@@ -54,7 +97,6 @@ class SmartLogsEngine {
54
97
  this.symbolCode = symbol;
55
98
  this.counter = 0;
56
99
  this.lastState = null;
57
- this.lastLogTime = 0;
58
100
 
59
101
  // State tracking for event detection (both strategies)
60
102
  this.lastBias = null;
@@ -69,10 +111,6 @@ class SmartLogsEngine {
69
111
  // QUANT specific
70
112
  this.lastZRegime = null;
71
113
  this.lastVpinToxic = false;
72
- this.lastPrice = 0;
73
- this.lastLoggedZ = null;
74
- this.lastLoggedOfi = null;
75
- this.recentMessages = [];
76
114
  }
77
115
 
78
116
  setSymbol(s) { this.symbolCode = s; }
@@ -89,11 +127,14 @@ class SmartLogsEngine {
89
127
 
90
128
  // Active position - same for all strategies
91
129
  if (position !== 0) {
92
- const side = position > 0 ? 'LONG' : 'SHORT';
93
- const flow = (position > 0 && delta > 0) || (position < 0 && delta < 0) ? 'FAVOR' : 'ADVERSE';
130
+ const isLong = position > 0;
131
+ const side = isLong ? C.long('LONG') : C.short('SHORT');
132
+ const flowFavor = (isLong && delta > 0) || (!isLong && delta < 0);
133
+ const flowLabel = flowFavor ? C.ok('FAVOR') : C.danger('ADVERSE');
134
+ const deltaStr = delta > 0 ? C.bull(`+${delta}`) : C.bear(`${delta}`);
94
135
  return {
95
136
  type: 'trade',
96
- message: `[${sym}] ${side} ACTIVE @ ${price} | Delta: ${delta > 0 ? '+' : ''}${delta} | Flow: ${flow}`,
137
+ message: `[${C.sym(sym)}] ${side} ACTIVE @ ${C.price(price)} | Delta: ${deltaStr} | Flow: ${flowLabel}`,
97
138
  logToSession: true
98
139
  };
99
140
  }
@@ -121,35 +162,37 @@ class SmartLogsEngine {
121
162
  this.warmupLogged = true;
122
163
  event = 'warmup';
123
164
  const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
124
- message = `[${sym}] 2B ready | ${bars} bars | ${warmupMsg}`;
165
+ message = `[${C.sym(sym)}] ${C.ok('2B ready')} | ${C.val(bars)} bars | ${C.dim(warmupMsg)}`;
125
166
  logType = 'system';
126
167
  }
127
168
  // EVENT 2: New zone created
128
169
  else if (zones > this.lastZones && zones > 0) {
129
170
  event = 'new_zone';
130
171
  const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
131
- message = `[${sym}] ${price} | Zone #${zones} | ${signalMsg}`;
172
+ message = `[${C.sym(sym)}] ${C.price(price)} | ${C.zone('Zone #' + zones)} | ${C.signal(signalMsg)}`;
132
173
  logType = 'signal';
133
174
  }
134
175
  // EVENT 3: New swing detected
135
176
  else if (swings > this.lastSwings && swings > 0) {
136
177
  event = 'new_swing';
137
178
  const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
138
- message = `[${sym}] ${price} | Swing #${swings} | ${scanMsg}`;
179
+ message = `[${C.sym(sym)}] ${C.price(price)} | ${C.info('Swing #' + swings)} | ${C.dim(scanMsg)}`;
139
180
  }
140
181
  // EVENT 4: Zone approach (price near zone)
141
182
  else if (nearZone && !this.lastNearZone && zones > 0) {
142
183
  event = 'zone_approach';
143
184
  const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
144
- message = `[${sym}] ${price} | Zone approach | ${signalMsg}`;
185
+ message = `[${C.sym(sym)}] ${C.price(price)} | ${C.warn('Zone approach')} | ${C.signal(signalMsg)}`;
145
186
  logType = 'signal';
146
187
  }
147
188
  // EVENT 5: Bias flip
148
189
  else if (this.lastBias && trend !== this.lastBias && trend !== 'neutral' && this.lastBias !== 'neutral') {
149
190
  event = 'bias_flip';
150
- const arrow = trend === 'bullish' ? chalk.green('▲') : chalk.red('▼');
191
+ const arrow = trend === 'bullish' ? C.bull('▲') : C.bear('▼');
192
+ const oldBias = this.lastBias === 'bullish' ? C.bull(this.lastBias) : C.bear(this.lastBias);
193
+ const newBias = trend === 'bullish' ? C.bull(trend) : C.bear(trend);
151
194
  const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, trend);
152
- message = `[${sym}] ${arrow} ${this.lastBias} → ${trend} | ${flipMsg}`;
195
+ message = `[${C.sym(sym)}] ${arrow} ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
153
196
  }
154
197
 
155
198
  // Update state tracking
@@ -181,12 +224,22 @@ class SmartLogsEngine {
181
224
  let logType = 'analysis';
182
225
  let message = null;
183
226
 
227
+ // Helper for Z-Score color
228
+ const zColor = (z) => {
229
+ const absVal = Math.abs(z);
230
+ const formatted = `${z.toFixed(1)}σ`;
231
+ if (absVal >= CONFIG.Z_EXTREME) return C.valHigh(formatted);
232
+ if (absVal >= CONFIG.Z_HIGH) return C.warn(formatted);
233
+ if (absVal >= CONFIG.Z_BUILDING) return C.val(formatted);
234
+ return C.dim(formatted);
235
+ };
236
+
184
237
  // EVENT 1: Warmup complete (250 ticks for QUANT models)
185
238
  if (ticks >= CONFIG.QUANT_WARMUP_TICKS && !this.warmupLogged) {
186
239
  this.warmupLogged = true;
187
240
  event = 'warmup';
188
241
  const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
189
- message = `[${sym}] QUANT ready | ${ticks} ticks | ${warmupMsg}`;
242
+ message = `[${C.sym(sym)}] ${C.ok('QUANT ready')} | ${C.val(ticks)} ticks | ${C.dim(warmupMsg)}`;
190
243
  logType = 'system';
191
244
  }
192
245
  // EVENT 2: Z-Score regime change
@@ -198,34 +251,37 @@ class SmartLogsEngine {
198
251
 
199
252
  if (zRegime === 'extreme') {
200
253
  logType = 'signal';
201
- const dir = zScore < 0 ? 'LONG' : 'SHORT';
254
+ const dir = zScore < 0 ? C.long('LONG') : C.short('SHORT');
202
255
  const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
203
- message = `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ | ${dir} | ${signalMsg}`;
256
+ message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.signal('EXTREME')} | ${dir} | ${C.signal(signalMsg)}`;
204
257
  } else if (zRegime === 'high') {
205
258
  logType = 'signal';
206
- message = `[${sym}] ${price} | Z: ${zScore.toFixed(1)}σ | ${instrumentMsg}`;
259
+ message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.warn('HIGH')} | ${C.dim(instrumentMsg)}`;
207
260
  } else if (zRegime === 'building') {
208
- message = `[${sym}] ${price} | Z building (${zScore.toFixed(1)}σ) | ${instrumentMsg}`;
261
+ message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.info('building')} | ${C.dim(instrumentMsg)}`;
209
262
  } else {
210
263
  const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
211
- message = `[${sym}] ${price} | Z normalized | ${scanMsg}`;
264
+ message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${C.ok('normalized')} | ${C.dim(scanMsg)}`;
212
265
  }
213
266
  }
214
267
  // EVENT 3: Bias flip (OFI direction change)
215
268
  else if (this.lastBias !== null && bias !== this.lastBias && bias !== 'neutral' && this.lastBias !== 'neutral') {
216
269
  event = 'bias_flip';
217
- const arrow = bias === 'bullish' ? chalk.green('▲') : chalk.red('▼');
270
+ const arrow = bias === 'bullish' ? C.bull('▲') : C.bear('▼');
271
+ const oldBias = this.lastBias === 'bullish' ? C.bull(this.lastBias) : C.bear(this.lastBias);
272
+ const newBias = bias === 'bullish' ? C.bull(bias) : C.bear(bias);
218
273
  const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, bias);
219
- message = `[${sym}] ${arrow} OFI: ${this.lastBias} → ${bias} | ${flipMsg}`;
274
+ message = `[${C.sym(sym)}] ${arrow} OFI: ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
220
275
  }
221
276
  // EVENT 4: VPIN toxicity change
222
277
  else if (this.lastVpinToxic !== null && vpinToxic !== this.lastVpinToxic) {
223
278
  event = 'vpin';
279
+ const vpinPct = (vpin * 100).toFixed(0);
224
280
  if (vpinToxic) {
225
- message = `[${sym}] ${price} | VPIN toxic (${(vpin * 100).toFixed(0)}%) - informed flow detected`;
281
+ message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.danger(vpinPct + '%')} ${C.danger('TOXIC')} - informed flow`;
226
282
  logType = 'risk';
227
283
  } else {
228
- message = `[${sym}] ${price} | VPIN clean (${(vpin * 100).toFixed(0)}%) - normal flow`;
284
+ message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.ok(vpinPct + '%')} ${C.ok('clean')} - normal flow`;
229
285
  }
230
286
  }
231
287
 
@@ -235,66 +291,12 @@ class SmartLogsEngine {
235
291
  this.lastVpinToxic = vpinToxic;
236
292
 
237
293
  if (event && message) {
238
- this.lastLogTime = Date.now();
239
- this.lastPrice = state.price;
240
- this.lastLoggedZ = zScore;
241
- this.lastLoggedOfi = ofi;
242
294
  return { type: logType, message, logToSession: event === 'z_regime' || event === 'bias_flip' };
243
295
  }
244
296
 
245
- // REAL-TIME LOGS: Every second, show meaningful market activity
246
- const now = Date.now();
247
- if (this.warmupLogged && now - this.lastLogTime >= 1000) {
248
- const price = state.price || 0;
249
- const priceChange = this.lastPrice ? price - this.lastPrice : 0;
250
- const zChange = this.lastLoggedZ !== null ? zScore - this.lastLoggedZ : 0;
251
- const ofiChange = this.lastLoggedOfi !== null ? ofi - this.lastLoggedOfi : 0;
252
-
253
- this.lastLogTime = now;
254
- this.lastPrice = price;
255
- this.lastLoggedZ = zScore;
256
- this.lastLoggedOfi = ofi;
257
-
258
- // Build contextual message based on what's actually happening
259
- const zStr = zScore >= 0 ? `+${zScore.toFixed(1)}` : zScore.toFixed(1);
260
- const ofiPct = (ofi * 100).toFixed(0);
261
- const vpinPct = (vpin * 100).toFixed(0);
262
-
263
- // Determine what's notable RIGHT NOW
264
- let context;
265
- if (Math.abs(priceChange) >= 0.5) {
266
- // Price moved significantly
267
- const dir = priceChange > 0 ? 'uptick' : 'downtick';
268
- const ticks = Math.abs(priceChange / 0.25).toFixed(0);
269
- context = `${dir} ${ticks}t`;
270
- } else if (Math.abs(zChange) >= 0.3) {
271
- // Z-Score shifting
272
- context = zChange > 0 ? 'Z expanding' : 'Z contracting';
273
- } else if (Math.abs(ofiChange) >= 0.05) {
274
- // OFI shifting
275
- context = ofiChange > 0 ? 'buying pressure' : 'selling pressure';
276
- } else if (absZ >= 1.5) {
277
- // In signal zone
278
- const dir = zScore < 0 ? 'LONG zone' : 'SHORT zone';
279
- context = dir;
280
- } else if (Math.abs(ofi) >= 0.15) {
281
- // Strong flow
282
- context = ofi > 0 ? 'bid strength' : 'offer strength';
283
- } else if (vpin > 0.4) {
284
- // Elevated VPIN
285
- context = 'elevated toxicity';
286
- } else {
287
- // Get instrument-specific neutral message
288
- context = getContextualMessage(this.symbolCode, this.strategyId, 'neutral');
289
- }
290
-
291
- return {
292
- type: 'analysis',
293
- message: `[${sym}] ${price.toFixed(2)} | Z: ${zStr}σ | OFI: ${ofiPct}% | ${context}`,
294
- logToSession: false
295
- };
296
- }
297
-
297
+ // EVENT-DRIVEN ONLY: No spam, no repetitive logs
298
+ // Silence = system is scanning, nothing notable happening
299
+ // This is professional HF behavior
298
300
  return null;
299
301
  }
300
302
 
@@ -303,7 +305,6 @@ class SmartLogsEngine {
303
305
  this.counter = 0;
304
306
  this.lastBias = null;
305
307
  this.warmupLogged = false;
306
- this.lastLogTime = 0;
307
308
  // HQX-2B
308
309
  this.lastBars = 0;
309
310
  this.lastSwings = 0;
@@ -312,10 +313,6 @@ class SmartLogsEngine {
312
313
  // QUANT
313
314
  this.lastZRegime = null;
314
315
  this.lastVpinToxic = false;
315
- this.lastPrice = 0;
316
- this.lastLoggedZ = null;
317
- this.lastLoggedOfi = null;
318
- this.recentMessages = [];
319
316
  }
320
317
  }
321
318