hedgequantx 2.9.230 → 2.9.232

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.230",
3
+ "version": "2.9.232",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1,320 +1,228 @@
1
1
  /**
2
- * Smart Logs Engine - Unified Event-Driven Intelligent Logs
3
- * ==========================================================
2
+ * Smart Logs Engine - Professional HF-Grade Real-Time Logs
3
+ * =========================================================
4
4
  *
5
- * UNIFIED SYSTEM for all CLI strategies:
6
- * - Same engine, same event detection logic
7
- * - Strategy-specific vocabulary (HQX-2B: bars/swings/zones, QUANT: ticks/Z-Score/VPIN/OFI)
8
- * - Uses smartLogs.getLiveAnalysisLog() for varied, non-repetitive messages
5
+ * REAL-TIME logs every second showing:
6
+ * 1. Current price action
7
+ * 2. QUANT model states (Z-Score, VPIN, OFI)
8
+ * 3. Why we're not entering (or why we ARE entering)
9
+ * 4. Market microstructure insights
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
+ * NO fake messages - everything is derived from real tick data
21
12
  */
22
13
 
23
14
  'use strict';
24
15
 
25
16
  const chalk = require('chalk');
26
- const smartLogs = require('./smart-logs');
27
- const { getContextualMessage } = require('./smart-logs-context');
28
17
 
29
18
  // Color helpers for consistent styling
30
19
  const C = {
31
- // Symbols & identifiers
32
20
  sym: (s) => chalk.cyan.bold(s),
33
-
34
- // Prices
35
21
  price: (p) => chalk.white.bold(p),
36
-
37
- // Direction
38
22
  long: (s) => chalk.green.bold(s),
39
23
  short: (s) => chalk.red.bold(s),
40
24
  bull: (s) => chalk.green(s),
41
25
  bear: (s) => chalk.red(s),
42
-
43
- // Values & metrics
44
26
  val: (v) => chalk.blue(v),
45
27
  valHigh: (v) => chalk.magenta.bold(v),
46
-
47
- // Status
48
28
  ok: (s) => chalk.green(s),
49
29
  warn: (s) => chalk.yellow(s),
50
30
  danger: (s) => chalk.red.bold(s),
51
-
52
- // System/neutral
53
31
  dim: (s) => chalk.dim(s),
54
32
  info: (s) => chalk.gray(s),
55
-
56
- // Special
57
33
  signal: (s) => chalk.yellow.bold(s),
58
- zone: (s) => chalk.magenta(s),
59
- regime: (s) => chalk.cyan(s),
60
34
  };
61
35
 
62
36
  const CONFIG = {
63
- SESSION_LOG_INTERVAL: 10,
64
- // HQX-2B thresholds
65
- PRICE_CHANGE_TICKS: 4,
66
- DELTA_CHANGE_THRESHOLD: 200,
67
- // QUANT thresholds
68
37
  Z_EXTREME: 2.0,
69
38
  Z_HIGH: 1.5,
70
39
  Z_BUILDING: 1.0,
40
+ OFI_STRONG: 0.20,
71
41
  OFI_THRESHOLD: 0.15,
72
- VPIN_TOXIC: 0.6,
73
- QUANT_WARMUP_TICKS: 250,
74
- // Heartbeat interval - frequent updates in scanning mode
75
- HEARTBEAT_MS: 5000, // 5 seconds
76
- };
77
-
78
- const SYMBOLS = {
79
- NQ: 'NQ', MNQ: 'MNQ', ES: 'ES', MES: 'MES', YM: 'YM', MYM: 'MYM',
80
- CL: 'CL', MCL: 'MCL', GC: 'GC', MGC: 'MGC', SI: 'SI', SIL: 'SIL',
81
- RTY: 'RTY', M2K: 'M2K', ZB: 'ZB', ZN: 'ZN',
42
+ VPIN_TOXIC: 0.65,
43
+ VPIN_ELEVATED: 0.50,
82
44
  };
83
45
 
84
46
  function getSym(s) {
85
47
  if (!s) return 'FUT';
86
48
  const b = s.split(':')[0].replace(/[FGHJKMNQUVXZ]\d{1,2}$/, '').toUpperCase();
87
- return SYMBOLS[b] || b;
49
+ const map = { ENQ: 'NQ', EP: 'ES', RTY: 'RTY', EMD: 'EMD', MGC: 'GC', MCL: 'CL' };
50
+ return map[b] || b;
88
51
  }
