hedgequantx 2.9.232 → 2.9.234

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.232",
3
+ "version": "2.9.234",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -15,22 +15,44 @@
15
15
 
16
16
  const chalk = require('chalk');
17
17
 
18
- // Color helpers for consistent styling
18
+ // Rich color helpers for professional HF display
19
19
  const C = {
20
- sym: (s) => chalk.cyan.bold(s),
21
- price: (p) => chalk.white.bold(p),
22
- long: (s) => chalk.green.bold(s),
23
- short: (s) => chalk.red.bold(s),
24
- bull: (s) => chalk.green(s),
25
- bear: (s) => chalk.red(s),
26
- val: (v) => chalk.blue(v),
27
- valHigh: (v) => chalk.magenta.bold(v),
28
- ok: (s) => chalk.green(s),
29
- warn: (s) => chalk.yellow(s),
30
- danger: (s) => chalk.red.bold(s),
31
- dim: (s) => chalk.dim(s),
32
- info: (s) => chalk.gray(s),
33
- signal: (s) => chalk.yellow.bold(s),
20
+ // Symbol - bright cyan
21
+ sym: (s) => chalk.hex('#00FFFF').bold(s),
22
+
23
+ // Price - bright white/yellow
24
+ price: (p) => chalk.hex('#FFFFFF').bold(p),
25
+ priceUp: (p) => chalk.hex('#00FF00').bold(p),
26
+ priceDown: (p) => chalk.hex('#FF4444').bold(p),
27
+
28
+ // Direction
29
+ long: (s) => chalk.hex('#00FF00').bold(s),
30
+ short: (s) => chalk.hex('#FF4444').bold(s),
31
+ bull: (s) => chalk.hex('#00DD00')(s),
32
+ bear: (s) => chalk.hex('#FF6666')(s),
33
+
34
+ // Values & metrics
35
+ val: (v) => chalk.hex('#00BFFF')(v), // Deep sky blue
36
+ valHigh: (v) => chalk.hex('#FF00FF').bold(v), // Magenta for extreme
37
+ zscore: (v) => chalk.hex('#FFD700')(v), // Gold for Z-score
38
+
39
+ // Status indicators
40
+ ok: (s) => chalk.hex('#00FF00')(s),
41
+ warn: (s) => chalk.hex('#FFA500').bold(s), // Orange warning
42
+ danger: (s) => chalk.hex('#FF0000').bold(s), // Red danger
43
+
44
+ // Neutral/info
45
+ dim: (s) => chalk.hex('#888888')(s),
46
+ info: (s) => chalk.hex('#AAAAAA')(s),
47
+ muted: (s) => chalk.hex('#666666')(s),
48
+
49
+ // Special states
50
+ signal: (s) => chalk.hex('#FFFF00').bold(s), // Bright yellow signal
51
+ toxic: (s) => chalk.hex('#FF0000').bgHex('#330000').bold(s),
52
+
53
+ // Labels
54
+ label: (s) => chalk.hex('#888888')(s),
55
+ separator: () => chalk.hex('#444444')('|'),
34
56
  };
35
57
 
