hedgequantx 2.9.159 → 2.9.161

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/dist/lib/data.jsc CHANGED
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.9.159",
3
+ "version": "2.9.161",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Smart Logs Engine - Institutional HFT Terminal
3
- * Professional hedge fund terminology with extensive message variety
4
- * Imports 50 messages per phase from strategy-specific files
2
+ * Smart Logs Engine - Event-Driven Intelligent Logs
3
+ * Only logs when something SIGNIFICANT happens in the strategy
4
+ * No spam, no repetitive messages - just real events
5
5
  */
6
6
 
7
7
  'use strict';
@@ -10,7 +10,12 @@ const chalk = require('chalk');
10
10
  const HQX2B = require('./smart-logs-hqx2b');
11
11
  const QUANT = require('./smart-logs-quant');
12
12
 
13
- const CONFIG = { MAX_RECENT: 80, SESSION_LOG_INTERVAL: 10 };
13
+ const CONFIG = {
14
+ SESSION_LOG_INTERVAL: 10,
15
+ PRICE_CHANGE_TICKS: 4, // Log when price moves 4+ ticks
16
+ DELTA_CHANGE_THRESHOLD: 200, // Log when delta changes 200+
17
+ ZONE_APPROACH_TICKS: 5, // Log when within 5 ticks of zone
18
+ };
14
19
 
