hedgequantx 2.9.94 → 2.9.96

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.
@@ -1,705 +1 @@
1
- var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __commonJS = (cb, mod) => function __require() {
3
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
- };
5
-
6
- // ultra-scalping/config.js
7
- var require_config = __commonJS({
8
- "ultra-scalping/config.js"(exports2, module2) {
9
- var DEFAULT_CONFIG = {
10
- // Model Parameters
11
- zscoreEntryThreshold: 1.5,
12
- // Live trading threshold (backtest: 2.5)
13
- zscoreExitThreshold: 0.5,
14
- vpinWindow: 50,
15
- vpinToxicThreshold: 0.7,
16
- // Skip if VPIN > 0.7
17
- volatilityLookback: 100,
18
- ofiLookback: 20,
19
- // Trade Parameters
20
- baseStopTicks: 8,
21
- // $40
22
- baseTargetTicks: 16,
23
- // $80
24
- breakevenTicks: 4,
25
- // Move to BE at +4 ticks
26
- profitLockPct: 0.5,
27
- // Lock 50% of profit
28
- minConfidence: 0.55,
29
- // Minimum composite confidence
30
- cooldownMs: 3e4,
31
- // 30 seconds between signals
32
- minHoldTimeMs: 1e4,
33
- // Minimum 10 seconds hold
34
- // Model Weights (from Python backtest)
35
- weights: {
36
- zscore: 0.3,
37
- // 30%
38
- ofi: 0.2,
39
- // 20%
40
- vpin: 0.15,
41
- // 15%
42
- kalman: 0.15,
43
- // 15%
44
- kyleLambda: 0.1,
45
- // 10%
46
- volatility: 0.1
47
- // 10%
48
- },
49
- // Session (Futures Market Hours - Sunday 18:00 to Friday 17:00 EST)
50
- session: {
51
- enabled: false,
52
- // Trade anytime markets are open
53
- timezone: "America/New_York"
54
- }
55
- };
56
- module2.exports = { DEFAULT_CONFIG };
57
- }
58
- });
59
-
60
- // common/types.js
61
- var require_types = __commonJS({
62
- "common/types.js"(exports2, module2) {
63
- var OrderSide2 = { BID: 0, ASK: 1 };
64
- var SignalStrength2 = { WEAK: 1, MODERATE: 2, STRONG: 3, VERY_STRONG: 4 };
65
- module2.exports = { OrderSide: OrderSide2, SignalStrength: SignalStrength2 };
66
- }
67
- });
68
-
69
- // ultra-scalping/signal.js
70
- var require_signal = __commonJS({
71
- "ultra-scalping/signal.js"(exports2, module2) {
72
- var { v4: uuidv4 } = require("uuid");
73
- var { OrderSide: OrderSide2, SignalStrength: SignalStrength2 } = require_types();
74
- function generateSignal(params) {
75
- const {
76
- contractId,
77
- currentPrice,
78
- zscore,
79
- vpin,
80
- kyleLambda,
81
- kalmanEstimate,
82
- regime,
83
- volParams,
84
- ofi,
85
- config,
86
- tickSize
87
- } = params;
88
- const absZscore = Math.abs(zscore);
89
- if (absZscore < volParams.zscoreThreshold) {
90
- return null;
91
- }
92
- if (vpin > config.vpinToxicThreshold) {
93
- return null;
94
- }
95
- let direction;
96
- if (zscore < -volParams.zscoreThreshold) {
97
- direction = "long";
98
- } else if (zscore > volParams.zscoreThreshold) {
99
- direction = "short";
100
- } else {
101
- return null;
102
- }
103
- const ofiConfirms = direction === "long" && ofi > 0.1 || direction === "short" && ofi < -0.1;
104
- const kalmanDiff = currentPrice - kalmanEstimate;
105
- const kalmanConfirms = direction === "long" && kalmanDiff < 0 || direction === "short" && kalmanDiff > 0;
106
- const scores = {
107
- zscore: Math.min(1, absZscore / 4),
108
- // Normalize to 0-1
109
- vpin: 1 - vpin,
110
- // Lower VPIN = better
111
- kyleLambda: kyleLambda > 1e-3 ? 0.5 : 0.8,
112
- // Moderate lambda is good
113
- kalman: kalmanConfirms ? 0.8 : 0.4,
114
- volatility: regime === "normal" ? 0.8 : regime === "low" ? 0.7 : 0.6,
115
- ofi: ofiConfirms ? 0.9 : 0.5,
116
- composite: 0
117
- // Calculated below
118
- };
119
- scores.composite = scores.zscore * config.weights.zscore + // 30%
120
- scores.vpin * config.weights.vpin + // 15%
121
- scores.kyleLambda * config.weights.kyleLambda + // 10%
122
- scores.kalman * config.weights.kalman + // 15%
123
- scores.volatility * config.weights.volatility + // 10%
124
- scores.ofi * config.weights.ofi;
125
- const confidence = Math.min(1, scores.composite + volParams.confidenceBonus);
126
- if (confidence < config.minConfidence) {
127
- return null;
128
- }
129
- const stopTicks = Math.round(config.baseStopTicks * volParams.stopMultiplier);
130
- const targetTicks = Math.round(config.baseTargetTicks * volParams.targetMultiplier);
131
- const actualStopTicks = Math.max(6, Math.min(12, stopTicks));
132
- const actualTargetTicks = Math.max(actualStopTicks * 1.5, Math.min(24, targetTicks));
133
- let stopLoss, takeProfit, beBreakeven, profitLockLevel;
134
- if (direction === "long") {
135
- stopLoss = currentPrice - actualStopTicks * tickSize;
136
- takeProfit = currentPrice + actualTargetTicks * tickSize;
137
- beBreakeven = currentPrice + config.breakevenTicks * tickSize;
138
- profitLockLevel = currentPrice + actualTargetTicks * config.profitLockPct * tickSize;
139
- } else {
140
- stopLoss = currentPrice + actualStopTicks * tickSize;
141
- takeProfit = currentPrice - actualTargetTicks * tickSize;
142
- beBreakeven = currentPrice - config.breakevenTicks * tickSize;
143
- profitLockLevel = currentPrice - actualTargetTicks * config.profitLockPct * tickSize;
144
- }
145
- const riskReward = actualTargetTicks / actualStopTicks;
146
- const trailTriggerTicks = Math.round(actualTargetTicks * 0.5);
147
- const trailDistanceTicks = Math.round(actualStopTicks * 0.4);
148
- let strength = SignalStrength2.MODERATE;
149
- if (confidence >= 0.85) strength = SignalStrength2.VERY_STRONG;
150
- else if (confidence >= 0.75) strength = SignalStrength2.STRONG;
151
- else if (confidence < 0.6) strength = SignalStrength2.WEAK;
152
- const winProb = 0.5 + (confidence - 0.5) * 0.4;
153
- const edge = winProb * Math.abs(takeProfit - currentPrice) - (1 - winProb) * Math.abs(currentPrice - stopLoss);
154
- return {
155
- id: uuidv4(),
156
- timestamp: Date.now(),
157
- symbol: contractId.split(".")[0] || contractId,
158
- contractId,
159
- side: direction === "long" ? OrderSide2.BID : OrderSide2.ASK,
160
- direction,
161
- strategy: "HQX_ULTRA_SCALPING_6MODELS",
162
- strength,
163
- edge,
164
- confidence,
165
- entry: currentPrice,
166
- entryPrice: currentPrice,
167
- stopLoss,
168
- takeProfit,
169
- riskReward,
170
- stopTicks: actualStopTicks,
171
- targetTicks: actualTargetTicks,
172
- trailTriggerTicks,
173
- trailDistanceTicks,
174
- beBreakeven,
175
- profitLockLevel,
176
- // Model values for debugging/monitoring
177
- zScore: zscore,
178
- zScoreExit: config.zscoreExitThreshold,
179
- vpinValue: vpin,
180
- kyleLambda,
181
- kalmanEstimate,
182
- volatilityRegime: regime,
183
- ofiValue: ofi,
184
- models: scores,
185
- // Order flow confirmation flag
186
- orderFlowConfirmed: ofiConfirms,
187
- kalmanConfirmed: kalmanConfirms,
188
- expires: Date.now() + 6e4
189
- };
190
- }
191
- module2.exports = { generateSignal };
192
- }
193
- });
194
-
195
- // ultra-scalping/models/zscore.js
196
- var require_zscore = __commonJS({
197
- "ultra-scalping/models/zscore.js"(exports2, module2) {
198
- function computeZScore(prices, window = 50) {
199
- if (prices.length < window) return 0;
200
- const recentPrices = prices.slice(-window);
201
- const mean = recentPrices.reduce((a, b) => a + b, 0) / window;
202
- const variance = recentPrices.reduce((sum, p) => sum + Math.pow(p - mean, 2), 0) / window;
203
- const std = Math.sqrt(variance);
204
- if (std < 1e-4) return 0;
205
- const currentPrice = prices[prices.length - 1];
206
- return (currentPrice - mean) / std;
207
- }
208
- module2.exports = { computeZScore };
209
- }
210
- });
211
-
212
- // ultra-scalping/models/vpin.js
213
- var require_vpin = __commonJS({
214
- "ultra-scalping/models/vpin.js"(exports2, module2) {
215
- function computeVPIN(volumes, vpinWindow = 50) {
216
- if (volumes.length < vpinWindow) return 0.5;
217
- const recentVolumes = volumes.slice(-vpinWindow);
218
- let totalBuy = 0;
219
- let totalSell = 0;
220
- for (const v of recentVolumes) {
221
- totalBuy += v.buy;
222
- totalSell += v.sell;
223
- }
224
- const totalVolume = totalBuy + totalSell;
225
- if (totalVolume < 1) return 0.5;
226
- return Math.abs(totalBuy - totalSell) / totalVolume;
227
- }
228
- module2.exports = { computeVPIN };
229
- }
230
- });
231
-
232
- // ultra-scalping/models/kyle.js
233
- var require_kyle = __commonJS({
234
- "ultra-scalping/models/kyle.js"(exports2, module2) {
235
- function computeKyleLambda(bars) {
236
- if (bars.length < 20) return 0;
237
- const recentBars = bars.slice(-20);
238
- const priceChanges = [];
239
- const volumes = [];
240
- for (let i = 1; i < recentBars.length; i++) {
241
- priceChanges.push(recentBars[i].close - recentBars[i - 1].close);
242
- volumes.push(recentBars[i].volume);
243
- }
244
- const meanPrice = priceChanges.reduce((a, b) => a + b, 0) / priceChanges.length;
245
- const meanVol = volumes.reduce((a, b) => a + b, 0) / volumes.length;
246
- let covariance = 0;
247
- let varianceVol = 0;
248
- for (let i = 0; i < priceChanges.length; i++) {
249
- covariance += (priceChanges[i] - meanPrice) * (volumes[i] - meanVol);
250
- varianceVol += Math.pow(volumes[i] - meanVol, 2);
251
- }
252
- covariance /= priceChanges.length;
253
- varianceVol /= priceChanges.length;
254
- if (varianceVol < 1e-4) return 0;
255
- return Math.abs(covariance / varianceVol);
256
- }
257
- module2.exports = { computeKyleLambda };
258
- }
259
- });
260
-
261
- // ultra-scalping/models/kalman.js
262
- var require_kalman = __commonJS({
263
- "ultra-scalping/models/kalman.js"(exports2, module2) {
264
- var KALMAN_PROCESS_NOISE = 0.01;
265
- var KALMAN_MEASUREMENT_NOISE = 0.1;
266
- function applyKalmanFilter(state, measurement) {
267
- if (!state || state.estimate === 0) {
268
- return {
269
- estimate: measurement,
270
- errorCovariance: 1,
271
- newEstimate: measurement
272
- };
273
- }
274
- const predictedEstimate = state.estimate;
275
- const predictedCovariance = state.errorCovariance + KALMAN_PROCESS_NOISE;
276
- const kalmanGain = predictedCovariance / (predictedCovariance + KALMAN_MEASUREMENT_NOISE);
277
- const newEstimate = predictedEstimate + kalmanGain * (measurement - predictedEstimate);
278
- const newCovariance = (1 - kalmanGain) * predictedCovariance;
279
- return {
280
- estimate: newEstimate,
281
- errorCovariance: newCovariance,
282
- newEstimate
283
- };
284
- }
285
- function createKalmanState() {
286
- return {
287
- estimate: 0,
288
- errorCovariance: 1
289
- };
290
- }
291
- module2.exports = {
292
- applyKalmanFilter,
293
- createKalmanState,
294
- KALMAN_PROCESS_NOISE,
295
- KALMAN_MEASUREMENT_NOISE
296
- };
297
- }
298
- });
299
-
300
- // ultra-scalping/models/volatility.js
301
- var require_volatility = __commonJS({
302
- "ultra-scalping/models/volatility.js"(exports2, module2) {
303
- function calculateATR(bars, period = 14) {
304
- if (bars.length < period + 1) return 2.5;
305
- const trValues = [];
306
- for (let i = bars.length - period; i < bars.length; i++) {
307
- const bar = bars[i];
308
- const prevClose = bars[i - 1].close;
309
- const tr = Math.max(
310
- bar.high - bar.low,
311
- Math.abs(bar.high - prevClose),
312
- Math.abs(bar.low - prevClose)
313
- );
314
- trValues.push(tr);
315
- }
316
- return trValues.reduce((a, b) => a + b, 0) / trValues.length;
317
- }
318
- function detectVolatilityRegime(atr, atrHistory, tickSize) {
319
- let atrPercentile = 0.5;
320
- if (atrHistory.length >= 20) {
321
- atrPercentile = atrHistory.filter((a) => a <= atr).length / atrHistory.length;
322
- }
323
- let regime, params;
324
- if (atrPercentile < 0.25) {
325
- regime = "low";
326
- params = {
327
- stopMultiplier: 0.8,
328
- targetMultiplier: 0.9,
329
- zscoreThreshold: 1.2,
330
- confidenceBonus: 0.05
331
- };
332
- } else if (atrPercentile < 0.75) {
333
- regime = "normal";
334
- params = {
335
- stopMultiplier: 1,
336
- targetMultiplier: 1,
337
- zscoreThreshold: 1.5,
338
- confidenceBonus: 0
339
- };
340
- } else {
341
- regime = "high";
342
- params = {
343
- stopMultiplier: 1.3,
344
- targetMultiplier: 1.2,
345
- zscoreThreshold: 2,
346
- confidenceBonus: -0.05
347
- };
348
- }
349
- return { regime, params, atrPercentile };
350
- }
351
- module2.exports = { calculateATR, detectVolatilityRegime };
352
- }
353
- });
354
-
355
- // ultra-scalping/models/ofi.js
356
- var require_ofi = __commonJS({
357
- "ultra-scalping/models/ofi.js"(exports2, module2) {
358
- function computeOrderFlowImbalance(bars, lookback = 20) {
359
- if (bars.length < lookback) return 0;
360
- const recentBars = bars.slice(-lookback);
361
- let totalBuyPressure = 0;
362
- let totalSellPressure = 0;
363
- for (const bar of recentBars) {
364
- const barRange = bar.high - bar.low;
365
- if (barRange > 0) {
366
- const closePosition = (bar.close - bar.low) / barRange;
367
- totalBuyPressure += closePosition * bar.volume;
368
- totalSellPressure += (1 - closePosition) * bar.volume;
369
- }
370
- }
371
- const totalPressure = totalBuyPressure + totalSellPressure;
372
- if (totalPressure < 1) return 0;
373
- return (totalBuyPressure - totalSellPressure) / totalPressure;
374
- }
375
- module2.exports = { computeOrderFlowImbalance };
376
- }
377
- });
378
-
379
- // ultra-scalping/models/index.js
380
- var require_models = __commonJS({
381
- "ultra-scalping/models/index.js"(exports2, module2) {
382
- var { computeZScore } = require_zscore();
383
- var { computeVPIN } = require_vpin();
384
- var { computeKyleLambda } = require_kyle();
385
- var { applyKalmanFilter, createKalmanState } = require_kalman();
386
- var { calculateATR, detectVolatilityRegime } = require_volatility();
387
- var { computeOrderFlowImbalance } = require_ofi();
388
- module2.exports = {
389
- computeZScore,
390
- computeVPIN,
391
- computeKyleLambda,
392
- applyKalmanFilter,
393
- createKalmanState,
394
- calculateATR,
395
- detectVolatilityRegime,
396
- computeOrderFlowImbalance
397
- };
398
- }
399
- });
400
-
401
- // ultra-scalping/core.js
402
- var require_core = __commonJS({
403
- "ultra-scalping/core.js"(exports2, module2) {
404
- var EventEmitter2 = require("events");
405
- var { DEFAULT_CONFIG } = require_config();
406
- var { generateSignal } = require_signal();
407
- var {
408
- computeZScore,
409
- computeVPIN,
410
- computeKyleLambda,
411
- applyKalmanFilter,
412
- createKalmanState,
413
- calculateATR,
414
- detectVolatilityRegime,
415
- computeOrderFlowImbalance
416
- } = require_models();
417
- var HQXUltraScalping2 = class extends EventEmitter2 {
418
- constructor(config = {}) {
419
- super();
420
- this.tickSize = config.tickSize || 0.25;
421
- this.tickValue = config.tickValue || 5;
422
- this.config = { ...DEFAULT_CONFIG, ...config };
423
- this.barHistory = /* @__PURE__ */ new Map();
424
- this.priceBuffer = /* @__PURE__ */ new Map();
425
- this.volumeBuffer = /* @__PURE__ */ new Map();
426
- this.kalmanStates = /* @__PURE__ */ new Map();
427
- this.atrHistory = /* @__PURE__ */ new Map();
428
- this.recentTrades = [];
429
- this.winStreak = 0;
430
- this.lossStreak = 0;
431
- this.lastSignalTime = 0;
432
- this.stats = { signals: 0, trades: 0, wins: 0, losses: 0, pnl: 0 };
433
- }
434
- initialize(contractId, tickSize = 0.25, tickValue = 5) {
435
- this.tickSize = tickSize;
436
- this.tickValue = tickValue;
437
- this.barHistory.set(contractId, []);
438
- this.priceBuffer.set(contractId, []);
439
- this.volumeBuffer.set(contractId, []);
440
- this.atrHistory.set(contractId, []);
441
- this.kalmanStates.set(contractId, createKalmanState());
442
- this.emit("log", {
443
- type: "info",
444
- message: `[HQX-UltraScalping] Initialized for ${contractId}: tick=${tickSize}, value=${tickValue}`
445
- });
446
- this.emit("log", {
447
- type: "info",
448
- message: `[HQX-UltraScalping] 6 Models: Z-Score(30%), OFI(20%), VPIN(15%), Kalman(15%), Kyle(10%), Vol(10%)`
449
- });
450
- }
451
- processTick(tick) {
452
- const { contractId, price, volume, timestamp } = tick;
453
- const bar = {
454
- timestamp: timestamp || Date.now(),
455
- open: price,
456
- high: price,
457
- low: price,
458
- close: price,
459
- volume: volume || 1
460
- };
461
- return this.processBar(contractId, bar);
462
- }
463
- onTick(tick) {
464
- return this.processTick(tick);
465
- }
466
- onTrade(trade) {
467
- return this.processTick({
468
- contractId: trade.contractId || trade.symbol,
469
- price: trade.price,
470
- volume: trade.size || trade.volume || 1,
471
- side: trade.side,
472
- timestamp: trade.timestamp || Date.now()
473
- });
474
- }
475
- processBar(contractId, bar) {
476
- let bars = this.barHistory.get(contractId);
477
- if (!bars) {
478
- this.initialize(contractId);
479
- bars = this.barHistory.get(contractId);
480
- }
481
- bars.push(bar);
482
- if (bars.length > 500) bars.shift();
483
- const prices = this.priceBuffer.get(contractId);
484
- prices.push(bar.close);
485
- if (prices.length > 200) prices.shift();
486
- const volumes = this.volumeBuffer.get(contractId);
487
- const barRange = bar.high - bar.low;
488
- let buyVol = bar.volume * 0.5;
489
- let sellVol = bar.volume * 0.5;
490
- if (barRange > 0) {
491
- const closePosition = (bar.close - bar.low) / barRange;
492
- buyVol = bar.volume * closePosition;
493
- sellVol = bar.volume * (1 - closePosition);
494
- }
495
- volumes.push({ buy: buyVol, sell: sellVol });
496
- if (volumes.length > 100) volumes.shift();
497
- if (bars.length < 50) return null;
498
- const zscore = computeZScore(prices);
499
- const vpin = computeVPIN(volumes, this.config.vpinWindow);
500
- const kyleLambda = computeKyleLambda(bars);
501
- const kalmanState = this.kalmanStates.get(contractId);
502
- const kalmanResult = applyKalmanFilter(kalmanState, bar.close);
503
- this.kalmanStates.set(contractId, {
504
- estimate: kalmanResult.estimate,
505
- errorCovariance: kalmanResult.errorCovariance
506
- });
507
- const kalmanEstimate = kalmanResult.newEstimate;
508
- const atr = calculateATR(bars);
509
- const atrHist = this.atrHistory.get(contractId);
510
- atrHist.push(atr);
511
- if (atrHist.length > 500) atrHist.shift();
512
- const { regime, params: volParams } = detectVolatilityRegime(atr, atrHist, this.tickSize);
513
- const ofi = computeOrderFlowImbalance(bars, this.config.ofiLookback);
514
- if (Date.now() - this.lastSignalTime < this.config.cooldownMs) {
515
- return null;
516
- }
517
- const signal = generateSignal({
518
- contractId,
519
- currentPrice: bar.close,
520
- zscore,
521
- vpin,
522
- kyleLambda,
523
- kalmanEstimate,
524
- regime,
525
- volParams,
526
- ofi,
527
- config: this.config,
528
- tickSize: this.tickSize
529
- });
530
- if (signal) {
531
- this.lastSignalTime = Date.now();
532
- this.stats.signals++;
533
- this.emit("signal", {
534
- side: signal.direction === "long" ? "buy" : "sell",
535
- action: "open",
536
- reason: `Z=${zscore.toFixed(2)}, VPIN=${(vpin * 100).toFixed(0)}%, OFI=${(ofi * 100).toFixed(0)}%, cf=${(signal.confidence * 100).toFixed(0)}%`,
537
- ...signal
538
- });
539
- this.emit("log", {
540
- type: "info",
541
- message: `[HQX] SIGNAL: ${signal.direction.toUpperCase()} @ ${bar.close.toFixed(2)} | Z:${zscore.toFixed(2)} VPIN:${(vpin * 100).toFixed(0)}% OFI:${(ofi * 100).toFixed(0)}% Kyle:${kyleLambda.toFixed(5)} Regime:${regime} | Conf:${(signal.confidence * 100).toFixed(0)}%`
542
- });
543
- }
544
- return signal;
545
- }
546
- shouldExitByZScore(contractId) {
547
- const prices = this.priceBuffer.get(contractId);
548
- if (!prices || prices.length < 50) return false;
549
- const zscore = computeZScore(prices);
550
- return Math.abs(zscore) < this.config.zscoreExitThreshold;
551
- }
552
- getModelValues(contractId) {
553
- const prices = this.priceBuffer.get(contractId);
554
- const volumes = this.volumeBuffer.get(contractId);
555
- const bars = this.barHistory.get(contractId);
556
- if (!prices || !volumes || !bars || bars.length < 50) {
557
- return null;
558
- }
559
- const zscore = computeZScore(prices);
560
- const vpin = computeVPIN(volumes, this.config.vpinWindow);
561
- const kyleLambda = computeKyleLambda(bars);
562
- const ofi = computeOrderFlowImbalance(bars, this.config.ofiLookback);
563
- return {
564
- zscore: Math.min(1, Math.abs(zscore) / 4),
565
- vpin: 1 - vpin,
566
- kyleLambda: kyleLambda > 1e-3 ? 0.5 : 0.8,
567
- kalman: 0.7,
568
- volatility: 0.7,
569
- ofi: Math.abs(ofi) > 0.1 ? 0.8 : 0.5,
570
- composite: 0.7,
571
- raw: { zscore, vpin, kyleLambda, ofi }
572
- };
573
- }
574
- getAnalysisState(contractId, currentPrice) {
575
- const bars = this.barHistory.get(contractId) || [];
576
- if (bars.length < 50) {
577
- return { ready: false, message: `Collecting data... ${bars.length}/50 bars` };
578
- }
579
- const prices = this.priceBuffer.get(contractId) || [];
580
- const volumes = this.volumeBuffer.get(contractId) || [];
581
- const atrHist = this.atrHistory.get(contractId) || [];
582
- const zscore = computeZScore(prices);
583
- const vpin = computeVPIN(volumes, this.config.vpinWindow);
584
- const ofi = computeOrderFlowImbalance(bars, this.config.ofiLookback);
585
- const kyleLambda = computeKyleLambda(bars);
586
- const atr = calculateATR(bars);
587
- const { regime, params } = detectVolatilityRegime(atr, atrHist, this.tickSize);
588
- return {
589
- ready: true,
590
- zScore: zscore,
591
- vpin,
592
- ofi,
593
- kyleLambda,
594
- regime,
595
- stopTicks: Math.round(this.config.baseStopTicks * params.stopMultiplier),
596
- targetTicks: Math.round(this.config.baseTargetTicks * params.targetMultiplier),
597
- threshold: params.zscoreThreshold,
598
- barsProcessed: bars.length,
599
- models: "6 (Z-Score, VPIN, Kyle, Kalman, Vol, OFI)"
600
- };
601
- }
602
- recordTradeResult(pnl) {
603
- this.recentTrades.push({ netPnl: pnl, timestamp: Date.now() });
604
- if (this.recentTrades.length > 100) this.recentTrades.shift();
605
- if (pnl > 0) {
606
- this.winStreak++;
607
- this.lossStreak = 0;
608
- this.stats.wins++;
609
- } else {
610
- this.lossStreak++;
611
- this.winStreak = 0;
612
- this.stats.losses++;
613
- }
614
- this.stats.trades++;
615
- this.stats.pnl += pnl;
616
- this.emit("log", {
617
- type: "debug",
618
- message: `[HQX] Trade result: ${pnl > 0 ? "WIN" : "LOSS"} $${pnl.toFixed(2)}, streak: ${pnl > 0 ? this.winStreak : -this.lossStreak}`
619
- });
620
- }
621
- getBarHistory(contractId) {
622
- return this.barHistory.get(contractId) || [];
623
- }
624
- getStats() {
625
- return this.stats;
626
- }
627
- reset(contractId) {
628
- this.barHistory.set(contractId, []);
629
- this.priceBuffer.set(contractId, []);
630
- this.volumeBuffer.set(contractId, []);
631
- this.atrHistory.set(contractId, []);
632
- this.kalmanStates.set(contractId, createKalmanState());
633
- this.emit("log", {
634
- type: "info",
635
- message: `[HQX-UltraScalping] Reset state for ${contractId}`
636
- });
637
- }
638
- };
639
- module2.exports = { HQXUltraScalping: HQXUltraScalping2 };
640
- }
641
- });
642
-
643
- // ultra-scalping/index.js
644
- var EventEmitter = require("events");
645
- var { HQXUltraScalping } = require_core();
646
- var { OrderSide, SignalStrength } = require_types();
647
- var UltraScalpingStrategy = class extends EventEmitter {
648
- constructor(config = {}) {
649
- super();
650
- this.config = config;
651
- this.strategy = new HQXUltraScalping(config);
652
- this.strategy.on("signal", (sig) => this.emit("signal", sig));
653
- this.strategy.on("log", (log) => this.emit("log", log));
654
- }
655
- // Interface methods (compatible with M1)
656
- processTick(tick) {
657
- return this.strategy.processTick(tick);
658
- }
659
- onTick(tick) {
660
- return this.strategy.onTick(tick);
661
- }
662
- onTrade(trade) {
663
- return this.strategy.onTrade(trade);
664
- }
665
- processBar(contractId, bar) {
666
- return this.strategy.processBar(contractId, bar);
667
- }
668
- initialize(contractId, tickSize, tickValue) {
669
- return this.strategy.initialize(contractId, tickSize, tickValue);
670
- }
671
- getAnalysisState(contractId, price) {
672
- return this.strategy.getAnalysisState(contractId, price);
673
- }
674
- recordTradeResult(pnl) {
675
- return this.strategy.recordTradeResult(pnl);
676
- }
677
- reset(contractId) {
678
- return this.strategy.reset(contractId);
679
- }
680
- getStats() {
681
- return this.strategy.getStats();
682
- }
683
- getBarHistory(contractId) {
684
- return this.strategy.getBarHistory(contractId);
685
- }
686
- getModelValues(contractId) {
687
- return this.strategy.getModelValues(contractId);
688
- }
689
- shouldExitByZScore(contractId) {
690
- return this.strategy.shouldExitByZScore(contractId);
691
- }
692
- generateSignal(params) {
693
- return null;
694
- }
695
- // Signals come from processBar
696
- };
697
- module.exports = {
698
- HQXUltraScalping,
699
- UltraScalpingStrategy,
700
- // Aliases for backward compatibility
701
- M1: UltraScalpingStrategy,
702
- S1: HQXUltraScalping,
703
- OrderSide,
704
- SignalStrength
705
- };
1
+ const _0x25ec0c=_0x681d;function _0x1ce9(){const _0x591cb0=['WEAK','53200VgJmOL','reduce','6VRNGeR','trades','_calculateATR','vpinWindow','barHistory','max','_computeZScore','_generateSignal','estimate','onTrade','1713NlwPVu','toUpperCase','2874529FubOBY',':\x20tick=','zscoreEntryThreshold','/50\x20bars','strategy','getBarHistory','sqrt','atrHistory','kyleLambda','buy','breakevenTicks','generateSignal','[HQX]\x20Trade\x20result:\x20','zscoreExitThreshold','kalman','42518oTQpBD','get','short','open','emit','\x20@\x20','_computeOrderFlowImbalance','tickSize','stats','lastSignalTime','getStats','toFixed','winStreak','signal','zscoreThreshold','%,\x20OFI=','volumeBuffer','715772vlgJvY','confidenceBonus','abs','high','16LvQzXm','symbol','vpinToxicThreshold','ASK','weights','close','LOSS','recentTrades','12026840ZgJdoz','uuid','STRONG','\x20Regime:','_detectVolatilityRegime','volume','tickValue','onTick','processBar','6\x20(Z-Score,\x20VPIN,\x20Kyle,\x20Kalman,\x20Vol,\x20OFI)','processTick','[HQX-UltraScalping]\x20Initialized\x20for\x20','stopMultiplier','round','_computeVPIN','424UThnFM','\x20|\x20Conf:','long','reset','1960569dOqUUn','priceBuffer','vpin','profitLockPct','ofiLookback','_computeKyleLambda','min','kalmanMeasurementNoise','info','signals','set','shouldExitByZScore','recordTradeResult','push','filter','getAnalysisState','slice','baseStopTicks','baseTargetTicks','low','lossStreak','log','shift','length'];_0x1ce9=function(){return _0x591cb0;};return _0x1ce9();}(function(_0x3ecadb,_0x5aa991){const _0x145507=_0x681d,_0x4ab801=_0x3ecadb();while(!![]){try{const _0x1a76a7=-parseInt(_0x145507(0x14e))/0x1+parseInt(_0x145507(0x17a))/0x2*(parseInt(_0x145507(0x13d))/0x3)+-parseInt(_0x145507(0x15f))/0x4+-parseInt(_0x145507(0x131))/0x5+-parseInt(_0x145507(0x133))/0x6*(parseInt(_0x145507(0x13f))/0x7)+-parseInt(_0x145507(0x163))/0x8*(parseInt(_0x145507(0x118))/0x9)+parseInt(_0x145507(0x16b))/0xa;if(_0x1a76a7===_0x5aa991)break;else _0x4ab801['push'](_0x4ab801['shift']());}catch(_0x4f1393){_0x4ab801['push'](_0x4ab801['shift']());}}}(_0x1ce9,0x3be3a));const EventEmitter=require('events'),{v4:uuidv4}=require(_0x25ec0c(0x16c)),OrderSide={'BID':0x0,'ASK':0x1},SignalStrength={'WEAK':0x1,'MODERATE':0x2,'STRONG':0x3,'VERY_STRONG':0x4};function _0x681d(_0x13eb78,_0xc9ff03){_0x13eb78=_0x13eb78-0x118;const _0x1ce911=_0x1ce9();let _0x681d0c=_0x1ce911[_0x13eb78];return _0x681d0c;}class HQXUltraScalping extends EventEmitter{constructor(_0x24eb07={}){const _0x569675=_0x25ec0c;super(),this[_0x569675(0x155)]=_0x24eb07[_0x569675(0x155)]||0.25,this[_0x569675(0x171)]=_0x24eb07['tickValue']||0x5,this[_0x569675(0x141)]=1.5,this['zscoreExitThreshold']=0.5,this[_0x569675(0x136)]=0x32,this['vpinToxicThreshold']=0.7,this['kalmanProcessNoise']=0.01,this['kalmanMeasurementNoise']=0.1,this['volatilityLookback']=0x64,this['ofiLookback']=0x14,this['baseStopTicks']=0x8,this[_0x569675(0x12a)]=0x10,this['breakevenTicks']=0x4,this[_0x569675(0x11b)]=0.5,this['minConfidence']=0.55,this[_0x569675(0x167)]={'zscore':0.3,'ofi':0.2,'vpin':0.15,'kalman':0.15,'kyleLambda':0.1,'volatility':0.1},this[_0x569675(0x137)]=new Map(),this['priceBuffer']=new Map(),this[_0x569675(0x15e)]=new Map(),this['kalmanStates']=new Map(),this[_0x569675(0x146)]=new Map(),this[_0x569675(0x16a)]=[],this[_0x569675(0x15a)]=0x0,this[_0x569675(0x12c)]=0x0,this['lastSignalTime']=0x0,this['cooldownMs']=0x7530,this['minHoldTimeMs']=0x2710,this[_0x569675(0x156)]={'signals':0x0,'trades':0x0,'wins':0x0,'losses':0x0,'pnl':0x0};}['initialize'](_0xd388e8,_0x16d8cf=0.25,_0x138a3a=0x5){const _0x52a9ba=_0x25ec0c;this[_0x52a9ba(0x155)]=_0x16d8cf,this['tickValue']=_0x138a3a,this['barHistory']['set'](_0xd388e8,[]),this[_0x52a9ba(0x119)]['set'](_0xd388e8,[]),this['volumeBuffer'][_0x52a9ba(0x122)](_0xd388e8,[]),this[_0x52a9ba(0x146)][_0x52a9ba(0x122)](_0xd388e8,[]),this['kalmanStates']['set'](_0xd388e8,{'estimate':0x0,'errorCovariance':0x1}),this[_0x52a9ba(0x152)](_0x52a9ba(0x12d),{'type':_0x52a9ba(0x120),'message':_0x52a9ba(0x176)+_0xd388e8+_0x52a9ba(0x140)+_0x16d8cf+',\x20value='+_0x138a3a}),this['emit']('log',{'type':'info','message':'[HQX-UltraScalping]\x206\x20Models:\x20Z-Score(30%),\x20OFI(20%),\x20VPIN(15%),\x20Kalman(15%),\x20Kyle(10%),\x20Vol(10%)'});}[_0x25ec0c(0x175)](_0x564aca){const {contractId:_0x45b123,price:_0x167042,volume:_0x8c0e5d,side:_0xffe477,timestamp:_0x28a9d8}=_0x564aca,_0x5c0322={'timestamp':_0x28a9d8||Date['now'](),'open':_0x167042,'high':_0x167042,'low':_0x167042,'close':_0x167042,'volume':_0x8c0e5d||0x1};return this['processBar'](_0x45b123,_0x5c0322);}['onTick'](_0xc80be9){const _0xf652d9=_0x25ec0c;return this[_0xf652d9(0x175)](_0xc80be9);}[_0x25ec0c(0x13c)](_0x4fbdeb){const _0x250d38=_0x25ec0c;return this['processTick']({'contractId':_0x4fbdeb['contractId']||_0x4fbdeb[_0x250d38(0x164)],'price':_0x4fbdeb['price'],'volume':_0x4fbdeb['size']||_0x4fbdeb['volume']||0x1,'side':_0x4fbdeb['side'],'timestamp':_0x4fbdeb['timestamp']||Date['now']()});}['processBar'](_0x1442cf,_0x231c33){const _0x4a41d8=_0x25ec0c;let _0x532f3f=this['barHistory']['get'](_0x1442cf);!_0x532f3f&&(this['initialize'](_0x1442cf),_0x532f3f=this[_0x4a41d8(0x137)]['get'](_0x1442cf));_0x532f3f['push'](_0x231c33);if(_0x532f3f[_0x4a41d8(0x12f)]>0x1f4)_0x532f3f['shift']();const _0x54c1a3=this[_0x4a41d8(0x119)][_0x4a41d8(0x14f)](_0x1442cf);_0x54c1a3['push'](_0x231c33['close']);if(_0x54c1a3['length']>0xc8)_0x54c1a3[_0x4a41d8(0x12e)]();const _0x3e12c6=this[_0x4a41d8(0x15e)][_0x4a41d8(0x14f)](_0x1442cf),_0x20f9d8=_0x231c33[_0x4a41d8(0x162)]-_0x231c33[_0x4a41d8(0x12b)];let _0x4cce04=_0x231c33['volume']*0.5,_0xa5bffa=_0x231c33['volume']*0.5;if(_0x20f9d8>0x0){const _0x3c114e=(_0x231c33['close']-_0x231c33[_0x4a41d8(0x12b)])/_0x20f9d8;_0x4cce04=_0x231c33['volume']*_0x3c114e,_0xa5bffa=_0x231c33['volume']*(0x1-_0x3c114e);}_0x3e12c6[_0x4a41d8(0x125)]({'buy':_0x4cce04,'sell':_0xa5bffa});if(_0x3e12c6['length']>0x64)_0x3e12c6['shift']();if(_0x532f3f[_0x4a41d8(0x12f)]<0x32)return null;const _0x4a5788=this['_computeZScore'](_0x54c1a3),_0x4337d1=this['_computeVPIN'](_0x3e12c6),_0x5120e2=this[_0x4a41d8(0x11d)](_0x532f3f),_0x5cd1fc=this['_applyKalmanFilter'](_0x1442cf,_0x231c33['close']),{regime:_0x1e8732,params:_0x36dd63}=this[_0x4a41d8(0x16f)](_0x1442cf,_0x532f3f),_0x455254=this[_0x4a41d8(0x154)](_0x532f3f);return this[_0x4a41d8(0x13a)](_0x1442cf,_0x231c33[_0x4a41d8(0x168)],_0x4a5788,_0x4337d1,_0x5120e2,_0x5cd1fc,_0x1e8732,_0x36dd63,_0x455254,_0x532f3f);}['_computeZScore'](_0x56cc77,_0x44e30c=0x32){const _0x203b4e=_0x25ec0c;if(_0x56cc77['length']<_0x44e30c)return 0x0;const _0x1d8e30=_0x56cc77['slice'](-_0x44e30c),_0x36705a=_0x1d8e30[_0x203b4e(0x132)]((_0x333ff7,_0x3cf675)=>_0x333ff7+_0x3cf675,0x0)/_0x44e30c,_0x2de8f6=_0x1d8e30[_0x203b4e(0x132)]((_0x1f8c86,_0x27057b)=>_0x1f8c86+Math['pow'](_0x27057b-_0x36705a,0x2),0x0)/_0x44e30c,_0x2a63f3=Math[_0x203b4e(0x145)](_0x2de8f6);if(_0x2a63f3<0.0001)return 0x0;const _0x2a0b8c=_0x56cc77[_0x56cc77[_0x203b4e(0x12f)]-0x1];return(_0x2a0b8c-_0x36705a)/_0x2a63f3;}['_computeVPIN'](_0x2f67d7){const _0x1ee21a=_0x25ec0c;if(_0x2f67d7['length']<this[_0x1ee21a(0x136)])return 0.5;const _0x3920b3=_0x2f67d7['slice'](-this[_0x1ee21a(0x136)]);let _0x5e1231=0x0,_0x3057c5=0x0;for(const _0x1f11ed of _0x3920b3){_0x5e1231+=_0x1f11ed[_0x1ee21a(0x148)],_0x3057c5+=_0x1f11ed['sell'];}const _0x488ca2=_0x5e1231+_0x3057c5;if(_0x488ca2<0x1)return 0.5;return Math['abs'](_0x5e1231-_0x3057c5)/_0x488ca2;}['_computeKyleLambda'](_0x3e58e0){const _0x3c008a=_0x25ec0c;if(_0x3e58e0['length']<0x14)return 0x0;const _0x377e14=_0x3e58e0['slice'](-0x14),_0x383b9d=[],_0x41ee55=[];for(let _0x4417f7=0x1;_0x4417f7<_0x377e14['length'];_0x4417f7++){_0x383b9d['push'](_0x377e14[_0x4417f7][_0x3c008a(0x168)]-_0x377e14[_0x4417f7-0x1][_0x3c008a(0x168)]),_0x41ee55['push'](_0x377e14[_0x4417f7][_0x3c008a(0x170)]);}const _0x304307=_0x383b9d[_0x3c008a(0x132)]((_0x4a85d8,_0x4472f5)=>_0x4a85d8+_0x4472f5,0x0)/_0x383b9d['length'],_0x1b3832=_0x41ee55['reduce']((_0x5908ed,_0x3d50b3)=>_0x5908ed+_0x3d50b3,0x0)/_0x41ee55['length'];let _0x334ee2=0x0,_0x386c5e=0x0;for(let _0x41f00e=0x0;_0x41f00e<_0x383b9d[_0x3c008a(0x12f)];_0x41f00e++){_0x334ee2+=(_0x383b9d[_0x41f00e]-_0x304307)*(_0x41ee55[_0x41f00e]-_0x1b3832),_0x386c5e+=Math['pow'](_0x41ee55[_0x41f00e]-_0x1b3832,0x2);}_0x334ee2/=_0x383b9d['length'],_0x386c5e/=_0x383b9d['length'];if(_0x386c5e<0.0001)return 0x0;return Math['abs'](_0x334ee2/_0x386c5e);}['_applyKalmanFilter'](_0x2ba437,_0x55dc91){const _0x5e51c2=_0x25ec0c;let _0x5d6e15=this['kalmanStates']['get'](_0x2ba437);if(!_0x5d6e15)return _0x5d6e15={'estimate':_0x55dc91,'errorCovariance':0x1},this['kalmanStates']['set'](_0x2ba437,_0x5d6e15),_0x55dc91;const _0x326864=_0x5d6e15[_0x5e51c2(0x13b)],_0x63370d=_0x5d6e15['errorCovariance']+this['kalmanProcessNoise'],_0x2c0592=_0x63370d/(_0x63370d+this[_0x5e51c2(0x11f)]),_0x136516=_0x326864+_0x2c0592*(_0x55dc91-_0x326864),_0x288567=(0x1-_0x2c0592)*_0x63370d;return _0x5d6e15[_0x5e51c2(0x13b)]=_0x136516,_0x5d6e15['errorCovariance']=_0x288567,_0x136516;}[_0x25ec0c(0x16f)](_0x5e689e,_0x44afd7){const _0x3b5214=_0x25ec0c,_0x31ae07=this[_0x3b5214(0x135)](_0x44afd7),_0x144e0d=_0x31ae07/this['tickSize'];let _0x54ac70=this[_0x3b5214(0x146)][_0x3b5214(0x14f)](_0x5e689e);!_0x54ac70&&(_0x54ac70=[],this['atrHistory'][_0x3b5214(0x122)](_0x5e689e,_0x54ac70));_0x54ac70[_0x3b5214(0x125)](_0x31ae07);if(_0x54ac70['length']>0x1f4)_0x54ac70['shift']();let _0x60c15a=0.5;_0x54ac70['length']>=0x14&&(_0x60c15a=_0x54ac70[_0x3b5214(0x126)](_0x2c4acf=>_0x2c4acf<=_0x31ae07)['length']/_0x54ac70['length']);let _0x31775f,_0x136e93;if(_0x60c15a<0.25)_0x31775f='low',_0x136e93={'stopMultiplier':0.8,'targetMultiplier':0.9,'zscoreThreshold':1.2,'confidenceBonus':0.05};else _0x60c15a<0.75?(_0x31775f='normal',_0x136e93={'stopMultiplier':0x1,'targetMultiplier':0x1,'zscoreThreshold':1.5,'confidenceBonus':0x0}):(_0x31775f='high',_0x136e93={'stopMultiplier':1.3,'targetMultiplier':1.2,'zscoreThreshold':0x2,'confidenceBonus':-0.05});return{'regime':_0x31775f,'params':_0x136e93};}['_calculateATR'](_0x272d28,_0x26ea80=0xe){const _0x4764c5=_0x25ec0c;if(_0x272d28['length']<_0x26ea80+0x1)return 2.5;const _0x39e351=[];for(let _0x316356=_0x272d28['length']-_0x26ea80;_0x316356<_0x272d28['length'];_0x316356++){const _0x362b73=_0x272d28[_0x316356],_0x35bca5=_0x272d28[_0x316356-0x1]['close'],_0xc5c1d7=Math[_0x4764c5(0x138)](_0x362b73[_0x4764c5(0x162)]-_0x362b73[_0x4764c5(0x12b)],Math[_0x4764c5(0x161)](_0x362b73['high']-_0x35bca5),Math[_0x4764c5(0x161)](_0x362b73[_0x4764c5(0x12b)]-_0x35bca5));_0x39e351['push'](_0xc5c1d7);}return _0x39e351['reduce']((_0x547998,_0x26b7ed)=>_0x547998+_0x26b7ed,0x0)/_0x39e351[_0x4764c5(0x12f)];}['_computeOrderFlowImbalance'](_0x1cfd11){const _0x295658=_0x25ec0c;if(_0x1cfd11['length']<this[_0x295658(0x11c)])return 0x0;const _0x11857e=_0x1cfd11[_0x295658(0x128)](-this['ofiLookback']);let _0x428bb7=0x0,_0x288b9f=0x0;for(const _0x52f5ff of _0x11857e){const _0x3b8d71=_0x52f5ff[_0x295658(0x162)]-_0x52f5ff['low'];if(_0x3b8d71>0x0){const _0x37146f=(_0x52f5ff['close']-_0x52f5ff[_0x295658(0x12b)])/_0x3b8d71;_0x428bb7+=_0x37146f*_0x52f5ff[_0x295658(0x170)],_0x288b9f+=(0x1-_0x37146f)*_0x52f5ff[_0x295658(0x170)];}}const _0x577fff=_0x428bb7+_0x288b9f;if(_0x577fff<0x1)return 0x0;return(_0x428bb7-_0x288b9f)/_0x577fff;}[_0x25ec0c(0x13a)](_0x2a541f,_0x37bac3,_0x5362f8,_0x2fe4b8,_0x9084c0,_0x4a7a22,_0x5afb6d,_0x5c393b,_0x3ff8a2,_0x1987c4){const _0x210f1b=_0x25ec0c,_0xc36d49=Math[_0x210f1b(0x161)](_0x5362f8);if(_0xc36d49<_0x5c393b[_0x210f1b(0x15c)])return null;if(_0x2fe4b8>this[_0x210f1b(0x165)])return null;let _0x2cbd66;if(_0x5362f8<-_0x5c393b['zscoreThreshold'])_0x2cbd66=_0x210f1b(0x17c);else{if(_0x5362f8>_0x5c393b[_0x210f1b(0x15c)])_0x2cbd66=_0x210f1b(0x150);else return null;}const _0x2842c2=_0x2cbd66===_0x210f1b(0x17c)&&_0x3ff8a2>0.1||_0x2cbd66==='short'&&_0x3ff8a2<-0.1,_0x156f33=_0x37bac3-_0x4a7a22,_0x27a9ff=_0x2cbd66===_0x210f1b(0x17c)&&_0x156f33<0x0||_0x2cbd66===_0x210f1b(0x150)&&_0x156f33>0x0,_0xa70813={'zscore':Math[_0x210f1b(0x11e)](0x1,_0xc36d49/0x4),'vpin':0x1-_0x2fe4b8,'kyleLambda':_0x9084c0>0.001?0.5:0.8,'kalman':_0x27a9ff?0.8:0.4,'volatility':_0x5afb6d==='normal'?0.8:_0x5afb6d==='low'?0.7:0.6,'ofi':_0x2842c2?0.9:0.5,'composite':0x0};_0xa70813['composite']=_0xa70813['zscore']*this[_0x210f1b(0x167)]['zscore']+_0xa70813[_0x210f1b(0x11a)]*this['weights'][_0x210f1b(0x11a)]+_0xa70813[_0x210f1b(0x147)]*this[_0x210f1b(0x167)][_0x210f1b(0x147)]+_0xa70813['kalman']*this['weights'][_0x210f1b(0x14d)]+_0xa70813['volatility']*this[_0x210f1b(0x167)]['volatility']+_0xa70813['ofi']*this[_0x210f1b(0x167)]['ofi'];const _0xa1ae70=Math[_0x210f1b(0x11e)](0x1,_0xa70813['composite']+_0x5c393b[_0x210f1b(0x160)]);if(_0xa1ae70<this['minConfidence'])return null;if(Date['now']()-this[_0x210f1b(0x157)]<this['cooldownMs'])return null;const _0x1448bb=Math['round'](this[_0x210f1b(0x129)]*_0x5c393b['stopMultiplier']),_0x26ea75=Math[_0x210f1b(0x178)](this[_0x210f1b(0x12a)]*_0x5c393b['targetMultiplier']),_0x2c6a68=Math[_0x210f1b(0x138)](0x6,Math[_0x210f1b(0x11e)](0xc,_0x1448bb)),_0x2c9a8b=Math[_0x210f1b(0x138)](_0x2c6a68*1.5,Math[_0x210f1b(0x11e)](0x18,_0x26ea75));let _0x2e0b76,_0x32eca3,_0xb55e8f,_0x5b9b34;_0x2cbd66===_0x210f1b(0x17c)?(_0x2e0b76=_0x37bac3-_0x2c6a68*this[_0x210f1b(0x155)],_0x32eca3=_0x37bac3+_0x2c9a8b*this['tickSize'],_0xb55e8f=_0x37bac3+this[_0x210f1b(0x149)]*this['tickSize'],_0x5b9b34=_0x37bac3+_0x2c9a8b*this['profitLockPct']*this['tickSize']):(_0x2e0b76=_0x37bac3+_0x2c6a68*this[_0x210f1b(0x155)],_0x32eca3=_0x37bac3-_0x2c9a8b*this[_0x210f1b(0x155)],_0xb55e8f=_0x37bac3-this[_0x210f1b(0x149)]*this[_0x210f1b(0x155)],_0x5b9b34=_0x37bac3-_0x2c9a8b*this[_0x210f1b(0x11b)]*this['tickSize']);const _0x44e223=_0x2c9a8b/_0x2c6a68,_0x43d1c8=Math[_0x210f1b(0x178)](_0x2c9a8b*0.5),_0x2167b0=Math[_0x210f1b(0x178)](_0x2c6a68*0.4);let _0xbf3c45=SignalStrength['MODERATE'];if(_0xa1ae70>=0.85)_0xbf3c45=SignalStrength['VERY_STRONG'];else{if(_0xa1ae70>=0.75)_0xbf3c45=SignalStrength[_0x210f1b(0x16d)];else{if(_0xa1ae70<0.6)_0xbf3c45=SignalStrength[_0x210f1b(0x130)];}}const _0x104791=0.5+(_0xa1ae70-0.5)*0.4,_0x45900b=_0x104791*Math[_0x210f1b(0x161)](_0x32eca3-_0x37bac3)-(0x1-_0x104791)*Math['abs'](_0x37bac3-_0x2e0b76);this['lastSignalTime']=Date['now'](),this[_0x210f1b(0x156)][_0x210f1b(0x121)]++;const _0x1899ad={'id':uuidv4(),'timestamp':Date['now'](),'symbol':_0x2a541f['split']('.')[0x0]||_0x2a541f,'contractId':_0x2a541f,'side':_0x2cbd66==='long'?OrderSide['BID']:OrderSide[_0x210f1b(0x166)],'direction':_0x2cbd66,'strategy':'HQX_ULTRA_SCALPING_6MODELS','strength':_0xbf3c45,'edge':_0x45900b,'confidence':_0xa1ae70,'entry':_0x37bac3,'entryPrice':_0x37bac3,'stopLoss':_0x2e0b76,'takeProfit':_0x32eca3,'riskReward':_0x44e223,'stopTicks':_0x2c6a68,'targetTicks':_0x2c9a8b,'trailTriggerTicks':_0x43d1c8,'trailDistanceTicks':_0x2167b0,'beBreakeven':_0xb55e8f,'profitLockLevel':_0x5b9b34,'zScore':_0x5362f8,'zScoreExit':this[_0x210f1b(0x14c)],'vpinValue':_0x2fe4b8,'kyleLambda':_0x9084c0,'kalmanEstimate':_0x4a7a22,'volatilityRegime':_0x5afb6d,'ofiValue':_0x3ff8a2,'models':_0xa70813,'orderFlowConfirmed':_0x2842c2,'kalmanConfirmed':_0x27a9ff,'expires':Date['now']()+0xea60};return this[_0x210f1b(0x152)]('signal',{'side':_0x2cbd66==='long'?_0x210f1b(0x148):'sell','action':_0x210f1b(0x151),'reason':'Z='+_0x5362f8['toFixed'](0x2)+',\x20VPIN='+(_0x2fe4b8*0x64)['toFixed'](0x0)+_0x210f1b(0x15d)+(_0x3ff8a2*0x64)[_0x210f1b(0x159)](0x0)+'%,\x20cf='+(_0xa1ae70*0x64)[_0x210f1b(0x159)](0x0)+'%',..._0x1899ad}),this[_0x210f1b(0x152)](_0x210f1b(0x12d),{'type':_0x210f1b(0x120),'message':'[HQX]\x20SIGNAL:\x20'+_0x2cbd66[_0x210f1b(0x13e)]()+_0x210f1b(0x153)+_0x37bac3['toFixed'](0x2)+'\x20|\x20Z:'+_0x5362f8['toFixed'](0x2)+'\x20VPIN:'+(_0x2fe4b8*0x64)['toFixed'](0x0)+'%\x20OFI:'+(_0x3ff8a2*0x64)['toFixed'](0x0)+'%\x20Kyle:'+_0x9084c0[_0x210f1b(0x159)](0x5)+_0x210f1b(0x16e)+_0x5afb6d+_0x210f1b(0x17b)+(_0xa1ae70*0x64)[_0x210f1b(0x159)](0x0)+'%'}),_0x1899ad;}['shouldExitByZScore'](_0x3cf5a0){const _0xaedc1f=_0x25ec0c,_0x6c2423=this[_0xaedc1f(0x119)][_0xaedc1f(0x14f)](_0x3cf5a0);if(!_0x6c2423||_0x6c2423['length']<0x32)return![];const _0x597b95=this[_0xaedc1f(0x139)](_0x6c2423);return Math[_0xaedc1f(0x161)](_0x597b95)<this[_0xaedc1f(0x14c)];}['getModelValues'](_0x34f955){const _0x1ac26c=_0x25ec0c,_0x4dbaa7=this[_0x1ac26c(0x119)]['get'](_0x34f955),_0x537d16=this[_0x1ac26c(0x15e)][_0x1ac26c(0x14f)](_0x34f955),_0x5dae22=this['barHistory'][_0x1ac26c(0x14f)](_0x34f955);if(!_0x4dbaa7||!_0x537d16||!_0x5dae22||_0x5dae22['length']<0x32)return null;const _0x5ad365=this['_computeZScore'](_0x4dbaa7),_0x480bb1=this['_computeVPIN'](_0x537d16),_0x398339=this[_0x1ac26c(0x11d)](_0x5dae22),_0x2a82cb=this['_computeOrderFlowImbalance'](_0x5dae22);return{'zscore':Math['min'](0x1,Math[_0x1ac26c(0x161)](_0x5ad365)/0x4),'vpin':0x1-_0x480bb1,'kyleLambda':_0x398339>0.001?0.5:0.8,'kalman':0.7,'volatility':0.7,'ofi':Math['abs'](_0x2a82cb)>0.1?0.8:0.5,'composite':0.7,'raw':{'zscore':_0x5ad365,'vpin':_0x480bb1,'kyleLambda':_0x398339,'ofi':_0x2a82cb}};}[_0x25ec0c(0x127)](_0x868cfa,_0x45ed5c){const _0x3ed786=_0x25ec0c,_0x1135d8=this['barHistory'][_0x3ed786(0x14f)](_0x868cfa)||[];if(_0x1135d8['length']<0x32)return{'ready':![],'message':'Collecting\x20data...\x20'+_0x1135d8['length']+_0x3ed786(0x142)};const _0x230ec9=this[_0x3ed786(0x119)]['get'](_0x868cfa)||[],_0x1d04ac=this[_0x3ed786(0x15e)]['get'](_0x868cfa)||[],_0x5d2f6c=this['_computeZScore'](_0x230ec9),_0x3d21c7=this[_0x3ed786(0x179)](_0x1d04ac),_0x552760=this[_0x3ed786(0x154)](_0x1135d8),_0xa93f48=this[_0x3ed786(0x11d)](_0x1135d8),{regime:_0x235004,params:_0x2dfb29}=this['_detectVolatilityRegime'](_0x868cfa,_0x1135d8);return{'ready':!![],'zScore':_0x5d2f6c,'vpin':_0x3d21c7,'ofi':_0x552760,'kyleLambda':_0xa93f48,'regime':_0x235004,'stopTicks':Math['round'](this[_0x3ed786(0x129)]*_0x2dfb29[_0x3ed786(0x177)]),'targetTicks':Math['round'](this['baseTargetTicks']*_0x2dfb29['targetMultiplier']),'threshold':_0x2dfb29['zscoreThreshold'],'barsProcessed':_0x1135d8[_0x3ed786(0x12f)],'models':_0x3ed786(0x174)};}['recordTradeResult'](_0x57c6fc){const _0x443d8e=_0x25ec0c;this[_0x443d8e(0x16a)][_0x443d8e(0x125)]({'netPnl':_0x57c6fc,'timestamp':Date['now']()});if(this[_0x443d8e(0x16a)]['length']>0x64)this['recentTrades'][_0x443d8e(0x12e)]();_0x57c6fc>0x0?(this[_0x443d8e(0x15a)]++,this[_0x443d8e(0x12c)]=0x0,this['stats']['wins']++):(this[_0x443d8e(0x12c)]++,this[_0x443d8e(0x15a)]=0x0,this[_0x443d8e(0x156)]['losses']++),this['stats'][_0x443d8e(0x134)]++,this['stats']['pnl']+=_0x57c6fc,this[_0x443d8e(0x152)]('log',{'type':'debug','message':_0x443d8e(0x14b)+(_0x57c6fc>0x0?'WIN':_0x443d8e(0x169))+'\x20$'+_0x57c6fc[_0x443d8e(0x159)](0x2)+',\x20streak:\x20'+(_0x57c6fc>0x0?this[_0x443d8e(0x15a)]:-this['lossStreak'])});}['getBarHistory'](_0x478bf3){const _0x5b5bf9=_0x25ec0c;return this[_0x5b5bf9(0x137)]['get'](_0x478bf3)||[];}[_0x25ec0c(0x158)](){return this['stats'];}['reset'](_0x15949e){const _0xd4e09f=_0x25ec0c;this['barHistory']['set'](_0x15949e,[]),this['priceBuffer']['set'](_0x15949e,[]),this[_0xd4e09f(0x15e)]['set'](_0x15949e,[]),this[_0xd4e09f(0x146)][_0xd4e09f(0x122)](_0x15949e,[]),this['kalmanStates']['set'](_0x15949e,{'estimate':0x0,'errorCovariance':0x1}),this[_0xd4e09f(0x152)]('log',{'type':_0xd4e09f(0x120),'message':'[HQX-UltraScalping]\x20Reset\x20state\x20for\x20'+_0x15949e});}}class UltraScalpingStrategy extends EventEmitter{constructor(_0x63f1c8={}){const _0x1a9473=_0x25ec0c;super(),this['config']=_0x63f1c8,this[_0x1a9473(0x143)]=new HQXUltraScalping(_0x63f1c8),this[_0x1a9473(0x143)]['on'](_0x1a9473(0x15b),_0x177427=>this[_0x1a9473(0x152)](_0x1a9473(0x15b),_0x177427)),this['strategy']['on'](_0x1a9473(0x12d),_0x3ae7e8=>this[_0x1a9473(0x152)]('log',_0x3ae7e8));}['processTick'](_0x15795e){const _0x230916=_0x25ec0c;return this[_0x230916(0x143)]['processTick'](_0x15795e);}['onTick'](_0x139ec2){const _0x32a3c2=_0x25ec0c;return this['strategy'][_0x32a3c2(0x172)](_0x139ec2);}['onTrade'](_0x260570){const _0x4a9f34=_0x25ec0c;return this[_0x4a9f34(0x143)][_0x4a9f34(0x13c)](_0x260570);}['processBar'](_0x517c9b,_0x4e2b5a){const _0x269f3d=_0x25ec0c;return this['strategy'][_0x269f3d(0x173)](_0x517c9b,_0x4e2b5a);}['initialize'](_0x5a3e4b,_0x4b240b,_0x43a10b){const _0x37d3d8=_0x25ec0c;return this[_0x37d3d8(0x143)]['initialize'](_0x5a3e4b,_0x4b240b,_0x43a10b);}['getAnalysisState'](_0x39e7f9,_0x4a7311){const _0x44c7c9=_0x25ec0c;return this[_0x44c7c9(0x143)]['getAnalysisState'](_0x39e7f9,_0x4a7311);}['recordTradeResult'](_0x3a8e0f){const _0x31841a=_0x25ec0c;return this[_0x31841a(0x143)][_0x31841a(0x124)](_0x3a8e0f);}[_0x25ec0c(0x17d)](_0x22890e){const _0x2bc4c5=_0x25ec0c;return this[_0x2bc4c5(0x143)][_0x2bc4c5(0x17d)](_0x22890e);}['getStats'](){return this['strategy']['getStats']();}[_0x25ec0c(0x144)](_0x2b734b){const _0x4039f4=_0x25ec0c;return this['strategy'][_0x4039f4(0x144)](_0x2b734b);}['getModelValues'](_0x4c7224){return this['strategy']['getModelValues'](_0x4c7224);}[_0x25ec0c(0x123)](_0x285148){const _0x2e749c=_0x25ec0c;return this[_0x2e749c(0x143)]['shouldExitByZScore'](_0x285148);}[_0x25ec0c(0x14a)](_0x5b2bb5){return null;}}module['exports']={'HQXUltraScalping':HQXUltraScalping,'UltraScalpingStrategy':UltraScalpingStrategy,'M1':UltraScalpingStrategy,'S1':HQXUltraScalping,'OrderSide':OrderSide,'SignalStrength':SignalStrength};