36
58
  const CONFIG = {
@@ -86,8 +108,9 @@ class SmartLogsEngine {
86
108
  const priceNum = state.price || 0;
87
109
  const lastPrice = this._lastPrice || priceNum;
88
110
  const priceDiff = priceNum - lastPrice;
89
- const priceDir = priceDiff > 0.01 ? '▲' : priceDiff < -0.01 ? '▼' : '';
90
- const priceDirColor = priceDiff > 0 ? C.bull : priceDiff < 0 ? C.bear : C.dim;
111
+ const priceDir = priceDiff > 0.01 ? '▲' : priceDiff < -0.01 ? '▼' : '';
112
+ const priceDirColor = priceDiff > 0 ? C.bull : priceDiff < 0 ? C.bear : C.muted;
113
+ const priceDisplay = priceDiff > 0 ? C.priceUp(price) : priceDiff < 0 ? C.priceDown(price) : C.price(price);
91
114
  this._lastPrice = priceNum;
92
115
 
93
116
  // Track tick velocity
@@ -96,13 +119,17 @@ class SmartLogsEngine {
96
119
  this._lastTicks = tickCount || bars || 0;
97
120
 
98
121
  // Not enough data - still warming up
99
- const dataPoints = bars || tickCount || 0;
100
- if (dataPoints < 50 || !price) {
101
- const pct = Math.min(100, Math.round((dataPoints / 50) * 100));
102
- const remaining = 50 - dataPoints;
122
+ // HQX Scalping is a TICK strategy - needs minimum ticks for QUANT models
123
+ const tickTotal = tickCount || 0;
124
+ const minTicks = 500; // Minimum ticks needed for Z-score, VPIN, OFI calculations
125
+
126
+ if (tickTotal < minTicks || !price) {
127
+ const pct = Math.min(100, Math.round((tickTotal / minTicks) * 100));
128
+ const remaining = minTicks - tickTotal;
129
+ const pctColor = pct < 30 ? C.warn : pct < 70 ? C.val : C.ok;
103
130
  return {
104
131
  type: 'system',
105
- message: `[${C.sym(sym)}] ${price ? C.price(price) : '-.--'} | Calibrating ${C.val(pct + '%')} | ${remaining} samples to ready | +${tickVelocity}/s`,
132
+ message: `[${C.sym(sym)}] ${price ? C.price(price) : C.dim('-.--')} ${C.separator()} ${C.label('Calibrating')} ${pctColor(pct + '%')} ${C.separator()} ${C.val(tickTotal + '/' + minTicks)} ${C.label('ticks')} ${C.separator()} ${C.val('+' + tickVelocity + '/s')}`,
106
133
  logToSession: false
107
134
  };
108
135
  }
@@ -114,38 +141,46 @@ class SmartLogsEngine {
114
141
  const buyPctRound = Math.round(buyPct || 50);
115
142
  const deltaRound = Math.round(delta || 0);
116
143
 
117
- // Z-Score color based on level
144
+ // Z-Score color based on level - more vivid
118
145
  const zColor = absZ >= CONFIG.Z_EXTREME ? C.valHigh :
119
- absZ >= CONFIG.Z_HIGH ? C.warn :
120
- absZ >= CONFIG.Z_BUILDING ? C.val : C.dim;
146
+ absZ >= CONFIG.Z_HIGH ? C.signal :
147
+ absZ >= CONFIG.Z_BUILDING ? C.zscore : C.muted;
121
148
  const zStr = zColor(`${zScore.toFixed(2)}σ`);
122
149
 
123
- // OFI color based on direction
124
- const ofiColor = ofi > CONFIG.OFI_THRESHOLD ? C.bull :
125
- ofi < -CONFIG.OFI_THRESHOLD ? C.bear : C.dim;
150
+ // OFI color based on direction - more vivid
151
+ const ofiColor = ofi > CONFIG.OFI_STRONG ? C.long :
152
+ ofi > CONFIG.OFI_THRESHOLD ? C.bull :
153
+ ofi < -CONFIG.OFI_STRONG ? C.short :
154
+ ofi < -CONFIG.OFI_THRESHOLD ? C.bear : C.muted;
126
155
  const ofiStr = ofiColor(`${ofi >= 0 ? '+' : ''}${ofiPct}%`);
127
156
 
128
- // VPIN color based on toxicity
129
- const vpinColor = vpin > CONFIG.VPIN_TOXIC ? C.danger :
157
+ // VPIN color based on toxicity - more vivid
158
+ const vpinColor = vpin > CONFIG.VPIN_TOXIC ? C.toxic :
130
159
  vpin > CONFIG.VPIN_ELEVATED ? C.warn : C.ok;
131
160
  const vpinStr = vpinColor(`${vpinPct}%`);
132
161
 
133
- // Delta (buy-sell imbalance) display
134
- const deltaColor = deltaRound > 0 ? C.bull : deltaRound < 0 ? C.bear : C.dim;
162
+ // Delta (buy-sell imbalance) display - more vivid
163
+ const deltaAbs = Math.abs(deltaRound);
164
+ const deltaColor = deltaRound > 50 ? C.long : deltaRound > 0 ? C.bull :
165
+ deltaRound < -50 ? C.short : deltaRound < 0 ? C.bear : C.muted;
135
166
  const deltaStr = deltaColor(`${deltaRound > 0 ? '+' : ''}${deltaRound}`);
136
167
 
168
+ // Buy percentage color
169
+ const buyColor = buyPctRound > 60 ? C.bull : buyPctRound < 40 ? C.bear : C.muted;
170
+ const buyStr = buyColor(`${buyPctRound}%`);
171
+
137
172
  // Active position - show position management with unique data
138
173
  if (position !== 0) {
139
174
  const isLong = position > 0;
140
- const side = isLong ? C.long('LONG') : C.short('SHORT');
175
+ const side = isLong ? C.long('LONG') : C.short('SHORT');
141
176
  const flowFavor = (isLong && ofi > 0) || (!isLong && ofi < 0);
142
- const flowLabel = flowFavor ? C.ok('aligned') : C.warn('adverse');
177
+ const flowLabel = flowFavor ? C.ok('aligned') : C.warn('adverse');
143
178
  const exitClose = absZ < 0.5;
144
- const exitInfo = exitClose ? C.warn('EXIT ZONE') : 'holding';
179
+ const exitInfo = exitClose ? C.warn('EXIT ZONE') : C.ok('holding');
145
180
 
146
181
  return {
147
182
  type: 'trade',
148
- message: `[${C.sym(sym)}] ${side} ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} ${exitInfo} | Δ:${deltaStr} | Flow:${flowLabel}`,
183
+ message: `[${C.sym(sym)}] ${side} ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${exitInfo} ${C.separator()} ${C.label('Δ:')}${deltaStr} ${C.separator()} ${flowLabel}`,
149
184
  logToSession: false
150
185
  };
151
186
  }
@@ -159,31 +194,31 @@ class SmartLogsEngine {
159
194
 
160
195
  // VPIN toxic - highest priority blocker
161
196
  if (vpin > CONFIG.VPIN_TOXIC) {
162
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | VPIN:${vpinStr} ${C.danger('TOXIC')} | Z:${zStr} | Δ:${deltaStr} | Hold`;
197
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('VPIN:')}${vpinStr} ${C.toxic('TOXIC')} ${C.separator()} ${C.label('Z:')}${zStr} ${C.separator()} ${C.label('Δ:')}${deltaStr} ${C.separator()} ${C.danger('NO ENTRY')}`;
163
198
  logType = 'risk';
164
199
  }
165
200
  // Z-Score extreme + OFI confirms = SIGNAL
166
201
  else if (absZ >= CONFIG.Z_EXTREME &&
167
202
  ((zScore < 0 && ofi > CONFIG.OFI_THRESHOLD) || (zScore > 0 && ofi < -CONFIG.OFI_THRESHOLD))) {
168
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} ${C.signal('EXTREME')} | OFI:${ofiStr} ${C.ok('✓')} | ${dirColor(direction)} SIGNAL`;
203
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${C.signal('EXTREME')} ${C.separator()} ${C.label('OFI:')}${ofiStr} ${C.ok('✓')} ${C.separator()} ${dirColor('► ' + direction + ' SIGNAL')}`;
169
204
  logType = 'signal';
170
205
  }
171
206
  // Z-Score extreme but OFI doesn't confirm
172
207
  else if (absZ >= CONFIG.Z_EXTREME) {
173
- const ofiNeed = zScore < 0 ? `need >${15}%` : `need <-${15}%`;
174
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} ${C.signal('!')} | OFI:${ofiStr} ${ofiNeed} | ${C.warn('pending')}`;
208
+ const ofiNeed = zScore < 0 ? C.dim('need >15%') : C.dim('need <-15%');
209
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${C.signal('!')} ${C.separator()} ${C.label('OFI:')}${ofiStr} ${ofiNeed} ${C.separator()} ${C.warn('◐ PENDING')}`;
175
210
  logType = 'signal';
176
211
  }
177
212
  // Z-Score high - setup forming
178
213
  else if (absZ >= CONFIG.Z_HIGH) {
179
214
  const needed = (CONFIG.Z_EXTREME - absZ).toFixed(2);
180
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} +${needed}σ to signal | OFI:${ofiStr} | Δ:${deltaStr}`;
215
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${C.val('+' + needed + 'σ')} ${C.label('to signal')} ${C.separator()} ${C.label('OFI:')}${ofiStr} ${C.separator()} ${C.label('Δ:')}${deltaStr}`;
181
216
  }
182
217
  // Z-Score building
183
218
  else if (absZ >= CONFIG.Z_BUILDING) {
184
219
  const needed = (CONFIG.Z_HIGH - absZ).toFixed(2);
185
- const bias = zScore < 0 ? 'bid' : 'ask';
186
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} ${bias} pressure | +${needed}σ to setup | Δ:${deltaStr}`;
220
+ const bias = zScore < 0 ? C.bull('bid') : C.bear('ask');
221
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${bias} ${C.separator()} ${C.val('+' + needed + 'σ')} ${C.label('to setup')} ${C.separator()} ${C.label('Δ:')}${deltaStr}`;
187
222
  }
188
223
  // Z-Score neutral - scanning
189
224
  else {
@@ -192,18 +227,18 @@ class SmartLogsEngine {
192
227
  let context;
193
228
  switch (infoType) {
194
229
  case 0:
195
- context = `Δ:${deltaStr} | Buy:${buyPctRound}%`;
230
+ context = `${C.label('Δ:')}${deltaStr} ${C.separator()} ${C.label('Buy:')}${buyStr}`;
196
231
  break;
197
232
  case 1:
198
- context = `VPIN:${vpinStr} | OFI:${ofiStr}`;
233
+ context = `${C.label('VPIN:')}${vpinStr} ${C.separator()} ${C.label('OFI:')}${ofiStr}`;
199
234
  break;
200
235
  case 2:
201
- context = `${tickVelocity} ticks/s | Δ:${deltaStr}`;
236
+ context = `${C.val(tickVelocity)} ${C.label('ticks/s')} ${C.separator()} ${C.label('Δ:')}${deltaStr}`;
202
237
  break;
203
238
  default:
204
- context = `OFI:${ofiStr} | Buy:${buyPctRound}%`;
239
+ context = `${C.label('OFI:')}${ofiStr} ${C.separator()} ${C.label('Buy:')}${buyStr}`;
205
240
  }
206
- message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} scanning | ${context}`;
241
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${priceDisplay} ${C.separator()} ${C.label('Z:')}${zStr} ${C.muted('scanning')} ${C.separator()} ${context}`;
207
242
  }
208
243
 
209
244
  return { type: logType, message, logToSession: logType === 'signal' };