15
20
  const SYMBOLS = {
16
21
  NQ: 'NQ', MNQ: 'MNQ', ES: 'ES', MES: 'MES', YM: 'YM', MYM: 'MYM',
@@ -29,92 +34,155 @@ class SmartLogsEngine {
29
34
  this.strategyId = strategyId || 'hqx-2b';
30
35
  this.symbolCode = symbol;
31
36
  this.counter = 0;
32
- this.recent = [];
37
+ this.lastState = null;
38
+ this.lastLogTime = 0;
33
39
  }
34
40
 
35
41
  setSymbol(s) { this.symbolCode = s; }
36
42
 
37
- _unique(gen, d) {
38
- let msg, i = 0;
39
- do { msg = gen(d); i++; } while (this.recent.includes(msg) && i < 15);
40
- this.recent.push(msg);
41
- if (this.recent.length > CONFIG.MAX_RECENT) this.recent.shift();
42
- return msg;
43
+ /**
44
+ * Detect significant events by comparing current vs previous state
45
+ * Returns array of events sorted by priority (1 = highest)
46
+ */
47
+ _detectEvents(current, previous) {
48
+ if (!previous) return [{ type: 'init', priority: 5 }];
49
+
50
+ const events = [];
51
+ const tickSize = 0.25; // Default, should come from config
52
+
53
+ // New bar created
54
+ if (current.bars > previous.bars) {
55
+ events.push({ type: 'newBar', priority: 4, data: { count: current.bars } });
56
+ }
57
+
58
+ // New swing detected
59
+ if (current.swings > previous.swings) {
60
+ events.push({ type: 'newSwing', priority: 2, data: { count: current.swings } });
61
+ }
62
+
63
+ // New zone created
64
+ if (current.zones > previous.zones) {
65
+ events.push({ type: 'newZone', priority: 1, data: { count: current.zones } });
66
+ }
67
+
68
+ // Zone approached (became near when wasn't before)
69
+ if (current.nearZone && !previous.nearZone) {
70
+ events.push({ type: 'approachZone', priority: 1, data: {
71
+ zonePrice: current.nearestSupport || current.nearestResistance
72
+ }});
73
+ }
74
+
75
+ // Bias flip (bull <-> bear)
76
+ if (previous.trend && current.trend !== previous.trend &&
77
+ current.trend !== 'neutral' && previous.trend !== 'neutral') {
78
+ events.push({ type: 'biasFlip', priority: 2, data: {
79
+ from: previous.trend, to: current.trend
80
+ }});
81
+ }
82
+
83
+ // Significant price move (4+ ticks)
84
+ if (current.price > 0 && previous.price > 0) {
85
+ const priceDiff = Math.abs(current.price - previous.price);
86
+ const ticksMoved = priceDiff / tickSize;
87
+ if (ticksMoved >= CONFIG.PRICE_CHANGE_TICKS) {
88
+ events.push({ type: 'priceMove', priority: 3, data: {
89
+ from: previous.price, to: current.price, ticks: ticksMoved
90
+ }});
91
+ }
92
+ }
93
+
94
+ // Delta shift (significant change in order flow)
95
+ const deltaDiff = Math.abs(current.delta - (previous.delta || 0));
96
+ if (deltaDiff >= CONFIG.DELTA_CHANGE_THRESHOLD) {
97
+ events.push({ type: 'deltaShift', priority: 3, data: {
98
+ from: previous.delta || 0, to: current.delta
99
+ }});
100
+ }
101
+
102
+ // Sort by priority (lower = more important)
103
+ return events.sort((a, b) => a.priority - b.priority);
104
+ }
105
+
106
+ /**
107
+ * Format event into display message
108
+ */
109
+ _formatEvent(event, state) {
110
+ const sym = getSym(this.symbolCode);
111
+ const price = state.price > 0 ? state.price.toFixed(2) : '-.--';
112
+ const T = this.strategyId === 'hqx-2b' ? HQX2B : QUANT;
113
+
114
+ switch (event.type) {
115
+ case 'init':
116
+ return { type: 'system', message: T.init({ sym, bars: state.bars, swings: state.swings, zones: state.zones }) };
117
+
118
+ case 'newBar':
119
+ return { type: 'system', message: T.newBar({ sym, bars: state.bars, price }) };
120
+
121
+ case 'newSwing':
122
+ return { type: 'analysis', message: T.newSwing({ sym, swings: state.swings, price }) };
123
+
124
+ case 'newZone':
125
+ return { type: 'signal', message: T.newZone({ sym, zones: state.zones, price }) };
126
+
127
+ case 'approachZone':
128
+ const zonePrice = event.data.zonePrice;
129
+ const distance = zonePrice ? Math.abs(state.price - zonePrice) / 0.25 : 0;
130
+ return { type: 'signal', message: T.approachZone({ sym, price, zonePrice: zonePrice?.toFixed(2) || 'N/A', distance: distance.toFixed(1) }) };
131
+
132
+ case 'biasFlip':
133
+ return { type: 'analysis', message: T.biasFlip({ sym, from: event.data.from, to: event.data.to, delta: state.delta }) };
134
+
135
+ case 'priceMove':
136
+ const dir = event.data.to > event.data.from ? 'up' : 'down';
137
+ return { type: 'analysis', message: T.priceMove({ sym, price, dir, ticks: event.data.ticks.toFixed(1) }) };
138
+
139
+ case 'deltaShift':
140
+ return { type: 'analysis', message: T.deltaShift({ sym, from: event.data.from, to: event.data.to }) };
141
+
142
+ default:
143
+ return null;
144
+ }
43
145
  }
44
146
 
45
147
  getLog(state = {}) {
46
148
  this.counter++;
47
- const { trend = 'neutral', position = 0, zones = 0, swings = 0, bars = 0,
48
- price = 0, delta = 0, buyPct = 50, tickCount = 0,
49
- zScore = 0, vpin = 0, ofi = 0, setupForming = false } = state;
50
-
51
- const isQuant = this.strategyId !== 'hqx-2b';
52
- const T = isQuant ? QUANT : HQX2B;
53
-
54
- const d = {
55
- sym: getSym(this.symbolCode),
56
- price: price > 0 ? price.toFixed(2) : '-.--',
57
- delta, zones, swings, bars,
58
- ticks: tickCount > 1000 ? `${(tickCount/1000).toFixed(0)}k` : String(tickCount),
59
- // Real QUANT metrics from strategy (keep sign for direction)
60
- zScore: zScore.toFixed(2),
61
- zScoreAbs: Math.abs(zScore).toFixed(2),
62
- vpin: (vpin * 100).toFixed(0),
63
- ofi: ofi > 0 ? `+${ofi.toFixed(0)}` : ofi.toFixed(0),
64
- rawZScore: zScore, // For direction calculation
65
- };
149
+ const { position = 0, delta = 0 } = state;
150
+ const sym = getSym(this.symbolCode);
151
+ const price = state.price > 0 ? state.price.toFixed(2) : '-.--';
66
152
 
153
+ // Active position - always log
67
154
  if (position !== 0) {
68
155
  const side = position > 0 ? 'LONG' : 'SHORT';
69
156
  const pnl = (position > 0 && delta > 0) || (position < 0 && delta < 0) ? 'FAVOR' : 'ADVERSE';
70
157
  return {
71
158
  type: 'trade',
72
- message: `▶ [${d.sym}] ${side} ACTIVE @ ${d.price} | OFI: ${delta > 0 ? '+' : ''}${delta} | Flow: ${pnl}`,
73
- logToSession: this.counter % CONFIG.SESSION_LOG_INTERVAL === 0
159
+ message: `[${sym}] ${side} ACTIVE @ ${price} | Delta: ${delta > 0 ? '+' : ''}${delta} | Flow: ${pnl}`,
160
+ logToSession: true
74
161
  };
75
162
  }
76
163
 
77
- // Determine phase and message type based on strategy
78
- let gen, type;
79
-
80
- if (isQuant) {
81
- // QUANT: tick-based, uses zScore/vpin/ofi
82
- const minTicks = 50;
83
- const isBuilding = bars < minTicks;
84
- const bull = trend === 'bullish' || zScore > 1.5 || buyPct > 58;
85
- const bear = trend === 'bearish' || zScore < -1.5 || buyPct < 42;
86
- const ready = Math.abs(zScore) > 2.0 && setupForming;
87
-
88
- if (ready) { gen = T.ready; type = 'signal'; }
89
- else if (isBuilding) { gen = T.building; type = 'system'; }
90
- else if (bull) { gen = T.bull; type = 'bullish'; }
91
- else if (bear) { gen = T.bear; type = 'bearish'; }
92
- else { gen = T.zones; type = 'analysis'; } // zones = analysis for QUANT
93
- } else {
94
- // HQX-2B: bar-based, uses zones/swings
95
- const minBars = 3;
96
- const isBuilding = bars < minBars;
97
- const hasZones = zones > 0 || swings >= 2;
98
- const bull = trend === 'bullish' || buyPct > 55;
99
- const bear = trend === 'bearish' || buyPct < 45;
100
- const ready = setupForming && zones > 0;
101
-
102
- if (ready) { gen = T.ready; type = 'signal'; }
103
- else if (isBuilding) { gen = T.building; type = 'system'; }
104
- else if (bull) { gen = T.bull; type = 'bullish'; }
105
- else if (bear) { gen = T.bear; type = 'bearish'; }
106
- else if (hasZones) { gen = T.zones; type = 'analysis'; }
107
- else { gen = T.neutral; type = 'analysis'; }
164
+ // Detect events
165
+ const events = this._detectEvents(state, this.lastState);
166
+ this.lastState = { ...state };
167
+
168
+ // No events = no log (SILENCE)
169
+ if (events.length === 0) {
170
+ return null;
108
171
  }
109
172
 
110
- return {
111
- type,
112
- message: this._unique(gen, d),
113
- logToSession: this.counter % CONFIG.SESSION_LOG_INTERVAL === 0
114
- };
173
+ // Format the most important event
174
+ const log = this._formatEvent(events[0], state);
175
+ if (log) {
176
+ log.logToSession = this.counter % CONFIG.SESSION_LOG_INTERVAL === 0;
177
+ }
178
+ return log;
115
179
  }
116
180
 
117
- reset() { this.recent = []; this.counter = 0; }
181
+ reset() {
182
+ this.lastState = null;
183
+ this.counter = 0;
184
+ this.lastLogTime = 0;
185
+ }
118
186
  }
119
187
 
120
188
  function createEngine(strategyId, symbol) { return new SmartLogsEngine(strategyId, symbol); }
@@ -1,334 +1,57 @@
1
1
  /**
2
- * HQX-2B Liquidity Sweep - Message Templates
3
- * 50 messages per phase - ALL using REAL data from strategy
4
- * Real Variables: d.sym, d.price, d.delta, d.zones, d.swings, d.bars, d.ticks
5
- * WITH COLORS: cyan=building, yellow=zones, green=bull, red=bear, gray=neutral
2
+ * HQX-2B Liquidity Sweep - Event-Based Messages
3
+ * Each function = one specific event type
4
+ * Messages reflect REAL strategy state, no random spam
6
5
  */
7
6
  'use strict';
8
7
 
9
8
  const chalk = require('chalk');
10
- const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
11
9
 
12
10
  module.exports = {
13
- building: (d) => pick([
14
- chalk.cyan(`[${d.sym}]`) + ` Microstructure scan active | ${chalk.white(d.bars)} bars | ${chalk.white(d.swings)} swing pivots | Zone mapping init`,
15
- chalk.cyan(`[${d.sym}]`) + ` Order block detection | ${chalk.white(d.ticks)} ticks analyzed | Institutional footprint search`,
16
- chalk.cyan(`[${d.sym}]`) + ` Liquidity topology build | ${chalk.white(d.swings)} pivots mapped | Stop cluster identification`,
17
- chalk.cyan(`[${d.sym}]`) + ` Structure analysis | ${chalk.white(d.bars)} OHLC bars | Delta: ${chalk.white(d.delta)} | Zone formation`,
18
- chalk.cyan(`[${d.sym}]`) + ` Sweep zone calibration | ${chalk.white(d.ticks)} tick sample | ${chalk.white(d.swings)} swing nodes`,
19
- chalk.cyan(`[${d.sym}]`) + ` Institutional level mapping | ${chalk.white(d.bars)} bars processed | Building heatmap`,
20
- chalk.cyan(`[${d.sym}]`) + ` Market structure parse | ${chalk.white(d.swings)} pivots detected | Liquidity map loading`,
21
- chalk.cyan(`[${d.sym}]`) + ` Price action decomposition | ${chalk.white(d.ticks)} ticks | Swing extraction running`,
22
- chalk.cyan(`[${d.sym}]`) + ` DOM reconstruction active | ${chalk.white(d.ticks)} ticks | Depth analysis init`,
23
- chalk.cyan(`[${d.sym}]`) + ` Volume profile build | ${chalk.white(d.bars)} bars | POC/VAH/VAL computation`,
24
- chalk.cyan(`[${d.sym}]`) + ` Iceberg detection scan | ${chalk.white(d.ticks)} tick flow | Hidden liquidity search`,
25
- chalk.cyan(`[${d.sym}]`) + ` Stop cluster triangulation | ${chalk.white(d.swings)} swings | Sweep target ID`,
26
- chalk.cyan(`[${d.sym}]`) + ` Auction theory analysis | ${chalk.white(d.bars)} bars | Value area computation`,
27
- chalk.cyan(`[${d.sym}]`) + ` Order flow calibration | ${chalk.white(d.ticks)} ticks | Aggressor tagging active`,
28
- chalk.cyan(`[${d.sym}]`) + ` Footprint initialization | ${chalk.white(d.bars)} bars | Delta/volume decomposition`,
29
- chalk.cyan(`[${d.sym}]`) + ` Swing structure mapping | ${chalk.white(d.swings)} pivots | HH/HL/LH/LL detection`,
30
- chalk.cyan(`[${d.sym}]`) + ` Liquidity heatmap build | ${chalk.white(d.ticks)} observations | Cluster density calc`,
31
- chalk.cyan(`[${d.sym}]`) + ` Market profile loading | ${chalk.white(d.bars)} TPOs | Distribution analysis`,
32
- chalk.cyan(`[${d.sym}]`) + ` Absorption scan active | ${chalk.white(d.ticks)} ticks | Passive order detection`,
33
- chalk.cyan(`[${d.sym}]`) + ` Momentum calibration | ${chalk.white(d.bars)} bars | Velocity/acceleration calc`,
34
- chalk.cyan(`[${d.sym}]`) + ` Building structure | ${chalk.white(d.bars)} bars | ${chalk.white(d.ticks)} ticks | Warmup`,
35
- chalk.cyan(`[${d.sym}]`) + ` Zone detection init | ${chalk.white(d.swings)} swings found | Liquidity mapping`,
36
- chalk.cyan(`[${d.sym}]`) + ` Liquidity scan running | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.bars)} bars`,
37
- chalk.cyan(`[${d.sym}]`) + ` Order book analysis | ${chalk.white(d.ticks)} ticks | Bid/ask imbalance detect`,
38
- chalk.cyan(`[${d.sym}]`) + ` Pivot detection active | ${chalk.white(d.swings)} swings | ${chalk.white(d.bars)} bars`,
39
- chalk.cyan(`[${d.sym}]`) + ` Imbalance scan | ${chalk.white(d.ticks)} ticks | Delta: ${chalk.white(d.delta)} | Flow`,
40
- chalk.cyan(`[${d.sym}]`) + ` Structure warmup | ${chalk.white(d.bars)} bars | ${chalk.white(d.swings)} pivots | Zone cal`,
41
- chalk.cyan(`[${d.sym}]`) + ` Flow analysis init | ${chalk.white(d.ticks)} ticks | Order flow model loading`,
42
- chalk.cyan(`[${d.sym}]`) + ` Level mapping active | ${chalk.white(d.bars)} bars | ${chalk.white(d.swings)} swings`,
43
- chalk.cyan(`[${d.sym}]`) + ` Sweep target scan | ${chalk.white(d.ticks)} ticks analyzed | Stop cluster map`,
44
- chalk.cyan(`[${d.sym}]`) + ` Institutional footprint | ${chalk.white(d.bars)} bars | Delta: ${chalk.white(d.delta)}`,
45
- chalk.cyan(`[${d.sym}]`) + ` Stop hunt mapping | ${chalk.white(d.swings)} pivots detected | Trap zone ID`,
46
- chalk.cyan(`[${d.sym}]`) + ` Liquidity pool scan | ${chalk.white(d.ticks)} ticks | Resting order detection`,
47
- chalk.cyan(`[${d.sym}]`) + ` Delta profile build | ${chalk.white(d.bars)} bars | ${chalk.white(d.delta)} cumulative`,
48
- chalk.cyan(`[${d.sym}]`) + ` Zone warmup phase | ${chalk.white(d.swings)} swings | ${chalk.white(d.ticks)} ticks`,
49
- chalk.cyan(`[${d.sym}]`) + ` Tick analysis running | ${chalk.white(d.ticks)} processed | ${chalk.white(d.bars)} bars`,
50
- chalk.cyan(`[${d.sym}]`) + ` Swing detection active | ${chalk.white(d.swings)} found | Delta: ${chalk.white(d.delta)}`,
51
- chalk.cyan(`[${d.sym}]`) + ` Order flow init | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.bars)} bars | Model`,
52
- chalk.cyan(`[${d.sym}]`) + ` Structure mapping | ${chalk.white(d.bars)} bars | ${chalk.white(d.swings)} pivots`,
53
- chalk.cyan(`[${d.sym}]`) + ` Liquidity calibration | ${chalk.white(d.ticks)} ticks | Building sweep targets`,
54
- chalk.cyan(`[${d.sym}]`) + ` Building zones | ${chalk.white(d.bars)} bars | ${chalk.white(d.swings)} swings | Warmup`,
55
- chalk.cyan(`[${d.sym}]`) + ` Flow warmup phase | ${chalk.white(d.ticks)} ticks | Delta: ${chalk.white(d.delta)}`,
56
- chalk.cyan(`[${d.sym}]`) + ` Pivot scan active | ${chalk.white(d.swings)} detected | ${chalk.white(d.bars)} bars`,
57
- chalk.cyan(`[${d.sym}]`) + ` DOM analysis running | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.swings)} pivots`,
58
- chalk.cyan(`[${d.sym}]`) + ` Level detection | ${chalk.white(d.bars)} bars | ${chalk.white(d.ticks)} ticks | Zone ID`,
59
- chalk.cyan(`[${d.sym}]`) + ` Sweep calibration | ${chalk.white(d.swings)} swings | Delta: ${chalk.white(d.delta)}`,
60
- chalk.cyan(`[${d.sym}]`) + ` Structure init | ${chalk.white(d.bars)} bars | ${chalk.white(d.ticks)} ticks | Model`,
61
- chalk.cyan(`[${d.sym}]`) + ` Zone mapping active | ${chalk.white(d.swings)} pivots | ${chalk.white(d.bars)} bars`,
62
- chalk.cyan(`[${d.sym}]`) + ` Liquidity warmup | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.swings)} swings`,
63
- chalk.cyan(`[${d.sym}]`) + ` Order analysis | ${chalk.white(d.bars)} bars | Delta: ${chalk.white(d.delta)} | Flow`,
64
- ]),
11
+ // Strategy initialized
12
+ init: (d) => chalk.cyan(`[${d.sym}]`) + ` Strategy ready | ${d.bars} bars | ${d.swings} swings | ${d.zones} zones`,
65
13
 
66
- zones: (d) => pick([
67
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' liquidity zones')} active | Sweep probability elevated`,
68
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Stop cluster proximity | ${chalk.yellow(d.zones + ' institutional levels')} in range`,
69
- chalk.yellow(`[${d.sym}]`) + ` Zone convergence alert | ${chalk.yellow(d.zones + ' sweep targets')} | OFI: ${chalk.white(d.delta)}`,
70
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Liquidity pool vulnerable | ${chalk.yellow(d.zones + ' zones')} | Monitoring`,
71
- chalk.yellow(`[${d.sym}]`) + ` Institutional zone active | ${chalk.yellow(d.zones + ' levels')} | ${chalk.white(d.swings)} swing confirm`,
72
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' stop clusters')} mapped | Sweep trigger watch`,
73
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | HVN proximity | ${chalk.yellow(d.zones + ' zones')} defended | Watching`,
74
- chalk.yellow(`[${d.sym}]`) + ` Resting liquidity detected | ${chalk.yellow(d.zones + ' pools')} | ${chalk.white(d.price)} approach`,
75
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' absorption zones')} | Delta: ${chalk.white(d.delta)}`,
76
- chalk.yellow(`[${d.sym}]`) + ` Stop hunt proximity alert | ${chalk.yellow(d.zones + ' targets')} | Price: ${chalk.white(d.price)}`,
77
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Iceberg cluster | ${chalk.yellow(d.zones + ' levels')} | Sweep imminent`,
78
- chalk.yellow(`[${d.sym}]`) + ` Liquidity vacuum ahead | ${chalk.yellow(d.zones + ' zones')} | Acceleration expected`,
79
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' institutional traps')} | OFI shift monitor`,
80
- chalk.yellow(`[${d.sym}]`) + ` POC rejection zone | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' confluences')} active`,
81
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Value area boundary | ${chalk.yellow(d.zones + ' levels')} | Breakout watch`,
82
- chalk.yellow(`[${d.sym}]`) + ` Delta divergence @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | Reversal setup`,
83
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Trapped traders | ${chalk.yellow(d.zones + ' levels')} | Squeeze potential`,
84
- chalk.yellow(`[${d.sym}]`) + ` Order block test active | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' institutional zones')}`,
85
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Liquidity grab zone | ${chalk.yellow(d.zones + ' stops')} vulnerable`,
86
- chalk.yellow(`[${d.sym}]`) + ` Fair value gap @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' imbalances')} | Fill expected`,
87
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | ${chalk.white(d.swings)} pivots confirm`,
88
- chalk.yellow(`[${d.sym}]`) + ` Sweep setup forming | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} | Delta: ${chalk.white(d.delta)}`,
89
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Liquidity ${chalk.yellow(d.zones + ' levels')} | ${chalk.white(d.ticks)} ticks`,
90
- chalk.yellow(`[${d.sym}]`) + ` Zone active alert | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' pools')} | ${chalk.white(d.swings)} swings`,
91
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' clusters')} | Delta: ${chalk.white(d.delta)} | Watch`,
92
- chalk.yellow(`[${d.sym}]`) + ` Stop proximity alert | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | Sweep watch`,
93
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Institutional ${chalk.yellow(d.zones + ' levels')} | ${chalk.white(d.swings)} pivots`,
94
- chalk.yellow(`[${d.sym}]`) + ` Liquidity @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | Delta: ${chalk.white(d.delta)}`,
95
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' sweep targets')} | ${chalk.white(d.ticks)} ticks confirm`,
96
- chalk.yellow(`[${d.sym}]`) + ` Zone test active | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | ${chalk.white(d.swings)} swings`,
97
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' traps')} detected | Delta: ${chalk.white(d.delta)}`,
98
- chalk.yellow(`[${d.sym}]`) + ` Cluster @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} active | ${chalk.white(d.ticks)} ticks`,
99
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' liquidity')} pools | ${chalk.white(d.swings)} pivots`,
100
- chalk.yellow(`[${d.sym}]`) + ` Sweep zone alert | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} mapped | Ready`,
101
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' pools')} vulnerable | Delta: ${chalk.white(d.delta)}`,
102
- chalk.yellow(`[${d.sym}]`) + ` Level test active | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | ${chalk.white(d.swings)} swings`,
103
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' stops')} clustered | ${chalk.white(d.ticks)} ticks`,
104
- chalk.yellow(`[${d.sym}]`) + ` Liquidity zone alert | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | Sweep watch`,
105
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' clusters')} | ${chalk.white(d.swings)} pivots | Watch`,
106
- chalk.yellow(`[${d.sym}]`) + ` Zone proximity | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} | Delta: ${chalk.white(d.delta)}`,
107
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' institutional')} levels | ${chalk.white(d.ticks)} ticks`,
108
- chalk.yellow(`[${d.sym}]`) + ` Stop zone alert | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | ${chalk.white(d.swings)} swings`,
109
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' sweep')} targets | Delta: ${chalk.white(d.delta)}`,
110
- chalk.yellow(`[${d.sym}]`) + ` Pool @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | ${chalk.white(d.ticks)} ticks | Alert`,
111
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' liquidity traps')} | ${chalk.white(d.swings)} pivots`,
112
- chalk.yellow(`[${d.sym}]`) + ` Zone watch active | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} | Sweep alert`,
113
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | Delta: ${chalk.white(d.delta)} | Trigger`,
114
- chalk.yellow(`[${d.sym}]`) + ` Sweep proximity | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | ${chalk.white(d.swings)} swings`,
115
- chalk.yellow(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' clusters')} mapped | ${chalk.white(d.ticks)} ticks`,
116
- chalk.yellow(`[${d.sym}]`) + ` Liquidity test | ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' pools')} | Delta: ${chalk.white(d.delta)}`,
117
- ]),
14
+ // New 1-minute bar closed
15
+ newBar: (d) => chalk.gray(`[${d.sym}]`) + ` Bar #${d.bars} @ ${chalk.white(d.price)}`,
118
16
 