89
52
 
90
53
  /**
91
- * Unified Smart Logs Engine
92
- * Works with any strategy - adapts vocabulary based on strategyId
54
+ * Professional HF Smart Logs Engine
93
55
  */
94
56
  class SmartLogsEngine {
95
57
  constructor(strategyId, symbol) {
96
- this.strategyId = strategyId || 'hqx-2b';
58
+ this.strategyId = strategyId || 'ultra-scalping';
97
59
  this.symbolCode = symbol;
98
- this.counter = 0;
99
- this.lastState = null;
100
-
101
- // State tracking for event detection (both strategies)
102
- this.lastBias = null;
103
- this.warmupLogged = false;
60
+ this.lastLogHash = null;
61
+ this.lastLogTime = 0;
62
+ this.eventCounter = 0;
104
63
 
105
- // HQX-2B specific
106
- this.lastBars = 0;
107
- this.lastSwings = 0;
108
- this.lastZones = 0;
109
- this.lastNearZone = false;
110
-
111
- // QUANT specific
112
- this.lastZRegime = null;
113
- this.lastVpinToxic = false;
64
+ // State tracking for change detection
65
+ this.prev = {
66
+ zRegime: null,
67
+ ofiDir: null,
68
+ vpinLevel: null,
69
+ position: 0,
70
+ ready: false,
71
+ };
114
72
  }
115
73
 
116
74
  setSymbol(s) { this.symbolCode = s; }
117
75
 
118
76
  /**
119
- * Get log message - unified entry point
120
- * Detects strategy and routes to appropriate handler
77
+ * Main entry - ALWAYS returns a UNIQUE log showing real-time market state
78
+ * Each message is different based on actual changing market data
121
79
  */
122
80
  getLog(state = {}) {
123
- this.counter++;
124
81
  const sym = getSym(this.symbolCode);
125
- const price = state.price > 0 ? state.price.toFixed(2) : '-.--';
126
- const { position = 0, delta = 0 } = state;
127
-
128
- // Active position - same for all strategies
82
+ const price = state.price > 0 ? state.price.toFixed(2) : null;
83
+ const { position = 0, zScore = 0, vpin = 0, ofi = 0, tickCount = 0, bars = 0, delta = 0, buyPct = 50 } = state;
84
+
85
+ // Track price movement for context
86
+ const priceNum = state.price || 0;
87
+ const lastPrice = this._lastPrice || priceNum;
88
+ 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;
91
+ this._lastPrice = priceNum;
92
+
93
+ // Track tick velocity
94
+ const lastTicks = this._lastTicks || 0;
95
+ const tickVelocity = (tickCount || bars || 0) - lastTicks;
96
+ this._lastTicks = tickCount || bars || 0;
97
+
98
+ // 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;
103
+ return {
104
+ type: 'system',
105
+ message: `[${C.sym(sym)}] ${price ? C.price(price) : '-.--'} | Calibrating ${C.val(pct + '%')} | ${remaining} samples to ready | +${tickVelocity}/s`,
106
+ logToSession: false
107
+ };
108
+ }
109
+
110
+ // Compute current states with precision for uniqueness
111
+ const absZ = Math.abs(zScore);
112
+ const ofiPct = (ofi * 100).toFixed(0);
113
+ const vpinPct = (vpin * 100).toFixed(0);
114
+ const buyPctRound = Math.round(buyPct || 50);
115
+ const deltaRound = Math.round(delta || 0);
116
+
117
+ // Z-Score color based on level
118
+ const zColor = absZ >= CONFIG.Z_EXTREME ? C.valHigh :
119
+ absZ >= CONFIG.Z_HIGH ? C.warn :
120
+ absZ >= CONFIG.Z_BUILDING ? C.val : C.dim;
121
+ const zStr = zColor(`${zScore.toFixed(2)}σ`);
122
+
123
+ // OFI color based on direction
124
+ const ofiColor = ofi > CONFIG.OFI_THRESHOLD ? C.bull :
125
+ ofi < -CONFIG.OFI_THRESHOLD ? C.bear : C.dim;
126
+ const ofiStr = ofiColor(`${ofi >= 0 ? '+' : ''}${ofiPct}%`);
127
+
128
+ // VPIN color based on toxicity
129
+ const vpinColor = vpin > CONFIG.VPIN_TOXIC ? C.danger :
130
+ vpin > CONFIG.VPIN_ELEVATED ? C.warn : C.ok;
131
+ const vpinStr = vpinColor(`${vpinPct}%`);
132
+
133
+ // Delta (buy-sell imbalance) display
134
+ const deltaColor = deltaRound > 0 ? C.bull : deltaRound < 0 ? C.bear : C.dim;
135
+ const deltaStr = deltaColor(`${deltaRound > 0 ? '+' : ''}${deltaRound}`);
136
+
137
+ // Active position - show position management with unique data
129
138
  if (position !== 0) {
130
139
  const isLong = position > 0;
131
140
  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}`);
141
+ const flowFavor = (isLong && ofi > 0) || (!isLong && ofi < 0);
142
+ const flowLabel = flowFavor ? C.ok('aligned') : C.warn('adverse');
143
+ const exitClose = absZ < 0.5;
144
+ const exitInfo = exitClose ? C.warn('EXIT ZONE') : 'holding';
145
+
135
146
  return {
136
147
  type: 'trade',
137
- message: `[${C.sym(sym)}] ${side} ACTIVE @ ${C.price(price)} | Delta: ${deltaStr} | Flow: ${flowLabel}`,
138
- logToSession: true
148
+ message: `[${C.sym(sym)}] ${side} ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} ${exitInfo} | Δ:${deltaStr} | Flow:${flowLabel}`,
149
+ logToSession: false
139
150
  };
140
151
  }
141
-
142
- // Route to strategy-specific handler
143
- if (this.strategyId === 'ultra-scalping') {
144
- return this._getQuantLog(state, sym, price);
145
- } else {
146
- return this._getHqx2bLog(state, sym, price);
147
- }
148
- }
149
-
150
- /**
151
- * HQX-2B Liquidity Sweep - Bar/Swing/Zone based events
152
- */
153
- _getHqx2bLog(state, sym, price) {
154
- const { bars = 0, swings = 0, zones = 0, nearZone = false, trend = 'neutral', delta = 0 } = state;
155
152
 
156
- let event = null;
153
+ // No position - show WHY we're not entering with unique context each time
154
+ const direction = zScore < 0 ? 'LONG' : 'SHORT';
155
+ const dirColor = zScore < 0 ? C.long : C.short;
156
+
157
157
  let logType = 'analysis';
158
- let message = null;
159
-
160
- // EVENT 1: Warmup complete (10+ bars)
161
- if (bars >= 10 && !this.warmupLogged) {
162
- this.warmupLogged = true;
163
- event = 'warmup';
164
- const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
165
- message = `[${C.sym(sym)}] ${C.ok('2B ready')} | ${C.val(bars)} bars | ${C.dim(warmupMsg)}`;
166
- logType = 'system';
158
+ let message;
159
+
160
+ // VPIN toxic - highest priority blocker
161
+ if (vpin > CONFIG.VPIN_TOXIC) {
162
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | VPIN:${vpinStr} ${C.danger('TOXIC')} | Z:${zStr} | Δ:${deltaStr} | Hold`;
163
+ logType = 'risk';
167
164
  }
