hedgequantx 2.9.215 → 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 +1 -1
- package/src/lib/smart-logs-engine.js +80 -19
package/package.json
CHANGED
|
@@ -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
|
|
@@ -84,11 +127,14 @@ class SmartLogsEngine {
|
|
|
84
127
|
|
|
85
128
|
// Active position - same for all strategies
|
|
86
129
|
if (position !== 0) {
|
|
87
|
-
const
|
|
88
|
-
const
|
|
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}`);
|
|
89
135
|
return {
|
|
90
136
|
type: 'trade',
|
|
91
|
-
message: `[${sym}] ${side} ACTIVE @ ${price} | Delta: ${
|
|
137
|
+
message: `[${C.sym(sym)}] ${side} ACTIVE @ ${C.price(price)} | Delta: ${deltaStr} | Flow: ${flowLabel}`,
|
|
92
138
|
logToSession: true
|
|
93
139
|
};
|
|
94
140
|
}
|
|
@@ -116,35 +162,37 @@ class SmartLogsEngine {
|
|
|
116
162
|
this.warmupLogged = true;
|
|
117
163
|
event = 'warmup';
|
|
118
164
|
const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
|
|
119
|
-
message = `[${sym}] 2B ready | ${bars} bars | ${warmupMsg}`;
|
|
165
|
+
message = `[${C.sym(sym)}] ${C.ok('2B ready')} | ${C.val(bars)} bars | ${C.dim(warmupMsg)}`;
|
|
120
166
|
logType = 'system';
|
|
121
167
|
}
|
|
122
168
|
// EVENT 2: New zone created
|
|
123
169
|
else if (zones > this.lastZones && zones > 0) {
|
|
124
170
|
event = 'new_zone';
|
|
125
171
|
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
126
|
-
message = `[${sym}] ${price} | Zone
|
|
172
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | ${C.zone('Zone #' + zones)} | ${C.signal(signalMsg)}`;
|
|
127
173
|
logType = 'signal';
|
|
128
174
|
}
|
|
129
175
|
// EVENT 3: New swing detected
|
|
130
176
|
else if (swings > this.lastSwings && swings > 0) {
|
|
131
177
|
event = 'new_swing';
|
|
132
178
|
const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
|
|
133
|
-
message = `[${sym}] ${price} | Swing
|
|
179
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | ${C.info('Swing #' + swings)} | ${C.dim(scanMsg)}`;
|
|
134
180
|
}
|
|
135
181
|
// EVENT 4: Zone approach (price near zone)
|
|
136
182
|
else if (nearZone && !this.lastNearZone && zones > 0) {
|
|
137
183
|
event = 'zone_approach';
|
|
138
184
|
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
139
|
-
message = `[${sym}] ${price} | Zone approach | ${signalMsg}`;
|
|
185
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | ${C.warn('Zone approach')} | ${C.signal(signalMsg)}`;
|
|
140
186
|
logType = 'signal';
|
|
141
187
|
}
|
|
142
188
|
// EVENT 5: Bias flip
|
|
143
189
|
else if (this.lastBias && trend !== this.lastBias && trend !== 'neutral' && this.lastBias !== 'neutral') {
|
|
144
190
|
event = 'bias_flip';
|
|
145
|
-
const arrow = trend === 'bullish' ?
|
|
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);
|
|
146
194
|
const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, trend);
|
|
147
|
-
message = `[${sym}] ${arrow} ${
|
|
195
|
+
message = `[${C.sym(sym)}] ${arrow} ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
|
|
148
196
|
}
|
|
149
197
|
|
|
150
198
|
// Update state tracking
|
|
@@ -176,12 +224,22 @@ class SmartLogsEngine {
|
|
|
176
224
|
let logType = 'analysis';
|
|
177
225
|
let message = null;
|
|
178
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
|
+
|
|
179
237
|
// EVENT 1: Warmup complete (250 ticks for QUANT models)
|
|
180
238
|
if (ticks >= CONFIG.QUANT_WARMUP_TICKS && !this.warmupLogged) {
|
|
181
239
|
this.warmupLogged = true;
|
|
182
240
|
event = 'warmup';
|
|
183
241
|
const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
|
|
184
|
-
message = `[${sym}] QUANT ready | ${ticks} ticks | ${warmupMsg}`;
|
|
242
|
+
message = `[${C.sym(sym)}] ${C.ok('QUANT ready')} | ${C.val(ticks)} ticks | ${C.dim(warmupMsg)}`;
|
|
185
243
|
logType = 'system';
|
|
186
244
|
}
|
|
187
245
|
// EVENT 2: Z-Score regime change
|
|
@@ -193,34 +251,37 @@ class SmartLogsEngine {
|
|
|
193
251
|
|
|
194
252
|
if (zRegime === 'extreme') {
|
|
195
253
|
logType = 'signal';
|
|
196
|
-
const dir = zScore < 0 ? 'LONG' : 'SHORT';
|
|
254
|
+
const dir = zScore < 0 ? C.long('LONG') : C.short('SHORT');
|
|
197
255
|
const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
|
|
198
|
-
message = `[${sym}] ${price} | Z: ${zScore.
|
|
256
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.signal('EXTREME')} | ${dir} | ${C.signal(signalMsg)}`;
|
|
199
257
|
} else if (zRegime === 'high') {
|
|
200
258
|
logType = 'signal';
|
|
201
|
-
message = `[${sym}] ${price} | Z: ${zScore.
|
|
259
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.warn('HIGH')} | ${C.dim(instrumentMsg)}`;
|
|
202
260
|
} else if (zRegime === 'building') {
|
|
203
|
-
message = `[${sym}] ${price} | Z
|
|
261
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.info('building')} | ${C.dim(instrumentMsg)}`;
|
|
204
262
|
} else {
|
|
205
263
|
const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
|
|
206
|
-
message = `[${sym}] ${price} | Z normalized | ${scanMsg}`;
|
|
264
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${C.ok('normalized')} | ${C.dim(scanMsg)}`;
|
|
207
265
|
}
|
|
208
266
|
}
|
|
209
267
|
// EVENT 3: Bias flip (OFI direction change)
|
|
210
268
|
else if (this.lastBias !== null && bias !== this.lastBias && bias !== 'neutral' && this.lastBias !== 'neutral') {
|
|
211
269
|
event = 'bias_flip';
|
|
212
|
-
const arrow = bias === 'bullish' ?
|
|
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);
|
|
213
273
|
const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, bias);
|
|
214
|
-
message = `[${sym}] ${arrow} OFI: ${
|
|
274
|
+
message = `[${C.sym(sym)}] ${arrow} OFI: ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
|
|
215
275
|
}
|
|
216
276
|
// EVENT 4: VPIN toxicity change
|
|
217
277
|
else if (this.lastVpinToxic !== null && vpinToxic !== this.lastVpinToxic) {
|
|
218
278
|
event = 'vpin';
|
|
279
|
+
const vpinPct = (vpin * 100).toFixed(0);
|
|
219
280
|
if (vpinToxic) {
|
|
220
|
-
message = `[${sym}] ${price} | VPIN
|
|
281
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.danger(vpinPct + '%')} ${C.danger('TOXIC')} - informed flow`;
|
|
221
282
|
logType = 'risk';
|
|
222
283
|
} else {
|
|
223
|
-
message = `[${sym}] ${price} | VPIN
|
|
284
|
+
message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.ok(vpinPct + '%')} ${C.ok('clean')} - normal flow`;
|
|
224
285
|
}
|
|
225
286
|
}
|
|
226
287
|
|