119
- bull: (d) => pick([
120
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | OFI: ${chalk.green('+' + Math.abs(d.delta))} | Bid absorption | Shorts vulnerable`,
121
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Institutional bid | ${chalk.white(d.zones)} support`,
122
- chalk.green(`[${d.sym}]`) + ` Bullish microstructure | OFI ${chalk.green('+' + Math.abs(d.delta))} | Stop hunt below pending`,
123
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Positive delta divergence | Offer exhaustion | Bulls control`,
124
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buy imbalance ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones defended`,
125
- chalk.green(`[${d.sym}]`) + ` Bid stack reinforcement | Delta ${chalk.green('+' + Math.abs(d.delta))} | Sweep below imminent`,
126
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Aggressive buyers | OFI ${chalk.green('+' + Math.abs(d.delta))} | Momentum`,
127
- chalk.green(`[${d.sym}]`) + ` Sell absorption complete | ${chalk.white(d.price)} | Delta: ${chalk.green('+' + Math.abs(d.delta))} | Longs load`,
128
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bullish order flow | ${chalk.green('+' + Math.abs(d.delta))} delta | Shorts trapped`,
129
- chalk.green(`[${d.sym}]`) + ` Passive bid detected | ${chalk.white(d.price)} | OFI: ${chalk.green('+' + Math.abs(d.delta))} | Accumulation`,
130
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Offer depletion | Delta ${chalk.green('+' + Math.abs(d.delta))} | Breakout setup`,
131
- chalk.green(`[${d.sym}]`) + ` Institutional buying | ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} imbalance | Trend`,
132
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bullish footprint | OFI ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones`,
133
- chalk.green(`[${d.sym}]`) + ` Buy program detected | ${chalk.white(d.price)} | Delta: ${chalk.green('+' + Math.abs(d.delta))} | Momentum`,
134
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Positive tick flow | ${chalk.green('+' + Math.abs(d.delta))} OFI | Upside`,
135
- chalk.green(`[${d.sym}]`) + ` Short squeeze setup | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Covering`,
136
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bid aggression | OFI: ${chalk.green('+' + Math.abs(d.delta))} | Offers lifted`,
137
- chalk.green(`[${d.sym}]`) + ` Bullish absorption | ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} delta | Continuation`,
138
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buy pressure dominant | Delta: ${chalk.green('+' + Math.abs(d.delta))} | Resistance`,
139
- chalk.green(`[${d.sym}]`) + ` Demand zone active | ${chalk.white(d.price)} | OFI ${chalk.green('+' + Math.abs(d.delta))} | Support confirm`,
140
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} delta | ${chalk.white(d.zones)} zones held | Bull`,
141
- chalk.green(`[${d.sym}]`) + ` Bullish @ ${chalk.white(d.price)} | OFI ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.swings)} swings`,
142
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buy flow ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.ticks)} ticks | Long`,
143
- chalk.green(`[${d.sym}]`) + ` Long bias confirmed | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Buyers`,
144
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bid stack | ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} support`,
145
- chalk.green(`[${d.sym}]`) + ` Buyers active | ${chalk.white(d.price)} | OFI: ${chalk.green('+' + Math.abs(d.delta))} | Momentum build`,
146
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} imbalance | ${chalk.white(d.swings)} pivots | Bull`,
147
- chalk.green(`[${d.sym}]`) + ` Bull momentum | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Continuation`,
148
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Offer lift | OFI ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones`,
149
- chalk.green(`[${d.sym}]`) + ` Accumulation phase | ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} delta | Longs load`,
150
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bullish delta ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.ticks)} ticks`,
151
- chalk.green(`[${d.sym}]`) + ` Buy side dominant | ${chalk.white(d.price)} | OFI: ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.swings)} swings`,
152
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} | Shorts vulnerable | Squeeze`,
153
- chalk.green(`[${d.sym}]`) + ` Bid control | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Bullish structure`,
154
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buy imbalance | ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones`,
155
- chalk.green(`[${d.sym}]`) + ` Bullish flow | ${chalk.white(d.price)} | OFI ${chalk.green('+' + Math.abs(d.delta))} | Momentum active`,
156
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} delta | ${chalk.white(d.swings)} pivots | Long`,
157
- chalk.green(`[${d.sym}]`) + ` Long setup forming | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.ticks)} ticks`,
158
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buyer aggression | ${chalk.green('+' + Math.abs(d.delta))} | Offers lifted`,
159
- chalk.green(`[${d.sym}]`) + ` Bull @ ${chalk.white(d.price)} | OFI ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones`,
160
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Positive flow | Delta ${chalk.green('+' + Math.abs(d.delta))} | Bullish bias`,
161
- chalk.green(`[${d.sym}]`) + ` Bid dominance | ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.swings)} swings`,
162
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Buy side ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.ticks)} ticks | Long`,
163
- chalk.green(`[${d.sym}]`) + ` Bullish print | ${chalk.white(d.price)} | OFI: ${chalk.green('+' + Math.abs(d.delta))} | Continuation`,
164
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.green('+' + Math.abs(d.delta))} delta | ${chalk.white(d.zones)} defended | Bull`,
165
- chalk.green(`[${d.sym}]`) + ` Long momentum | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | Upside target`,
166
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bid absorption | ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.swings)} pivots`,
167
- chalk.green(`[${d.sym}]`) + ` Buy zone active | ${chalk.white(d.price)} | OFI ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.ticks)} ticks`,
168
- chalk.green(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bullish ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.zones)} zones | Long`,
169
- chalk.green(`[${d.sym}]`) + ` Upside bias | ${chalk.white(d.price)} | Delta ${chalk.green('+' + Math.abs(d.delta))} | ${chalk.white(d.swings)} swings`,
170
- ]),
17
+ // New swing point detected
18
+ newSwing: (d) => chalk.yellow(`[${d.sym}]`) + ` Swing #${d.swings} detected @ ${chalk.white(d.price)}`,
171
19
 