168
- // EVENT 2: New zone created
169
- else if (zones > this.lastZones && zones > 0) {
170
- event = 'new_zone';
171
- const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
172
- message = `[${C.sym(sym)}] ${C.price(price)} | ${C.zone('Zone #' + zones)} | ${C.signal(signalMsg)}`;
165
+ // Z-Score extreme + OFI confirms = SIGNAL
166
+ else if (absZ >= CONFIG.Z_EXTREME &&
167
+ ((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`;
173
169
  logType = 'signal';
174
170
  }
175
- // EVENT 3: New swing detected
176
- else if (swings > this.lastSwings && swings > 0) {
177
- event = 'new_swing';
178
- const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
179
- message = `[${C.sym(sym)}] ${C.price(price)} | ${C.info('Swing #' + swings)} | ${C.dim(scanMsg)}`;
180
- }
181
- // EVENT 4: Zone approach (price near zone)
182
- else if (nearZone && !this.lastNearZone && zones > 0) {
183
- event = 'zone_approach';
184
- const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
185
- message = `[${C.sym(sym)}] ${C.price(price)} | ${C.warn('Zone approach')} | ${C.signal(signalMsg)}`;
171
+ // Z-Score extreme but OFI doesn't confirm
172
+ 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')}`;
186
175
  logType = 'signal';
187
176
  }
188
- // EVENT 5: Bias flip
189
- else if (this.lastBias && trend !== this.lastBias && trend !== 'neutral' && this.lastBias !== 'neutral') {
190
- event = 'bias_flip';
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);
194
- const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, trend);
195
- message = `[${C.sym(sym)}] ${arrow} ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
196
- }
197
-
198
- // Update state tracking
199
- this.lastBars = bars;
200
- this.lastSwings = swings;
201
- this.lastZones = zones;
202
- this.lastNearZone = nearZone;
203
- this.lastBias = trend;
204
-
205
- if (event && message) {
206
- return { type: logType, message, logToSession: event === 'new_zone' || event === 'bias_flip' };
207
- }
208
- return null;
209
- }
210
-
211
- /**
212
- * QUANT (HQX Ultra Scalping) - Tick/Z-Score/VPIN/OFI based events
213
- */
214
- _getQuantLog(state, sym, price) {
215
- const { tickCount = 0, zScore = 0, vpin = 0, ofi = 0 } = state;
216
- const ticks = tickCount || state.bars || 0;
217
-
218
- const absZ = Math.abs(zScore);
219
- const vpinToxic = vpin > CONFIG.VPIN_TOXIC;
220
- const zRegime = absZ >= CONFIG.Z_EXTREME ? 'extreme' : absZ >= CONFIG.Z_HIGH ? 'high' : absZ >= CONFIG.Z_BUILDING ? 'building' : 'neutral';
221
- const bias = ofi > CONFIG.OFI_THRESHOLD ? 'bullish' : ofi < -CONFIG.OFI_THRESHOLD ? 'bearish' : 'neutral';
222
-
223
- let event = null;
224
- let logType = 'analysis';
225
- let message = null;
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
-
237
- // EVENT 1: Warmup complete (250 ticks for QUANT models)
238
- if (ticks >= CONFIG.QUANT_WARMUP_TICKS && !this.warmupLogged) {
239
- this.warmupLogged = true;
240
- event = 'warmup';
241
- const warmupMsg = getContextualMessage(this.symbolCode, this.strategyId, 'warmup');
242
- message = `[${C.sym(sym)}] ${C.ok('QUANT ready')} | ${C.val(ticks)} ticks | ${C.dim(warmupMsg)}`;
243
- logType = 'system';
244
- }
245
- // EVENT 2: Z-Score regime change
246
- else if (this.lastZRegime !== null && zRegime !== this.lastZRegime) {
247
- event = 'z_regime';
248
- // Get instrument-specific market context message
249
- const marketCtx = bias === 'bullish' ? 'bullish' : bias === 'bearish' ? 'bearish' : 'neutral';
250
- const instrumentMsg = getContextualMessage(this.symbolCode, this.strategyId, marketCtx);
251
-
252
- if (zRegime === 'extreme') {
253
- logType = 'signal';
254
- const dir = zScore < 0 ? C.long('LONG') : C.short('SHORT');
255
- const signalMsg = getContextualMessage(this.symbolCode, this.strategyId, 'signal');
256
- message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.signal('EXTREME')} | ${dir} | ${C.signal(signalMsg)}`;
257
- } else if (zRegime === 'high') {
258
- logType = 'signal';
259
- message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.warn('HIGH')} | ${C.dim(instrumentMsg)}`;
260
- } else if (zRegime === 'building') {
261
- message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${zColor(zScore)} ${C.info('building')} | ${C.dim(instrumentMsg)}`;
262
- } else {
263
- const scanMsg = getContextualMessage(this.symbolCode, this.strategyId, 'scanning');
264
- message = `[${C.sym(sym)}] ${C.price(price)} | Z: ${C.ok('normalized')} | ${C.dim(scanMsg)}`;
265
- }
177
+ // Z-Score high - setup forming
178
+ else if (absZ >= CONFIG.Z_HIGH) {
179
+ 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}`;
266
181
  }
267
- // EVENT 3: Bias flip (OFI direction change)
268
- else if (this.lastBias !== null && bias !== this.lastBias && bias !== 'neutral' && this.lastBias !== 'neutral') {
269
- event = 'bias_flip';
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);
273
- const flipMsg = getContextualMessage(this.symbolCode, this.strategyId, bias);
274
- message = `[${C.sym(sym)}] ${arrow} OFI: ${oldBias} → ${newBias} | ${C.dim(flipMsg)}`;
182
+ // Z-Score building
183
+ else if (absZ >= CONFIG.Z_BUILDING) {
184
+ 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}`;
275
187
  }