172
- bear: (d) => pick([
173
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | OFI: ${chalk.red(d.delta)} | Offer absorption | Longs vulnerable`,
174
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Institutional offer | ${chalk.white(d.zones)} resistance`,
175
- chalk.red(`[${d.sym}]`) + ` Bearish microstructure | OFI ${chalk.red(d.delta)} | Stop hunt above pending`,
176
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Negative delta divergence | Bid exhaustion | Bears control`,
177
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sell imbalance ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones pressured`,
178
- chalk.red(`[${d.sym}]`) + ` Offer stack reinforcement | Delta ${chalk.red(d.delta)} | Sweep above imminent`,
179
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Aggressive sellers | OFI ${chalk.red(d.delta)} | Momentum`,
180
- chalk.red(`[${d.sym}]`) + ` Buy absorption complete | ${chalk.white(d.price)} | Delta: ${chalk.red(d.delta)} | Shorts load`,
181
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bearish order flow | ${chalk.red(d.delta)} delta | Longs trapped`,
182
- chalk.red(`[${d.sym}]`) + ` Passive offer detected | ${chalk.white(d.price)} | OFI: ${chalk.red(d.delta)} | Distribution`,
183
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bid depletion | Delta ${chalk.red(d.delta)} | Breakdown setup`,
184
- chalk.red(`[${d.sym}]`) + ` Institutional selling | ${chalk.white(d.price)} | ${chalk.red(d.delta)} imbalance | Trend`,
185
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bearish footprint | OFI ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones`,
186
- chalk.red(`[${d.sym}]`) + ` Sell program detected | ${chalk.white(d.price)} | Delta: ${chalk.red(d.delta)} | Momentum`,
187
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Negative tick flow | ${chalk.red(d.delta)} OFI | Downside`,
188
- chalk.red(`[${d.sym}]`) + ` Long squeeze setup | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Liquidation`,
189
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Offer aggression | OFI: ${chalk.red(d.delta)} | Bids hit`,
190
- chalk.red(`[${d.sym}]`) + ` Bearish absorption | ${chalk.white(d.price)} | ${chalk.red(d.delta)} delta | Continuation`,
191
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sell pressure dominant | Delta: ${chalk.red(d.delta)} | Support`,
192
- chalk.red(`[${d.sym}]`) + ` Supply zone active | ${chalk.white(d.price)} | OFI ${chalk.red(d.delta)} | Resistance confirm`,
193
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.red(d.delta)} delta | ${chalk.white(d.zones)} zones failed | Bear`,
194
- chalk.red(`[${d.sym}]`) + ` Bearish @ ${chalk.white(d.price)} | OFI ${chalk.red(d.delta)} | ${chalk.white(d.swings)} swings`,
195
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sell flow ${chalk.red(d.delta)} | ${chalk.white(d.ticks)} ticks | Short`,
196
- chalk.red(`[${d.sym}]`) + ` Short bias confirmed | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Sellers`,
197
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Offer stack | ${chalk.red(d.delta)} | ${chalk.white(d.zones)} resistance`,
198
- chalk.red(`[${d.sym}]`) + ` Sellers active | ${chalk.white(d.price)} | OFI: ${chalk.red(d.delta)} | Momentum build`,
199
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.red(d.delta)} imbalance | ${chalk.white(d.swings)} pivots | Bear`,
200
- chalk.red(`[${d.sym}]`) + ` Bear momentum | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Continuation`,
201
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bid hit | OFI ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones`,
202
- chalk.red(`[${d.sym}]`) + ` Distribution phase | ${chalk.white(d.price)} | ${chalk.red(d.delta)} delta | Shorts load`,
203
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bearish delta ${chalk.red(d.delta)} | ${chalk.white(d.ticks)} ticks`,
204
- chalk.red(`[${d.sym}]`) + ` Sell side dominant | ${chalk.white(d.price)} | OFI: ${chalk.red(d.delta)} | ${chalk.white(d.swings)} swings`,
205
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.red(d.delta)} | Longs vulnerable | Squeeze`,
206
- chalk.red(`[${d.sym}]`) + ` Offer control | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Bearish structure`,
207
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sell imbalance | ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones`,
208
- chalk.red(`[${d.sym}]`) + ` Bearish flow | ${chalk.white(d.price)} | OFI ${chalk.red(d.delta)} | Momentum active`,
209
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.red(d.delta)} delta | ${chalk.white(d.swings)} pivots | Short`,
210
- chalk.red(`[${d.sym}]`) + ` Short setup forming | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | ${chalk.white(d.ticks)} ticks`,
211
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Seller aggression | ${chalk.red(d.delta)} | Bids hit`,
212
- chalk.red(`[${d.sym}]`) + ` Bear @ ${chalk.white(d.price)} | OFI ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones`,
213
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Negative flow | Delta ${chalk.red(d.delta)} | Bearish bias`,
214
- chalk.red(`[${d.sym}]`) + ` Offer dominance | ${chalk.white(d.price)} | ${chalk.red(d.delta)} | ${chalk.white(d.swings)} swings`,
215
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sell side ${chalk.red(d.delta)} | ${chalk.white(d.ticks)} ticks | Short`,
216
- chalk.red(`[${d.sym}]`) + ` Bearish print | ${chalk.white(d.price)} | OFI: ${chalk.red(d.delta)} | Continuation`,
217
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | ${chalk.red(d.delta)} delta | ${chalk.white(d.zones)} pressured | Bear`,
218
- chalk.red(`[${d.sym}]`) + ` Short momentum | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | Downside target`,
219
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Offer absorption | ${chalk.red(d.delta)} | ${chalk.white(d.swings)} pivots`,
220
- chalk.red(`[${d.sym}]`) + ` Sell zone active | ${chalk.white(d.price)} | OFI ${chalk.red(d.delta)} | ${chalk.white(d.ticks)} ticks`,
221
- chalk.red(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bearish ${chalk.red(d.delta)} | ${chalk.white(d.zones)} zones | Short`,
222
- chalk.red(`[${d.sym}]`) + ` Downside bias | ${chalk.white(d.price)} | Delta ${chalk.red(d.delta)} | ${chalk.white(d.swings)} swings`,
223
- ]),
20
+ // New liquidity zone created
21
+ newZone: (d) => chalk.green(`[${d.sym}]`) + ` Zone #${d.zones} created @ ${chalk.white(d.price)} | Sweep target active`,
224
22
 
225
- neutral: (d) => pick([
226
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Delta neutral | ${chalk.white(d.zones)} zones intact | Awaiting catalyst`,
227
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | OFI balanced | ${chalk.white(d.zones)} zones stable | Range compression`,
228
- chalk.gray(`[${d.sym}]`) + ` Equilibrium @ ${chalk.white(d.price)} | Stops accumulating | ${chalk.white(d.ticks)} ticks | Patience`,
229
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No directional flow | ${chalk.white(d.zones)} liquidity pools stable`,
230
- chalk.gray(`[${d.sym}]`) + ` Range consolidation | ${chalk.white(d.price)} | Awaiting institutional catalyst`,
231
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Balanced book | ${chalk.white(d.zones)} zones | Breakout imminent`,
232
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Rotation mode | OFI flat | ${chalk.white(d.zones)} levels holding`,
233
- chalk.gray(`[${d.sym}]`) + ` Chop zone detected | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | No edge`,
234
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Two-sided flow | ${chalk.white(d.zones)} zones | Expansion pending`,
235
- chalk.gray(`[${d.sym}]`) + ` Value area rotation | ${chalk.white(d.price)} | Balanced auction | ${chalk.white(d.ticks)} ticks`,
236
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Inside bar structure | ${chalk.white(d.zones)} zones | Coiling`,
237
- chalk.gray(`[${d.sym}]`) + ` Consolidation phase | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)} | Range-bound`,
238
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Balanced delta | Awaiting volume | ${chalk.white(d.zones)} zones`,
239
- chalk.gray(`[${d.sym}]`) + ` Low conviction | ${chalk.white(d.price)} | Delta neutral | Patience mode active`,
240
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Tight range | ${chalk.white(d.zones)} zones | Volatility compression`,
241
- chalk.gray(`[${d.sym}]`) + ` Mean reversion zone | ${chalk.white(d.price)} | No trend | ${chalk.white(d.ticks)} ticks`,
242
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Symmetric flow | ${chalk.white(d.zones)} liquidity balanced`,
243
- chalk.gray(`[${d.sym}]`) + ` Absorption both sides | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)} | Standoff`,
244
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Bracket forming | ${chalk.white(d.zones)} levels | Expansion watch`,
245
- chalk.gray(`[${d.sym}]`) + ` Balance area | ${chalk.white(d.price)} | No aggression | ${chalk.white(d.ticks)} ticks`,
246
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Neutral flow | ${chalk.white(d.zones)} zones | ${chalk.white(d.swings)} swings`,
247
- chalk.gray(`[${d.sym}]`) + ` Range bound | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | Awaiting breakout`,
248
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No edge detected | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.zones)} zones`,
249
- chalk.gray(`[${d.sym}]`) + ` Flat @ ${chalk.white(d.price)} | ${chalk.white(d.swings)} pivots | Waiting for direction`,
250
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Balance | OFI: ${chalk.white(d.delta)} | ${chalk.white(d.zones)} zones`,
251
- chalk.gray(`[${d.sym}]`) + ` Consolidating | ${chalk.white(d.price)} | ${chalk.white(d.ticks)} ticks | Awaiting catalyst`,
252
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Neutral flow | ${chalk.white(d.zones)} levels | ${chalk.white(d.swings)} swings`,
253
- chalk.gray(`[${d.sym}]`) + ` No bias | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | Patience mode`,
254
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Range | ${chalk.white(d.zones)} zones | ${chalk.white(d.ticks)} ticks`,
255
- chalk.gray(`[${d.sym}]`) + ` Waiting | ${chalk.white(d.price)} | ${chalk.white(d.swings)} pivots | No directional edge`,
256
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Balanced | ${chalk.white(d.zones)} zones | Delta: ${chalk.white(d.delta)}`,
257
- chalk.gray(`[${d.sym}]`) + ` Rotation @ ${chalk.white(d.price)} | ${chalk.white(d.ticks)} ticks | Awaiting breakout`,
258
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No momentum | ${chalk.white(d.zones)} levels | Patience mode`,
259
- chalk.gray(`[${d.sym}]`) + ` Flat flow | ${chalk.white(d.price)} | ${chalk.white(d.swings)} swings | No edge`,
260
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Sideways | Delta: ${chalk.white(d.delta)} | ${chalk.white(d.zones)} zones`,
261
- chalk.gray(`[${d.sym}]`) + ` Neutral @ ${chalk.white(d.price)} | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.swings)} pivots`,
262
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No trend | ${chalk.white(d.zones)} zones | Awaiting catalyst`,
263
- chalk.gray(`[${d.sym}]`) + ` Balance @ ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | No edge`,
264
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Equilibrium | ${chalk.white(d.zones)} levels | ${chalk.white(d.ticks)} ticks`,
265
- chalk.gray(`[${d.sym}]`) + ` Range mode | ${chalk.white(d.price)} | ${chalk.white(d.swings)} swings | Awaiting direction`,
266
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Choppy | ${chalk.white(d.zones)} zones | Delta: ${chalk.white(d.delta)}`,
267
- chalk.gray(`[${d.sym}]`) + ` Coiling | ${chalk.white(d.price)} | ${chalk.white(d.ticks)} ticks | Expansion pending`,
268
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No direction | ${chalk.white(d.zones)} levels | ${chalk.white(d.swings)} pivots`,
269
- chalk.gray(`[${d.sym}]`) + ` Flat @ ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | No edge detected`,
270
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Balanced flow | ${chalk.white(d.zones)} zones | ${chalk.white(d.ticks)} ticks`,
271
- chalk.gray(`[${d.sym}]`) + ` Neutral bias | ${chalk.white(d.price)} | ${chalk.white(d.swings)} swings | Patience mode`,
272
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | Range bound | ${chalk.white(d.zones)} levels | Delta: ${chalk.white(d.delta)}`,
273
- chalk.gray(`[${d.sym}]`) + ` Waiting @ ${chalk.white(d.price)} | ${chalk.white(d.ticks)} ticks | ${chalk.white(d.swings)} pivots`,
274
- chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} | No edge | ${chalk.white(d.zones)} zones | Awaiting catalyst`,
275
- chalk.gray(`[${d.sym}]`) + ` Consolidation | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | ${chalk.white(d.ticks)} ticks`,
276
- ]),
23
+ // Price approaching a zone
24
+ approachZone: (d) => chalk.bgYellow.black(' ZONE ') + ` ${chalk.yellow(`[${d.sym}]`)} ${chalk.white(d.price)} approaching ${d.zonePrice} (${d.distance}t away)`,
277
25
 