276
- // EVENT 4: VPIN toxicity change
277
- else if (this.lastVpinToxic !== null && vpinToxic !== this.lastVpinToxic) {
278
- event = 'vpin';
279
- const vpinPct = (vpin * 100).toFixed(0);
280
- if (vpinToxic) {
281
- message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.danger(vpinPct + '%')} ${C.danger('TOXIC')} - informed flow`;
282
- logType = 'risk';
283
- } else {
284
- message = `[${C.sym(sym)}] ${C.price(price)} | VPIN: ${C.ok(vpinPct + '%')} ${C.ok('clean')} - normal flow`;
188
+ // Z-Score neutral - scanning
189
+ else {
190
+ // Cycle through different useful info each second to avoid repetition
191
+ const infoType = Math.floor(Date.now() / 1000) % 4;
192
+ let context;
193
+ switch (infoType) {
194
+ case 0:
195
+ context = `Δ:${deltaStr} | Buy:${buyPctRound}%`;
196
+ break;
197
+ case 1:
198
+ context = `VPIN:${vpinStr} | OFI:${ofiStr}`;
199
+ break;
200
+ case 2:
201
+ context = `${tickVelocity} ticks/s | Δ:${deltaStr}`;
202
+ break;
203
+ default:
204
+ context = `OFI:${ofiStr} | Buy:${buyPctRound}%`;
285
205
  }
286
- }
287
-
288
- // Update state tracking
289
- this.lastZRegime = zRegime;
290
- this.lastBias = bias;
291
- this.lastVpinToxic = vpinToxic;
292
-
293
- if (event && message) {
294
- return { type: logType, message, logToSession: event === 'z_regime' || event === 'bias_flip' };
206
+ message = `[${C.sym(sym)}] ${priceDirColor(priceDir)} ${C.price(price)} | Z:${zStr} scanning | ${context}`;
295
207
  }
296
208
 
297
- // EVENT-DRIVEN ONLY: No spam, no repetitive logs
298
- // Silence = system is scanning, nothing notable happening
299
- // This is professional HF behavior
300
- return null;
209
+ return { type: logType, message, logToSession: logType === 'signal' };
301
210
  }
302
211
 
303
212
  reset() {
304
- this.lastState = null;
305
- this.counter = 0;
306
- this.lastBias = null;
307
- this.warmupLogged = false;
308
- // HQX-2B
309
- this.lastBars = 0;
310
- this.lastSwings = 0;
311
- this.lastZones = 0;
312
- this.lastNearZone = false;
313
- // QUANT
314
- this.lastZRegime = null;
315
- this.lastVpinToxic = false;
213
+ this.lastLogHash = null;
214
+ this.lastLogTime = 0;
215
+ this.eventCounter = 0;
216
+ this._lastWarmupMilestone = 0;
217
+ this.prev = {
218
+ zRegime: null,
219
+ ofiDir: null,
220
+ vpinLevel: null,
221
+ position: 0,
222
+ ready: false,
223
+ };
316
224
  }
317
225
  }
318
226
 
319
227
  function createEngine(strategyId, symbol) { return new SmartLogsEngine(strategyId, symbol); }
320
- module.exports = { SmartLogsEngine, createEngine, CONFIG };
228
+ module.exports = { SmartLogsEngine, createEngine, CONFIG, C };