278
- ready: (d) => {
279
- const bias = d.delta > 0 ? 'bullish' : d.delta < 0 ? 'bearish' : 'neutral';
280
- const biasColor = d.delta > 0 ? chalk.green : d.delta < 0 ? chalk.red : chalk.gray;
281
- return pick([
282
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | ${biasColor(bias)} bias`,
283
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Watching @ ${chalk.white(d.price)} | ${chalk.yellow(d.swings + ' swings')} mapped`,
284
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | Sweep watch`,
285
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Zones active | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
286
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | Awaiting sweep`,
287
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Liquidity mapped | ${chalk.white(d.price)} | ${biasColor(bias)}`,
288
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.swings)} pivots | Delta: ${chalk.white(d.delta)}`,
289
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Monitoring @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')}`,
290
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)} | Zones ready`,
291
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Structure set | ${chalk.white(d.price)} | ${chalk.yellow(d.swings + ' swings')}`,
292
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${biasColor(bias)} flow | ${chalk.yellow(d.zones)} zones`,
293
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Sweep zones mapped | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)}`,
294
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} | ${biasColor(bias)}`,
295
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Watching levels | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
296
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Liquidity hunt active | ${chalk.yellow(d.zones)} zones`,
297
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Zones locked | ${chalk.white(d.price)} | ${biasColor(bias)} bias`,
298
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.swings + ' pivots')} | Sweep imminent`,
299
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Hunting liquidity | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)}`,
300
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones)} zones | Primed`,
301
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} 2B setup forming | ${chalk.white(d.price)} | ${biasColor(bias)}`,
302
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Stop hunt watch | ${chalk.yellow(d.zones + ' levels')}`,
303
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Armed @ ${chalk.white(d.price)} | ${chalk.yellow(d.swings)} swings | ${biasColor(bias)}`,
304
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | Zones primed`,
305
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Liquidity levels set | ${chalk.white(d.price)} | ${chalk.yellow(d.zones)} zones`,
306
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${biasColor(bias)} | Awaiting trigger`,
307
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Pattern forming | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
308
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' zones')} | Sweep watch`,
309
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Targets locked | ${chalk.white(d.price)} | ${biasColor(bias)} flow`,
310
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.swings)} pivots | Delta: ${chalk.white(d.delta)}`,
311
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Monitoring zones | ${chalk.white(d.price)} | ${biasColor(bias)}`,
312
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' levels')} | Armed`,
313
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Ready state | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
314
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Sweep zones active | ${biasColor(bias)}`,
315
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Watching @ ${chalk.white(d.price)} | ${chalk.yellow(d.zones)} zones ready`,
316
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)} | Primed`,
317
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Structure ready | ${chalk.white(d.price)} | ${chalk.yellow(d.swings + ' swings')}`,
318
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${biasColor(bias)} bias | ${chalk.yellow(d.zones)} zones`,
319
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Levels mapped | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
320
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones + ' targets')} | Watching`,
321
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Zones active | ${chalk.white(d.price)} | ${biasColor(bias)} flow`,
322
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.swings)} pivots | Sweep watch`,
323
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Liquidity hunt | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)}`,
324
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones)} zones | Armed`,
325
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Awaiting sweep | ${chalk.white(d.price)} | ${biasColor(bias)}`,
326
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)} | ${chalk.yellow(d.zones + ' levels')}`,
327
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Pattern watch | ${chalk.white(d.price)} | ${biasColor(bias)} flow`,
328
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.swings + ' swings')} | Primed`,
329
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Stop hunt mode | ${chalk.white(d.price)} | Delta: ${chalk.white(d.delta)}`,
330
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${chalk.white(d.price)} | ${chalk.yellow(d.zones)} zones | ${biasColor(bias)}`,
331
- chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} Sweep ready | ${chalk.white(d.price)} | OFI: ${chalk.white(d.delta)}`,
332
- ]);
26
+ // Bias flipped (bull <-> bear)
27
+ biasFlip: (d) => {
28
+ const arrow = d.to === 'bullish' ? chalk.green('') : chalk.red('');
29
+ const color = d.to === 'bullish' ? chalk.green : chalk.red;
30
+ return `[${d.sym}] ${arrow} Bias: ${d.from}${color(d.to)} | Delta: ${d.delta}`;
333
31
  },
32
+
33
+ // Significant price movement
34
+ priceMove: (d) => {
35
+ const arrow = d.dir === 'up' ? chalk.green('+') : chalk.red('-');
36
+ return chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} (${arrow}${d.ticks}t)`;
37
+ },
38
+
39
+ // Delta/OFI shift
40
+ deltaShift: (d) => {
41
+ const dir = d.to > d.from ? chalk.green('') : chalk.red('');
42
+ return chalk.gray(`[${d.sym}]`) + ` Delta shift: ${d.from}${dir}${d.to}`;
43
+ },
44
+
45
+ // Keep building/bull/bear/zones/neutral for QUANT compatibility (minimal versions)
46
+ building: (d) => chalk.cyan(`[${d.sym}]`) + ` Warmup: ${d.bars} bars | ${d.swings} swings`,
47
+
48
+ bull: (d) => chalk.green(`[${d.sym}]`) + ` ${d.price} | Delta: +${Math.abs(d.delta)} | Bullish`,
49
+
50
+ bear: (d) => chalk.red(`[${d.sym}]`) + ` ${d.price} | Delta: ${d.delta} | Bearish`,
51
+
52
+ zones: (d) => chalk.yellow(`[${d.sym}]`) + ` ${d.price} | ${d.zones} zones active`,
53
+
54
+ neutral: (d) => chalk.gray(`[${d.sym}]`) + ` ${d.price} | Neutral | ${d.zones} zones`,
55
+
56
+ ready: (d) => chalk.bgCyan.black(' RDY ') + ` ${chalk.cyan(`[${d.sym}]`)} ${d.price} | ${d.zones} zones | ${d.swings} swings`,
334
57
  };
@@ -1,8 +1,7 @@
1
1
  /**
2
- * QUANT (HQX Scalping) - Message Templates
3
- * 50 messages per phase - ALL using REAL data from strategy
4
- * Real Variables: d.sym, d.price, d.ticks, d.zScore, d.zScoreAbs, d.vpin, d.ofi, d.delta, d.rawZScore
5
- * WITH COLORS: cyan=building, yellow=zones, green=bull, red=bear, gray=neutral
2
+ * QUANT (HQX Scalping) - Event-Based + Legacy Messages
3
+ * Event functions for smart-logs-engine compatibility
4
+ * Legacy functions (building/zones/bull/bear/neutral/ready) kept for fallback
6
5
  */
7
6
  'use strict';
8
7
 
@@ -10,6 +9,20 @@ const chalk = require('chalk');
10
9
  const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
11
10
 
12
11
  module.exports = {
12
+ // Event-based messages (for smart-logs-engine event detection)
13
+ init: (d) => chalk.cyan(`[${d.sym}]`) + ` QUANT model ready | ${d.ticks || d.bars} observations`,
14
+ newBar: (d) => chalk.gray(`[${d.sym}]`) + ` Tick batch #${d.bars} @ ${chalk.white(d.price)}`,
15
+ newSwing: (d) => chalk.yellow(`[${d.sym}]`) + ` Z-score shift | ${d.swings} signals`,
16
+ newZone: (d) => chalk.green(`[${d.sym}]`) + ` Statistical edge detected | ${d.zones} factors aligned`,
17
+ approachZone: (d) => chalk.bgYellow.black(' EDGE ') + ` ${chalk.yellow(`[${d.sym}]`)} ${chalk.white(d.price)} | Threshold proximity`,
18
+ biasFlip: (d) => {
19
+ const arrow = d.to === 'bullish' ? chalk.green('') : chalk.red('');
20
+ return `[${d.sym}] ${arrow} Regime: ${d.from}${d.to} | OFI: ${d.delta}`;
21
+ },
22
+ priceMove: (d) => chalk.gray(`[${d.sym}]`) + ` ${chalk.white(d.price)} (${d.dir === 'up' ? '+' : '-'}${d.ticks}t)`,
23
+ deltaShift: (d) => chalk.gray(`[${d.sym}]`) + ` OFI shift: ${d.from}${d.to}`,
24
+
25
+ // Legacy message pools (for fallback compatibility)
13
26
  building: (d) => pick([
14
27
  chalk.cyan(`[${d.sym}]`) + ` Factor model calibration | ${chalk.white(d.ticks)} observations | Z-score baseline init`,
15
28
  chalk.cyan(`[${d.sym}]`) + ` VPIN computation | ${chalk.white(d.ticks)} tick volume | Toxicity threshold loading`,
@@ -422,7 +422,7 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
422
422
  const pnlInterval = setInterval(() => { if (running) pollPnL(); }, 2000);
423
423
  pollPnL();
424
424
 
425
- // Live analysis logs every 1 second
425
+ // Event-driven logs - only log when something significant happens
426
426
  let lastLiveLogSecond = 0;
427
427
  const liveLogInterval = setInterval(() => {
428
428
  if (!running) return;
@@ -438,6 +438,8 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
438
438
  zones: state?.activeZones || 0,
439
439
  trend: lastBias === 'LONG' ? 'bullish' : lastBias === 'SHORT' ? 'bearish' : 'neutral',
440
440
  nearZone: (state?.nearestSupport || state?.nearestResistance) ? true : false,
441
+ nearestSupport: state?.nearestSupport || null,
442
+ nearestResistance: state?.nearestResistance || null,
441
443
  setupForming: state?.ready && state?.activeZones > 0,
442
444
  position: currentPosition,
443
445
  price: lastPrice || 0,
@@ -450,9 +452,12 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
450
452
  ofi: state?.ofi || 0,
451
453
  };
452
454
 
455
+ // Only log if an event was detected (log !== null)
453
456
  const log = logsEngine.getLog(logState);
454
- ui.addLog(log.type, log.message);
455
- if (log.logToSession) sessionLogger.log('ANALYSIS', log.message);
457
+ if (log) {
458
+ ui.addLog(log.type, log.message);
459
+ if (log.logToSession) sessionLogger.log('ANALYSIS', log.message);
460
+ }
456
461
  }, 1000);
457
462
 
458
463
  const setupKeyHandler = () => {
@@ -129,12 +129,17 @@ class RithmicBrokerClient extends EventEmitter {
129
129
 
130
130
  /**
131
131
  * Login to Rithmic via daemon
132
+ * @param {string} username - Rithmic username
133
+ * @param {string} password - Rithmic password
134
+ * @param {Object} options - Optional settings
135
+ * @param {Array} options.cachedAccounts - Use cached accounts to avoid API call (CRITICAL for Rithmic limit)
132
136
  */
133
- async login(username, password) {
137
+ async login(username, password, options = {}) {
134
138
  const result = await this._request('login', {
135
139
  propfirmKey: this.propfirmKey,
136
140
  username,
137
141
  password,
142
+ cachedAccounts: options.cachedAccounts || null, // Pass to daemon to avoid fetchAccounts
138
143
  }, 60000);
139
144
 
140
145
  if (result.error) {
@@ -78,11 +78,27 @@ class RithmicBrokerDaemon {
78
78
  this.running = true;
79
79
  log('INFO', 'Daemon started', { pid: process.pid, port: BROKER_PORT });
80
80
 
81
- process.on('SIGTERM', () => this.stop());
82
- process.on('SIGINT', () => this.stop());
81
+ // Save state on ANY termination signal
82
+ const gracefulShutdown = (signal) => {
83
+ log('WARN', `Received ${signal}, saving state...`);
84
+ this._saveState();
85
+ this.stop();
86
+ };
87
+ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
88
+ process.on('SIGINT', () => gracefulShutdown('SIGINT'));
89
+ process.on('SIGHUP', () => gracefulShutdown('SIGHUP'));
90
+ process.on('uncaughtException', (err) => {
91
+ log('ERROR', 'Uncaught exception, saving state...', { error: err.message });
92
+ this._saveState();
93
+ process.exit(1);
94
+ });
95
+ process.on('unhandledRejection', (err) => {
96
+ log('ERROR', 'Unhandled rejection', { error: err?.message || String(err) });
97
+ this._saveState();
98
+ });
83
99
 
84
- // Auto-save state every 30s
85
- setInterval(() => this._saveState(), 30000);
100
+ // Auto-save state every 5s (critical for surviving updates)
101
+ setInterval(() => this._saveState(), 5000);
86
102
 
87
103
  // Start health check (monitoring + rate-limited reconnection)
88
104
  this.reconnectManager.startHealthCheck();
@@ -350,6 +366,7 @@ class RithmicBrokerDaemon {
350
366
 
351
367
  /**
352
368
  * Save state including accounts (for reconnection without API calls)
369
+ * CRITICAL: This state allows reconnection without hitting Rithmic's 2000 GetAccounts limit
353
370
  */
354
371
  _saveState() {
355
372
  const state = { connections: [], savedAt: new Date().toISOString() };
@@ -359,11 +376,17 @@ class RithmicBrokerDaemon {
359
376
  propfirmKey: key,
360
377
  credentials: conn.credentials,
361
378
  accounts: conn.accounts || [], // Save accounts to avoid fetchAccounts on restore
362
- connectedAt: conn.connectedAt
379
+ connectedAt: conn.connectedAt,
380
+ propfirm: conn.service?.propfirm?.name || key
363
381
  });
364
382
  }
365
383
  }
366
- try { fs.writeFileSync(STATE_FILE, JSON.stringify(state)); } catch (e) { /* ignore */ }
384
+ try {
385
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state));
386
+ log('DEBUG', 'State saved', { connections: state.connections.length });
387
+ } catch (e) {
388
+ log('ERROR', 'Failed to save state', { error: e.message });
389
+ }
367
390
  }
368
391
  }
369
392
 
@@ -116,16 +116,18 @@ const connections = {
116
116
  const existingSessions = storage.load();
117
117
  const aiSessions = existingSessions.filter(s => s.type === 'ai');
118
118
 
119
- // Build Rithmic sessions
119
+ // Build Rithmic sessions - INCLUDE accounts to avoid Rithmic API limit on restore
120
120
  const rithmicSessions = this.services.map(conn => ({
121
121
  type: conn.type,
122
122
  propfirm: conn.propfirm,
123
123
  propfirmKey: conn.service.propfirmKey || conn.propfirmKey,
124
124
  credentials: conn.service.credentials,
125
+ accounts: conn.service.accounts || [], // CRITICAL: Cache accounts to avoid 2000 GetAccounts limit
125
126
  }));
126
127
 
127
128
  // Merge: AI sessions + Rithmic sessions
128
129
  storage.save([...aiSessions, ...rithmicSessions]);
130
+ log.debug('Session saved', { rithmicCount: rithmicSessions.length, hasAccounts: rithmicSessions.some(s => s.accounts?.length > 0) });
129
131
  },
130
132
 
131
133
  async restoreFromStorage() {
@@ -197,7 +199,10 @@ const connections = {
197
199
  // Use broker client (daemon handles persistence)
198
200
  if (type === 'rithmic' && session.credentials) {
199
201
  const client = new RithmicBrokerClient(propfirmKey || 'apex_rithmic');
200
- const result = await client.login(session.credentials.username, session.credentials.password);
202
+
203
+ // CRITICAL: Pass cached accounts to avoid Rithmic's 2000 GetAccounts limit
204
+ const loginOptions = session.accounts ? { cachedAccounts: session.accounts } : {};
205
+ const result = await client.login(session.credentials.username, session.credentials.password, loginOptions);
201
206
 
202
207
  if (result.success) {
203
208
  this.services.push({
@@ -207,7 +212,7 @@ const connections = {
207
212
  propfirmKey,
208
213
  connectedAt: new Date(),
209
214
  });
210
- log.debug('Rithmic session restored via broker');
215
+ log.debug('Rithmic session restored via broker', { hasCachedAccounts: !!session.accounts });
211
216
  }
212
217
  }
213
218
  },