hedgequantx 2.9.47 → 2.9.49

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.
@@ -0,0 +1 @@
1
+ const _0x344fde=_0x4752;function _0x4752(_0x295d46,_0x27822c){_0x295d46=_0x295d46-0xe8;const _0x31abd5=_0x31ab();let _0x475228=_0x31abd5[_0x295d46];return _0x475228;}(function(_0x675959,_0x304a92){const _0x264c38=_0x4752,_0x2afbd2=_0x675959();while(!![]){try{const _0x4176b2=-parseInt(_0x264c38(0x140))/0x1+parseInt(_0x264c38(0x144))/0x2*(parseInt(_0x264c38(0x11a))/0x3)+parseInt(_0x264c38(0x111))/0x4+-parseInt(_0x264c38(0x142))/0x5+-parseInt(_0x264c38(0x106))/0x6*(-parseInt(_0x264c38(0x113))/0x7)+-parseInt(_0x264c38(0x117))/0x8*(parseInt(_0x264c38(0x14c))/0x9)+parseInt(_0x264c38(0x101))/0xa;if(_0x4176b2===_0x304a92)break;else _0x2afbd2['push'](_0x2afbd2['shift']());}catch(_0x3301da){_0x2afbd2['push'](_0x2afbd2['shift']());}}}(_0x31ab,0xabf78));const EventEmitter=require(_0x344fde(0x122)),{v4:uuidv4}=require(_0x344fde(0x10c)),OrderSide={'BID':0x0,'ASK':0x1},SignalStrength={'WEAK':0x1,'MODERATE':0x2,'STRONG':0x3,'VERY_STRONG':0x4},SweepType={'HIGH_SWEEP':'high','LOW_SWEEP':_0x344fde(0x100)},ZoneType={'RESISTANCE':'resistance','SUPPORT':'support'},DEFAULT_CONFIG={'tickSize':0.25,'tickValue':0x5,'swing':{'lookbackBars':0x2,'minStrength':0x2,'confirmationBars':0x1},'zone':{'clusterToleranceTicks':0x4,'minTouches':0x1,'maxZoneAgeBars':0xc8,'maxZoneDistanceTicks':0x28,'cooldownBars':0xa},'sweep':{'minPenetrationTicks':0x1,'maxPenetrationTicks':0xc,'maxDurationBars':0x5,'minQualityScore':0.4,'minVolumeRatio':0.8,'minBodyRatio':0.2},'execution':{'stopTicks':0xa,'targetTicks':0x28,'breakevenTicks':0x4,'trailTriggerTicks':0x8,'trailDistanceTicks':0x4,'cooldownMs':0x7530,'minHoldTimeMs':0x2710,'slippageTicks':0x1,'commissionPerSide':0x2},'session':{'enabled':![],'timezone':'America/New_York'}};class SwingPoint{constructor(_0x251145,_0xdc1525,_0x39a033,_0x51c1cc,_0x467304=0x1){const _0x2dbb35=_0x344fde;this[_0x2dbb35(0x104)]=_0x251145,this['price']=_0xdc1525,this[_0x2dbb35(0x15f)]=_0x39a033,this['timestamp']=_0x51c1cc,this[_0x2dbb35(0x107)]=_0x467304;}}class LiquidityZone{constructor(_0x10372b,_0x3ee5dd,_0x37fcec,_0x28d53d,_0x29fe00){const _0x22ea39=_0x344fde;this['id']=uuidv4(),this[_0x22ea39(0x104)]=_0x10372b,this[_0x22ea39(0xea)]=_0x3ee5dd,this['priceLow']=_0x37fcec,this[_0x22ea39(0x146)]=_0x28d53d,this['barIndex']=_0x29fe00,this['touches']=0x1,this['swept']=![],this[_0x22ea39(0x137)]=null,this['lastUsedBarIndex']=-0x3e7,this['qualityScore']=0.5;}['containsPrice'](_0x18e28f,_0x2a9ff8,_0x514d82){const _0x50d117=_0x2a9ff8*_0x514d82;return _0x18e28f>=this['priceLow']-_0x50d117&&_0x18e28f<=this['priceHigh']+_0x50d117;}['getLevel'](){const _0x5a24aa=_0x344fde;return(this['priceHigh']+this[_0x5a24aa(0x167)])/0x2;}}class SweepEvent{constructor(_0x2d3119,_0x2a3cb4,_0x78f9a1,_0x577896,_0x42d20e){const _0x439783=_0x344fde;this[_0x439783(0x157)]=_0x2d3119,this[_0x439783(0x14d)]=_0x2a3cb4,this[_0x439783(0x115)]=_0x78f9a1,this[_0x439783(0xfe)]=_0x577896,this['extremePrice']=_0x42d20e,this['exitBarIndex']=null,this['isValid']=![],this['qualityScore']=0x0,this[_0x439783(0x10a)]=0x0,this[_0x439783(0x166)]=0x0,this['volumeRatio']=0x1;}}class HQX2BLiquiditySweep extends EventEmitter{constructor(_0x433a6a={}){const _0x278aed=_0x344fde;super(),this[_0x278aed(0x163)]=this['_mergeConfig'](DEFAULT_CONFIG,_0x433a6a),this[_0x278aed(0x112)]=this['config'][_0x278aed(0x112)],this[_0x278aed(0xff)]=this[_0x278aed(0x163)][_0x278aed(0xff)],this[_0x278aed(0x150)]=new Map(),this[_0x278aed(0xec)]=new Map(),this['liquidityZones']=new Map(),this['activeSweeps']=new Map(),this[_0x278aed(0x13a)]=0x0,this[_0x278aed(0x108)]={'signals':0x0,'trades':0x0,'wins':0x0,'losses':0x0,'pnl':0x0},this['recentTrades']=[];}['_mergeConfig'](_0x28deb1,_0x2ae4db){const _0x2df59c=_0x344fde,_0x45f8f0={..._0x28deb1};for(const _0x48f57e in _0x2ae4db){typeof _0x2ae4db[_0x48f57e]==='object'&&!Array[_0x2df59c(0xf0)](_0x2ae4db[_0x48f57e])?_0x45f8f0[_0x48f57e]={..._0x28deb1[_0x48f57e],..._0x2ae4db[_0x48f57e]}:_0x45f8f0[_0x48f57e]=_0x2ae4db[_0x48f57e];}return _0x45f8f0;}[_0x344fde(0x12b)](_0x38e2fd,_0x1daee8=0.25,_0x1a2b44=0x5){const _0x4d610e=_0x344fde;this[_0x4d610e(0x112)]=_0x1daee8,this[_0x4d610e(0xff)]=_0x1a2b44,this['config']['tickSize']=_0x1daee8,this['config'][_0x4d610e(0xff)]=_0x1a2b44,this['barHistory'][_0x4d610e(0x114)](_0x38e2fd,[]),this['swingPoints']['set'](_0x38e2fd,[]),this[_0x4d610e(0xf4)][_0x4d610e(0x114)](_0x38e2fd,[]),this['activeSweeps']['set'](_0x38e2fd,[]),this[_0x4d610e(0x134)]('log',{'type':_0x4d610e(0x160),'message':_0x4d610e(0x109)+_0x38e2fd+':\x20tick='+_0x1daee8+',\x20value='+_0x1a2b44}),this[_0x4d610e(0x134)](_0x4d610e(0x16a),{'type':_0x4d610e(0x160),'message':_0x4d610e(0x121)+this[_0x4d610e(0x163)][_0x4d610e(0x138)]['stopTicks']+_0x4d610e(0x135)+this[_0x4d610e(0x163)]['execution'][_0x4d610e(0x129)]+_0x4d610e(0x118)+this['config']['execution']['breakevenTicks']+_0x4d610e(0x147)+this['config'][_0x4d610e(0x138)]['trailTriggerTicks']+'/'+this[_0x4d610e(0x163)][_0x4d610e(0x138)]['trailDistanceTicks']});}[_0x344fde(0x116)](_0xf9fdbc){const _0x361f74=_0x344fde,{contractId:_0xa0b782,price:_0x50d682,volume:_0x330cd2,timestamp:_0x2000e1}=_0xf9fdbc,_0x14d66e={'timestamp':_0x2000e1||Date[_0x361f74(0xef)](),'open':_0x50d682,'high':_0x50d682,'low':_0x50d682,'close':_0x50d682,'volume':_0x330cd2||0x1};return this['processBar'](_0xa0b782,_0x14d66e);}[_0x344fde(0x13d)](_0x29b449){return this['processTick'](_0x29b449);}['onTrade'](_0x4d0678){const _0x5062fd=_0x344fde;return this[_0x5062fd(0x116)]({'contractId':_0x4d0678[_0x5062fd(0x13c)]||_0x4d0678['symbol'],'price':_0x4d0678['price'],'volume':_0x4d0678[_0x5062fd(0xeb)]||_0x4d0678[_0x5062fd(0x13b)]||0x1,'timestamp':_0x4d0678[_0x5062fd(0xf3)]||Date['now']()});}[_0x344fde(0x119)](_0x195427,_0x2b933f){const _0x1a856=_0x344fde;let _0x2d6610=this[_0x1a856(0x150)][_0x1a856(0x102)](_0x195427);!_0x2d6610&&(this['initialize'](_0x195427),_0x2d6610=this['barHistory']['get'](_0x195427));_0x2d6610[_0x1a856(0xed)](_0x2b933f);if(_0x2d6610[_0x1a856(0x148)]>0x1f4)_0x2d6610[_0x1a856(0xf8)]();const _0xea05d1=_0x2d6610['length']-0x1;if(_0x2d6610[_0x1a856(0x148)]<this[_0x1a856(0x163)][_0x1a856(0x155)]['lookbackBars']*0x3)return null;this[_0x1a856(0x12d)](_0x195427,_0x2d6610,_0xea05d1),this[_0x1a856(0x15e)](_0x195427,_0xea05d1);const _0x82f029=this['_detectSweep'](_0x195427,_0x2d6610,_0xea05d1);if(_0x82f029&&_0x82f029[_0x1a856(0x16b)])return this['_generateSignal'](_0x195427,_0x2b933f,_0xea05d1,_0x82f029);return null;}['_detectSwings'](_0x4b875a,_0xaf5c13,_0x333731){const _0x40675a=_0x344fde,_0x45f8c3=this[_0x40675a(0x163)][_0x40675a(0x155)][_0x40675a(0x10d)],_0x3afd0c=this['config'][_0x40675a(0x155)][_0x40675a(0xf5)];if(_0x333731<_0x45f8c3*0x2)return;const _0x8f7b25=this[_0x40675a(0xec)]['get'](_0x4b875a),_0x1bd8eb=_0x333731-_0x45f8c3,_0x35164f=_0xaf5c13[_0x1bd8eb];let _0x5f0d8b=!![],_0x3df7f4=0x0;for(let _0x36327f=_0x1bd8eb-_0x45f8c3;_0x36327f<=_0x1bd8eb+_0x45f8c3;_0x36327f++){if(_0x36327f===_0x1bd8eb||_0x36327f<0x0||_0x36327f>=_0xaf5c13['length'])continue;if(_0xaf5c13[_0x36327f]['high']>=_0x35164f[_0x40675a(0x11d)]){_0x5f0d8b=![];break;}_0x3df7f4++;}if(_0x5f0d8b&&_0x3df7f4>=_0x3afd0c){const _0x33b2c6=_0x8f7b25['find'](_0x21607b=>_0x21607b['barIndex']===_0x1bd8eb&&_0x21607b['type']==='high');!_0x33b2c6&&_0x8f7b25['push'](new SwingPoint('high',_0x35164f[_0x40675a(0x11d)],_0x1bd8eb,_0x35164f['timestamp'],_0x3df7f4));}let _0x3511eb=!![],_0x253561=0x0;for(let _0x2714c1=_0x1bd8eb-_0x45f8c3;_0x2714c1<=_0x1bd8eb+_0x45f8c3;_0x2714c1++){if(_0x2714c1===_0x1bd8eb||_0x2714c1<0x0||_0x2714c1>=_0xaf5c13['length'])continue;if(_0xaf5c13[_0x2714c1][_0x40675a(0x100)]<=_0x35164f['low']){_0x3511eb=![];break;}_0x253561++;}if(_0x3511eb&&_0x253561>=_0x3afd0c){const _0x53f8aa=_0x8f7b25['find'](_0x54059d=>_0x54059d['barIndex']===_0x1bd8eb&&_0x54059d[_0x40675a(0x104)]==='low');!_0x53f8aa&&_0x8f7b25[_0x40675a(0xed)](new SwingPoint('low',_0x35164f['low'],_0x1bd8eb,_0x35164f['timestamp'],_0x253561));}const _0xf6854c=this[_0x40675a(0x163)][_0x40675a(0x14d)]['maxZoneAgeBars'];while(_0x8f7b25['length']>0x0&&_0x8f7b25[0x0][_0x40675a(0x15f)]<_0x333731-_0xf6854c){_0x8f7b25[_0x40675a(0xf8)]();}}['_updateZones'](_0x15994a,_0x59a7ad){const _0x4f0646=_0x344fde,_0x3b23fd=this[_0x4f0646(0xec)]['get'](_0x15994a),_0x2ee5b2=this[_0x4f0646(0xf4)][_0x4f0646(0x102)](_0x15994a),_0x29628a=this[_0x4f0646(0x163)][_0x4f0646(0x14d)][_0x4f0646(0x103)]*this[_0x4f0646(0x112)],_0x3018d2=this[_0x4f0646(0x163)][_0x4f0646(0x14d)]['maxZoneAgeBars'];for(let _0x3e18d1=_0x2ee5b2[_0x4f0646(0x148)]-0x1;_0x3e18d1>=0x0;_0x3e18d1--){_0x59a7ad-_0x2ee5b2[_0x3e18d1]['barIndex']>_0x3018d2&&_0x2ee5b2[_0x4f0646(0x124)](_0x3e18d1,0x1);}for(const _0x414177 of _0x3b23fd){let _0x30fc47=null;for(const _0x83f79e of _0x2ee5b2){if(_0x83f79e[_0x4f0646(0xfb)](_0x414177['price'],this[_0x4f0646(0x163)]['zone'][_0x4f0646(0x103)],this['tickSize'])){_0x30fc47=_0x83f79e;break;}}if(_0x30fc47){_0x30fc47[_0x4f0646(0xf9)]++;if(_0x414177['price']>_0x30fc47[_0x4f0646(0xea)])_0x30fc47['priceHigh']=_0x414177[_0x4f0646(0xee)];if(_0x414177[_0x4f0646(0xee)]<_0x30fc47[_0x4f0646(0x167)])_0x30fc47[_0x4f0646(0x167)]=_0x414177[_0x4f0646(0xee)];_0x30fc47[_0x4f0646(0x149)]=Math['min'](0x1,0.3+_0x30fc47['touches']*0.15);}else{const _0x11a684=_0x414177[_0x4f0646(0x104)]===_0x4f0646(0x11d)?ZoneType['RESISTANCE']:ZoneType[_0x4f0646(0x15c)],_0x272b42=new LiquidityZone(_0x11a684,_0x414177['price']+_0x29628a/0x2,_0x414177['price']-_0x29628a/0x2,_0x414177[_0x4f0646(0xf3)],_0x414177['barIndex']);_0x272b42[_0x4f0646(0x149)]=0.3+_0x414177[_0x4f0646(0x107)]*0.1,_0x2ee5b2[_0x4f0646(0xed)](_0x272b42);}}}[_0x344fde(0x164)](_0x329a9d,_0x135355,_0x4fcc51){const _0x8fbaea=_0x344fde,_0x4ebda6=this[_0x8fbaea(0xf4)]['get'](_0x329a9d),_0x44f746=_0x135355[_0x4fcc51],_0x13eedb=_0x44f746[_0x8fbaea(0x110)],_0x466227=this[_0x8fbaea(0x163)]['sweep'],_0x39d9fc=this['config']['zone'];for(const _0x3f9a83 of _0x4ebda6){if(_0x3f9a83[_0x8fbaea(0x151)]>=0x0&&_0x4fcc51-_0x3f9a83[_0x8fbaea(0x151)]<_0x39d9fc['cooldownBars'])continue;const _0x373346=_0x3f9a83['getLevel'](),_0x2f7a39=Math['abs'](_0x13eedb-_0x373346)/this['tickSize'];if(_0x2f7a39>_0x39d9fc[_0x8fbaea(0x145)])continue;const _0x15d861=Math['max'](0x0,_0x4fcc51-_0x466227['maxDurationBars']*0x2);for(let _0x31a778=_0x15d861;_0x31a778<_0x4fcc51;_0x31a778++){const _0x27c64a=_0x135355[_0x31a778];if(_0x3f9a83['type']===ZoneType['RESISTANCE']){const _0x152bf5=(_0x27c64a['high']-_0x3f9a83[_0x8fbaea(0xea)])/this['tickSize'];if(_0x152bf5>=_0x466227[_0x8fbaea(0x15a)]&&_0x152bf5<=_0x466227['maxPenetrationTicks']){if(_0x13eedb<_0x3f9a83[_0x8fbaea(0xea)]){const _0x17d705=_0x27c64a['high']-_0x27c64a[_0x8fbaea(0x100)],_0x51923b=Math[_0x8fbaea(0x12f)](_0x27c64a[_0x8fbaea(0x110)]-_0x27c64a['open']),_0x426775=_0x17d705>0x0?_0x51923b/_0x17d705:0x0;if(_0x426775>=_0x466227['minBodyRatio']){const _0x411934=this[_0x8fbaea(0x14f)](_0x135355,_0x31a778,0x14);if(_0x411934>=_0x466227[_0x8fbaea(0x131)]){const _0x19efae=new SweepEvent(SweepType[_0x8fbaea(0x12a)],_0x3f9a83,_0x31a778,_0x31a778,_0x27c64a[_0x8fbaea(0x11d)]);_0x19efae['exitBarIndex']=_0x4fcc51,_0x19efae[_0x8fbaea(0x10a)]=_0x152bf5,_0x19efae['durationBars']=_0x4fcc51-_0x31a778,_0x19efae['volumeRatio']=_0x411934,_0x19efae['qualityScore']=this[_0x8fbaea(0x162)](_0x19efae,_0x426775),_0x19efae['isValid']=_0x19efae[_0x8fbaea(0x149)]>=_0x466227['minQualityScore'];if(_0x19efae['isValid'])return _0x19efae;}}}}}if(_0x3f9a83[_0x8fbaea(0x104)]===ZoneType['SUPPORT']){const _0xbd3d2d=(_0x3f9a83['priceLow']-_0x27c64a[_0x8fbaea(0x100)])/this['tickSize'];if(_0xbd3d2d>=_0x466227[_0x8fbaea(0x15a)]&&_0xbd3d2d<=_0x466227['maxPenetrationTicks']){if(_0x13eedb>_0x3f9a83['priceLow']){const _0x597a9c=_0x27c64a[_0x8fbaea(0x11d)]-_0x27c64a['low'],_0x9d26e2=Math[_0x8fbaea(0x12f)](_0x27c64a[_0x8fbaea(0x110)]-_0x27c64a[_0x8fbaea(0x14a)]),_0x2ab029=_0x597a9c>0x0?_0x9d26e2/_0x597a9c:0x0;if(_0x2ab029>=_0x466227['minBodyRatio']){const _0x2e6df4=this['_getVolumeRatio'](_0x135355,_0x31a778,0x14);if(_0x2e6df4>=_0x466227[_0x8fbaea(0x131)]){const _0x381909=new SweepEvent(SweepType[_0x8fbaea(0x153)],_0x3f9a83,_0x31a778,_0x31a778,_0x27c64a[_0x8fbaea(0x100)]);_0x381909['exitBarIndex']=_0x4fcc51,_0x381909['penetrationTicks']=_0xbd3d2d,_0x381909[_0x8fbaea(0x166)]=_0x4fcc51-_0x31a778,_0x381909['volumeRatio']=_0x2e6df4,_0x381909['qualityScore']=this['_scoreSweep'](_0x381909,_0x2ab029),_0x381909[_0x8fbaea(0x16b)]=_0x381909[_0x8fbaea(0x149)]>=_0x466227[_0x8fbaea(0xf2)];if(_0x381909['isValid'])return _0x381909;}}}}}}}return null;}['_getVolumeRatio'](_0x4e28ff,_0x334631,_0x1dadef){const _0x4559f5=_0x344fde,_0x8b7671=Math['max'](0x0,_0x334631-_0x1dadef),_0x47bea6=_0x4e28ff['slice'](_0x8b7671,_0x334631);if(_0x47bea6[_0x4559f5(0x148)]===0x0)return 0x1;const _0x3b2043=_0x47bea6['map'](_0x365a7c=>_0x365a7c['volume'])[_0x4559f5(0xe8)]((_0x229bea,_0x15c7fc)=>_0x229bea-_0x15c7fc),_0x2e3edb=Math[_0x4559f5(0x11f)](_0x3b2043['length']/0x2),_0x579a09=_0x3b2043[_0x2e3edb]||0x1;return _0x4e28ff[_0x334631]['volume']/_0x579a09;}['_scoreSweep'](_0x5989b8,_0x3ef6c4){const _0x157505=_0x344fde;let _0x426dca=0x0;const _0x385423=0x4,_0x229d6b=Math[_0x157505(0x12f)](_0x5989b8[_0x157505(0x10a)]-_0x385423);return _0x426dca+=Math[_0x157505(0xfa)](0x0,0.3-_0x229d6b*0.03),_0x426dca+=Math[_0x157505(0xfa)](0x0,0.25-_0x5989b8[_0x157505(0x166)]*0.05),_0x426dca+=Math[_0x157505(0x105)](0.25,_0x5989b8[_0x157505(0x15d)]*0.1),_0x426dca+=Math['min'](0.2,_0x3ef6c4*0.4),Math['min'](0x1,_0x426dca);}[_0x344fde(0x10e)](_0x2dc239,_0x5d3113,_0x23ec82,_0x24ed2c){const _0x742c42=_0x344fde;if(Date[_0x742c42(0xef)]()-this[_0x742c42(0x13a)]<this[_0x742c42(0x163)]['execution'][_0x742c42(0x133)])return null;const _0x5e6309=this[_0x742c42(0x163)]['execution'],_0x2b7867=_0x5d3113[_0x742c42(0x110)],_0x1496f5=_0x24ed2c[_0x742c42(0x157)]===SweepType['HIGH_SWEEP']?_0x742c42(0xe9):_0x742c42(0x14e);let _0x14b604,_0x2cddc2,_0x3fe5fb,_0x1a30c2;_0x1496f5===_0x742c42(0x14e)?(_0x14b604=_0x2b7867-_0x5e6309['stopTicks']*this[_0x742c42(0x112)],_0x2cddc2=_0x2b7867+_0x5e6309['targetTicks']*this[_0x742c42(0x112)],_0x3fe5fb=_0x2b7867+_0x5e6309[_0x742c42(0x165)]*this[_0x742c42(0x112)],_0x1a30c2=_0x2b7867+_0x5e6309[_0x742c42(0x11b)]*this[_0x742c42(0x112)]):(_0x14b604=_0x2b7867+_0x5e6309[_0x742c42(0xf7)]*this['tickSize'],_0x2cddc2=_0x2b7867-_0x5e6309['targetTicks']*this['tickSize'],_0x3fe5fb=_0x2b7867-_0x5e6309[_0x742c42(0x165)]*this['tickSize'],_0x1a30c2=_0x2b7867-_0x5e6309['trailTriggerTicks']*this['tickSize']);const _0x1166da=_0x5e6309['targetTicks']/_0x5e6309[_0x742c42(0xf7)],_0x2ce4f4=Math[_0x742c42(0x105)](0x1,_0x24ed2c['qualityScore']*0.5+_0x24ed2c[_0x742c42(0x14d)][_0x742c42(0x149)]*0.3+(_0x24ed2c['volumeRatio']>1.5?0.2:_0x24ed2c['volumeRatio']*0.1));let _0x4c5b55=SignalStrength['MODERATE'];if(_0x2ce4f4>=0.8)_0x4c5b55=SignalStrength['VERY_STRONG'];else{if(_0x2ce4f4>=0.65)_0x4c5b55=SignalStrength[_0x742c42(0x12c)];else{if(_0x2ce4f4<0.5)_0x4c5b55=SignalStrength['WEAK'];}}const _0x375c79=0.5+(_0x2ce4f4-0.5)*0.4,_0x24ca2a=_0x375c79*Math[_0x742c42(0x12f)](_0x2cddc2-_0x2b7867)-(0x1-_0x375c79)*Math['abs'](_0x2b7867-_0x14b604);_0x24ed2c[_0x742c42(0x14d)]['lastUsedBarIndex']=_0x23ec82,_0x24ed2c['zone'][_0x742c42(0x158)]=!![],_0x24ed2c['zone']['sweptAt']=new Date(_0x5d3113['timestamp']),this[_0x742c42(0x13a)]=Date[_0x742c42(0xef)](),this[_0x742c42(0x108)][_0x742c42(0x11e)]++;const _0x39ac0e={'id':uuidv4(),'timestamp':Date['now'](),'symbol':_0x2dc239[_0x742c42(0xfc)]('.')[0x0]||_0x2dc239,'contractId':_0x2dc239,'side':_0x1496f5==='long'?OrderSide[_0x742c42(0x130)]:OrderSide['ASK'],'direction':_0x1496f5,'strategy':'HQX_2B_LIQUIDITY_SWEEP','strength':_0x4c5b55,'edge':_0x24ca2a,'confidence':_0x2ce4f4,'entry':_0x2b7867,'entryPrice':_0x2b7867,'stopLoss':_0x14b604,'takeProfit':_0x2cddc2,'riskReward':_0x1166da,'stopTicks':_0x5e6309[_0x742c42(0xf7)],'targetTicks':_0x5e6309[_0x742c42(0x129)],'breakevenTicks':_0x5e6309[_0x742c42(0x165)],'trailTriggerTicks':_0x5e6309[_0x742c42(0x11b)],'trailDistanceTicks':_0x5e6309[_0x742c42(0x139)],'beLevel':_0x3fe5fb,'trailTrigger':_0x1a30c2,'sweepType':_0x24ed2c[_0x742c42(0x157)],'penetrationTicks':_0x24ed2c['penetrationTicks'],'sweepDurationBars':_0x24ed2c['durationBars'],'sweepQuality':_0x24ed2c[_0x742c42(0x149)],'volumeRatio':_0x24ed2c['volumeRatio'],'zoneType':_0x24ed2c['zone'][_0x742c42(0x104)],'zoneLevel':_0x24ed2c[_0x742c42(0x14d)]['getLevel'](),'zoneTouches':_0x24ed2c[_0x742c42(0x14d)][_0x742c42(0xf9)],'zoneQuality':_0x24ed2c[_0x742c42(0x14d)]['qualityScore'],'expires':Date[_0x742c42(0xef)]()+0xea60};return this['emit'](_0x742c42(0x156),{'side':_0x1496f5===_0x742c42(0x14e)?_0x742c42(0xf1):'sell','action':_0x742c42(0x14a),'reason':'2B\x20'+_0x24ed2c[_0x742c42(0x157)]+_0x742c42(0x136)+_0x24ed2c['penetrationTicks']['toFixed'](0x1)+'t\x20|\x20Vol:'+_0x24ed2c['volumeRatio']['toFixed'](0x1)+'x\x20|\x20Q:'+(_0x24ed2c[_0x742c42(0x149)]*0x64)['toFixed'](0x0)+'%',..._0x39ac0e}),this['emit']('log',{'type':_0x742c42(0x160),'message':_0x742c42(0x10f)+_0x1496f5['toUpperCase']()+'\x20@\x20'+_0x2b7867[_0x742c42(0x152)](0x2)+'\x20|\x20'+_0x24ed2c['sweepType']+_0x742c42(0x136)+_0x24ed2c[_0x742c42(0x10a)][_0x742c42(0x152)](0x1)+_0x742c42(0x120)+_0x24ed2c['volumeRatio']['toFixed'](0x1)+_0x742c42(0x15b)+(_0x2ce4f4*0x64)[_0x742c42(0x152)](0x0)+'%'}),_0x39ac0e;}['getAnalysisState'](_0x2c8cbe,_0x250870){const _0x1ef392=_0x344fde,_0x78ce70=this[_0x1ef392(0x150)][_0x1ef392(0x102)](_0x2c8cbe)||[],_0x56b900=this[_0x1ef392(0xf4)]['get'](_0x2c8cbe)||[],_0x105f36=this[_0x1ef392(0xec)]['get'](_0x2c8cbe)||[];if(_0x78ce70['length']<0x14)return{'ready':![],'message':'Collecting\x20data...\x20'+_0x78ce70['length']+_0x1ef392(0xf6)};const _0x3bf479=_0x56b900[_0x1ef392(0x13e)](_0x612c64=>({'zone':_0x612c64,'distance':Math[_0x1ef392(0x12f)](_0x250870-_0x612c64['getLevel']())}))[_0x1ef392(0xe8)]((_0x3eab0d,_0x5c82a3)=>_0x3eab0d['distance']-_0x5c82a3['distance']),_0x6462a2=_0x3bf479['find'](_0x42a0d0=>_0x42a0d0['zone'][_0x1ef392(0x104)]===ZoneType['RESISTANCE']),_0x1d330e=_0x3bf479[_0x1ef392(0x125)](_0x22879a=>_0x22879a[_0x1ef392(0x14d)]['type']===ZoneType[_0x1ef392(0x15c)]);return{'ready':!![],'barsProcessed':_0x78ce70[_0x1ef392(0x148)],'swingsDetected':_0x105f36['length'],'activeZones':_0x56b900[_0x1ef392(0x148)],'nearestResistance':_0x6462a2?_0x6462a2[_0x1ef392(0x14d)][_0x1ef392(0xfd)]():null,'nearestSupport':_0x1d330e?_0x1d330e[_0x1ef392(0x14d)]['getLevel']():null,'stopTicks':this['config'][_0x1ef392(0x138)]['stopTicks'],'targetTicks':this['config'][_0x1ef392(0x138)]['targetTicks'],'strategy':_0x1ef392(0x123)};}[_0x344fde(0x159)](_0x5042ae){const _0x4156b0=_0x344fde;this[_0x4156b0(0x14b)][_0x4156b0(0xed)]({'netPnl':_0x5042ae,'timestamp':Date['now']()});if(this[_0x4156b0(0x14b)][_0x4156b0(0x148)]>0x64)this[_0x4156b0(0x14b)][_0x4156b0(0xf8)]();_0x5042ae>0x0?this[_0x4156b0(0x108)]['wins']++:this[_0x4156b0(0x108)][_0x4156b0(0x127)]++,this['stats']['trades']++,this[_0x4156b0(0x108)][_0x4156b0(0x168)]+=_0x5042ae,this['emit'](_0x4156b0(0x16a),{'type':_0x4156b0(0x12e),'message':_0x4156b0(0x13f)+(_0x5042ae>0x0?'WIN':_0x4156b0(0x161))+'\x20$'+_0x5042ae['toFixed'](0x2)});}[_0x344fde(0x11c)](_0x275010){const _0x51d5df=_0x344fde;return this[_0x51d5df(0x150)]['get'](_0x275010)||[];}['getStats'](){return this['stats'];}[_0x344fde(0x141)](_0x379e60){const _0x2ba6bb=_0x344fde;this[_0x2ba6bb(0x150)][_0x2ba6bb(0x114)](_0x379e60,[]),this[_0x2ba6bb(0xec)]['set'](_0x379e60,[]),this[_0x2ba6bb(0xf4)][_0x2ba6bb(0x114)](_0x379e60,[]),this[_0x2ba6bb(0x169)]['set'](_0x379e60,[]),this[_0x2ba6bb(0x134)](_0x2ba6bb(0x16a),{'type':'info','message':_0x2ba6bb(0x132)+_0x379e60});}}class HQX2BStrategy extends EventEmitter{constructor(_0x506c08={}){const _0x4e7b4c=_0x344fde;super(),this['config']=_0x506c08,this[_0x4e7b4c(0x143)]=new HQX2BLiquiditySweep(_0x506c08),this['strategy']['on']('signal',_0x2c7435=>this[_0x4e7b4c(0x134)](_0x4e7b4c(0x156),_0x2c7435)),this['strategy']['on']('log',_0x48ca94=>this[_0x4e7b4c(0x134)]('log',_0x48ca94));}[_0x344fde(0x116)](_0x5aaa50){return this['strategy']['processTick'](_0x5aaa50);}[_0x344fde(0x13d)](_0xdbe743){return this['strategy']['onTick'](_0xdbe743);}['onTrade'](_0x5334f0){const _0x2a4208=_0x344fde;return this['strategy'][_0x2a4208(0x128)](_0x5334f0);}[_0x344fde(0x119)](_0x514e07,_0x4d1ab6){const _0x4207a1=_0x344fde;return this[_0x4207a1(0x143)][_0x4207a1(0x119)](_0x514e07,_0x4d1ab6);}['initialize'](_0x57b0ba,_0x139161,_0x76515a){const _0x495bd0=_0x344fde;return this[_0x495bd0(0x143)][_0x495bd0(0x12b)](_0x57b0ba,_0x139161,_0x76515a);}[_0x344fde(0x154)](_0x478865,_0x1e51ed){const _0x25dc2d=_0x344fde;return this['strategy'][_0x25dc2d(0x154)](_0x478865,_0x1e51ed);}[_0x344fde(0x159)](_0x3fb341){const _0x44d0a6=_0x344fde;return this[_0x44d0a6(0x143)][_0x44d0a6(0x159)](_0x3fb341);}['reset'](_0x4b424e){const _0x2c60bd=_0x344fde;return this[_0x2c60bd(0x143)]['reset'](_0x4b424e);}[_0x344fde(0x126)](){const _0x4e147c=_0x344fde;return this[_0x4e147c(0x143)]['getStats']();}['getBarHistory'](_0x322616){const _0x5a2f94=_0x344fde;return this[_0x5a2f94(0x143)]['getBarHistory'](_0x322616);}['generateSignal'](_0x343b8a){return null;}}module[_0x344fde(0x10b)]={'HQX2BLiquiditySweep':HQX2BLiquiditySweep,'HQX2BStrategy':HQX2BStrategy,'M2':HQX2BStrategy,'S2':HQX2BLiquiditySweep,'OrderSide':OrderSide,'SignalStrength':SignalStrength,'SweepType':SweepType,'ZoneType':ZoneType,'DEFAULT_CONFIG':DEFAULT_CONFIG};function _0x31ab(){const _0x2068f5=['find','getStats','losses','onTrade','targetTicks','HIGH_SWEEP','initialize','STRONG','_detectSwings','debug','abs','BID','minVolumeRatio','[HQX-2B]\x20Reset\x20state\x20for\x20','cooldownMs','emit','t,\x20Target=','\x20|\x20Pen:','sweptAt','execution','trailDistanceTicks','lastSignalTime','volume','contractId','onTick','map','[HQX-2B]\x20Trade\x20result:\x20','452803FLuEym','reset','6360580TeFprc','strategy','1403666IRZbzt','maxZoneDistanceTicks','createdAt','t,\x20Trail=','length','qualityScore','open','recentTrades','9UMRmxi','zone','long','_getVolumeRatio','barHistory','lastUsedBarIndex','toFixed','LOW_SWEEP','getAnalysisState','swing','signal','sweepType','swept','recordTradeResult','minPenetrationTicks','x\x20|\x20Conf:','SUPPORT','volumeRatio','_updateZones','barIndex','info','LOSS','_scoreSweep','config','_detectSweep','breakevenTicks','durationBars','priceLow','pnl','activeSweeps','log','isValid','sort','short','priceHigh','size','swingPoints','push','price','now','isArray','buy','minQualityScore','timestamp','liquidityZones','minStrength','/20\x20bars','stopTicks','shift','touches','max','containsPrice','split','getLevel','extremeBarIndex','tickValue','low','11508580FNGdCh','get','clusterToleranceTicks','type','min','113766RvAvbN','strength','stats','[HQX-2B]\x20Initialized\x20for\x20','penetrationTicks','exports','uuid','lookbackBars','_generateSignal','[HQX-2B]\x20SIGNAL:\x20','close','4096960UugIad','tickSize','77AgvQkZ','set','entryBarIndex','processTick','5249656kdotoV','t,\x20BE=','processBar','3taXcSl','trailTriggerTicks','getBarHistory','high','signals','floor','t\x20Vol:','[HQX-2B]\x20Params:\x20Stop=','events','HQX-2B\x20Liquidity\x20Sweep\x20(Optimized)','splice'];_0x31ab=function(){return _0x2068f5;};return _0x31ab();}
@@ -0,0 +1 @@
1
+ const _0x371eb1=_0x4b27;(function(_0x507643,_0x538df8){const _0x563eca=_0x4b27,_0x3dfc41=_0x507643();while(!![]){try{const _0x42b617=-parseInt(_0x563eca(0x190))/0x1*(-parseInt(_0x563eca(0x156))/0x2)+parseInt(_0x563eca(0x183))/0x3+parseInt(_0x563eca(0x180))/0x4+-parseInt(_0x563eca(0x158))/0x5+parseInt(_0x563eca(0x15e))/0x6*(-parseInt(_0x563eca(0x189))/0x7)+parseInt(_0x563eca(0x137))/0x8+parseInt(_0x563eca(0x13f))/0x9*(-parseInt(_0x563eca(0x181))/0xa);if(_0x42b617===_0x538df8)break;else _0x3dfc41['push'](_0x3dfc41['shift']());}catch(_0xd4d426){_0x3dfc41['push'](_0x3dfc41['shift']());}}}(_0x411a,0x53323));const EventEmitter=require('events'),{v4:uuidv4}=require('uuid'),OrderSide={'BID':0x0,'ASK':0x1},SignalStrength={'WEAK':0x1,'MODERATE':0x2,'STRONG':0x3,'VERY_STRONG':0x4};function _0x411a(){const _0x27a23d=['2475448YZZsWq','kalman','price','kalmanStates','%\x20Kyle:','confidenceBonus','HQX_ULTRA_SCALPING_6MODELS','tickSize','694269rFwgpb','info','exports','BID','profitLockPct','split','ASK','stopMultiplier','trades','length','\x20VPIN:','onTick','\x20Regime:','stats','close','processTick','signal','getAnalysisState','lossStreak','barHistory','_generateSignal','lastSignalTime','getStats','470192mXQQiX','_detectVolatilityRegime','2511350svvQNF','estimate','[HQX-UltraScalping]\x20Initialized\x20for\x20','zscoreThreshold','weights','WEAK','204vdZvxj','now','sell','_computeVPIN','targetMultiplier','_applyKalmanFilter','kalmanProcessNoise',':\x20tick=','zscoreExitThreshold','signals',',\x20streak:\x20','pow','strategy','losses','winStreak','zscoreEntryThreshold','wins','symbol','_calculateATR','baseTargetTicks','filter','ofiLookback','generateSignal','abs','round','buy','initialize','push','reset','toFixed','composite','set','getModelValues','vpinToxicThreshold','1089760NgASxb','110shtkue','shift','2012835ylCsNd',',\x20value=','get','\x20@\x20','emit','Collecting\x20data...\x20','6468ehZsMS','getBarHistory','onTrade','_computeOrderFlowImbalance','high','reduce','breakevenTicks','2KorAWa','6\x20(Z-Score,\x20VPIN,\x20Kyle,\x20Kalman,\x20Vol,\x20OFI)','volumeBuffer','volume','minConfidence','pnl','log','recordTradeResult','long','kyleLambda','processBar','_computeKyleLambda','side','min','kalmanMeasurementNoise','priceBuffer','ofi','errorCovariance','max','short',',\x20VPIN=','slice','zscore','_computeZScore','atrHistory','volatility','low','baseStopTicks'];_0x411a=function(){return _0x27a23d;};return _0x411a();}class HQXUltraScalping extends EventEmitter{constructor(_0x36c01b={}){const _0x500d51=_0x4b27;super(),this[_0x500d51(0x13e)]=_0x36c01b[_0x500d51(0x13e)]||0.25,this['tickValue']=_0x36c01b['tickValue']||0x5,this[_0x500d51(0x16d)]=1.5,this['zscoreExitThreshold']=0.5,this['vpinWindow']=0x32,this['vpinToxicThreshold']=0.7,this[_0x500d51(0x164)]=0.01,this[_0x500d51(0x129)]=0.1,this['volatilityLookback']=0x64,this[_0x500d51(0x173)]=0x14,this['baseStopTicks']=0x8,this[_0x500d51(0x171)]=0x10,this[_0x500d51(0x18f)]=0x4,this['profitLockPct']=0.5,this['minConfidence']=0.55,this[_0x500d51(0x15c)]={'zscore':0.3,'ofi':0.2,'vpin':0.15,'kalman':0.15,'kyleLambda':0.1,'volatility':0.1},this['barHistory']=new Map(),this['priceBuffer']=new Map(),this['volumeBuffer']=new Map(),this[_0x500d51(0x13a)]=new Map(),this['atrHistory']=new Map(),this['recentTrades']=[],this['winStreak']=0x0,this['lossStreak']=0x0,this[_0x500d51(0x154)]=0x0,this['cooldownMs']=0x7530,this['minHoldTimeMs']=0x2710,this['stats']={'signals':0x0,'trades':0x0,'wins':0x0,'losses':0x0,'pnl':0x0};}[_0x371eb1(0x178)](_0x868a52,_0x4a1bf5=0.25,_0x27a4c2=0x5){const _0x4ddb38=_0x371eb1;this[_0x4ddb38(0x13e)]=_0x4a1bf5,this['tickValue']=_0x27a4c2,this[_0x4ddb38(0x152)][_0x4ddb38(0x17d)](_0x868a52,[]),this[_0x4ddb38(0x12a)]['set'](_0x868a52,[]),this[_0x4ddb38(0x192)]['set'](_0x868a52,[]),this[_0x4ddb38(0x133)]['set'](_0x868a52,[]),this[_0x4ddb38(0x13a)][_0x4ddb38(0x17d)](_0x868a52,{'estimate':0x0,'errorCovariance':0x1}),this['emit']('log',{'type':_0x4ddb38(0x140),'message':_0x4ddb38(0x15a)+_0x868a52+_0x4ddb38(0x165)+_0x4a1bf5+_0x4ddb38(0x184)+_0x27a4c2}),this[_0x4ddb38(0x187)](_0x4ddb38(0x121),{'type':_0x4ddb38(0x140),'message':'[HQX-UltraScalping]\x206\x20Models:\x20Z-Score(30%),\x20OFI(20%),\x20VPIN(15%),\x20Kalman(15%),\x20Kyle(10%),\x20Vol(10%)'});}[_0x371eb1(0x14e)](_0x16706f){const _0x4cbeda=_0x371eb1,{contractId:_0x27ef24,price:_0x53c926,volume:_0x388677,side:_0x3dff0d,timestamp:_0x1fd07f}=_0x16706f,_0x4bee87={'timestamp':_0x1fd07f||Date[_0x4cbeda(0x15f)](),'open':_0x53c926,'high':_0x53c926,'low':_0x53c926,'close':_0x53c926,'volume':_0x388677||0x1};return this[_0x4cbeda(0x125)](_0x27ef24,_0x4bee87);}['onTick'](_0x1328b5){const _0x5386f7=_0x371eb1;return this[_0x5386f7(0x14e)](_0x1328b5);}['onTrade'](_0xb54c4c){const _0x4d0ae5=_0x371eb1;return this[_0x4d0ae5(0x14e)]({'contractId':_0xb54c4c['contractId']||_0xb54c4c[_0x4d0ae5(0x16f)],'price':_0xb54c4c[_0x4d0ae5(0x139)],'volume':_0xb54c4c['size']||_0xb54c4c['volume']||0x1,'side':_0xb54c4c[_0x4d0ae5(0x127)],'timestamp':_0xb54c4c['timestamp']||Date[_0x4d0ae5(0x15f)]()});}[_0x371eb1(0x125)](_0x16055a,_0x283841){const _0x48a98e=_0x371eb1;let _0x4f34c0=this[_0x48a98e(0x152)]['get'](_0x16055a);!_0x4f34c0&&(this['initialize'](_0x16055a),_0x4f34c0=this[_0x48a98e(0x152)]['get'](_0x16055a));_0x4f34c0['push'](_0x283841);if(_0x4f34c0[_0x48a98e(0x148)]>0x1f4)_0x4f34c0[_0x48a98e(0x182)]();const _0x1254f0=this['priceBuffer']['get'](_0x16055a);_0x1254f0['push'](_0x283841['close']);if(_0x1254f0[_0x48a98e(0x148)]>0xc8)_0x1254f0[_0x48a98e(0x182)]();const _0x53a2b7=this['volumeBuffer']['get'](_0x16055a),_0x4eb2a6=_0x283841['high']-_0x283841[_0x48a98e(0x135)];let _0x473033=_0x283841[_0x48a98e(0x193)]*0.5,_0x13bb19=_0x283841['volume']*0.5;if(_0x4eb2a6>0x0){const _0x1c3017=(_0x283841['close']-_0x283841[_0x48a98e(0x135)])/_0x4eb2a6;_0x473033=_0x283841[_0x48a98e(0x193)]*_0x1c3017,_0x13bb19=_0x283841[_0x48a98e(0x193)]*(0x1-_0x1c3017);}_0x53a2b7['push']({'buy':_0x473033,'sell':_0x13bb19});if(_0x53a2b7['length']>0x64)_0x53a2b7[_0x48a98e(0x182)]();if(_0x4f34c0[_0x48a98e(0x148)]<0x32)return null;const _0x3dfcad=this['_computeZScore'](_0x1254f0),_0x1837a2=this[_0x48a98e(0x161)](_0x53a2b7),_0x74821=this[_0x48a98e(0x126)](_0x4f34c0),_0x25c8da=this[_0x48a98e(0x163)](_0x16055a,_0x283841['close']),{regime:_0x91e763,params:_0x24948f}=this[_0x48a98e(0x157)](_0x16055a,_0x4f34c0),_0x26a2b9=this[_0x48a98e(0x18c)](_0x4f34c0);return this['_generateSignal'](_0x16055a,_0x283841['close'],_0x3dfcad,_0x1837a2,_0x74821,_0x25c8da,_0x91e763,_0x24948f,_0x26a2b9,_0x4f34c0);}['_computeZScore'](_0x33dfb0,_0x2cf611=0x32){const _0x134efb=_0x371eb1;if(_0x33dfb0['length']<_0x2cf611)return 0x0;const _0x460593=_0x33dfb0[_0x134efb(0x130)](-_0x2cf611),_0x285e3f=_0x460593['reduce']((_0xd9a79b,_0x5d0d53)=>_0xd9a79b+_0x5d0d53,0x0)/_0x2cf611,_0x2cf47a=_0x460593[_0x134efb(0x18e)]((_0x442e16,_0x5b5e94)=>_0x442e16+Math[_0x134efb(0x169)](_0x5b5e94-_0x285e3f,0x2),0x0)/_0x2cf611,_0x42da2b=Math['sqrt'](_0x2cf47a);if(_0x42da2b<0.0001)return 0x0;const _0x4d38c3=_0x33dfb0[_0x33dfb0['length']-0x1];return(_0x4d38c3-_0x285e3f)/_0x42da2b;}[_0x371eb1(0x161)](_0x3b06d8){const _0x2eeedf=_0x371eb1;if(_0x3b06d8['length']<this['vpinWindow'])return 0.5;const _0x23f368=_0x3b06d8['slice'](-this['vpinWindow']);let _0x4031d1=0x0,_0x38689b=0x0;for(const _0x19a355 of _0x23f368){_0x4031d1+=_0x19a355[_0x2eeedf(0x177)],_0x38689b+=_0x19a355[_0x2eeedf(0x160)];}const _0x113023=_0x4031d1+_0x38689b;if(_0x113023<0x1)return 0.5;return Math['abs'](_0x4031d1-_0x38689b)/_0x113023;}['_computeKyleLambda'](_0xf4971c){const _0x813121=_0x371eb1;if(_0xf4971c['length']<0x14)return 0x0;const _0x33bf14=_0xf4971c['slice'](-0x14),_0x57317b=[],_0x34e3fd=[];for(let _0x56111a=0x1;_0x56111a<_0x33bf14[_0x813121(0x148)];_0x56111a++){_0x57317b['push'](_0x33bf14[_0x56111a][_0x813121(0x14d)]-_0x33bf14[_0x56111a-0x1]['close']),_0x34e3fd['push'](_0x33bf14[_0x56111a][_0x813121(0x193)]);}const _0x3d3b37=_0x57317b['reduce']((_0x738715,_0x3216f2)=>_0x738715+_0x3216f2,0x0)/_0x57317b[_0x813121(0x148)],_0x144ac9=_0x34e3fd[_0x813121(0x18e)]((_0x29a9b9,_0x2e41f7)=>_0x29a9b9+_0x2e41f7,0x0)/_0x34e3fd[_0x813121(0x148)];let _0x4b566e=0x0,_0x374f8d=0x0;for(let _0xa01cf4=0x0;_0xa01cf4<_0x57317b['length'];_0xa01cf4++){_0x4b566e+=(_0x57317b[_0xa01cf4]-_0x3d3b37)*(_0x34e3fd[_0xa01cf4]-_0x144ac9),_0x374f8d+=Math['pow'](_0x34e3fd[_0xa01cf4]-_0x144ac9,0x2);}_0x4b566e/=_0x57317b['length'],_0x374f8d/=_0x57317b[_0x813121(0x148)];if(_0x374f8d<0.0001)return 0x0;return Math['abs'](_0x4b566e/_0x374f8d);}[_0x371eb1(0x163)](_0x57d582,_0x3462ce){const _0x24cba8=_0x371eb1;let _0x486837=this[_0x24cba8(0x13a)]['get'](_0x57d582);if(!_0x486837)return _0x486837={'estimate':_0x3462ce,'errorCovariance':0x1},this['kalmanStates'][_0x24cba8(0x17d)](_0x57d582,_0x486837),_0x3462ce;const _0x2dd1da=_0x486837['estimate'],_0xc39734=_0x486837[_0x24cba8(0x12c)]+this['kalmanProcessNoise'],_0x56a97c=_0xc39734/(_0xc39734+this['kalmanMeasurementNoise']),_0x5a7c33=_0x2dd1da+_0x56a97c*(_0x3462ce-_0x2dd1da),_0x52d3e0=(0x1-_0x56a97c)*_0xc39734;return _0x486837[_0x24cba8(0x159)]=_0x5a7c33,_0x486837['errorCovariance']=_0x52d3e0,_0x5a7c33;}[_0x371eb1(0x157)](_0xc85bad,_0x8b120a){const _0x408ec8=_0x371eb1,_0x5aa785=this['_calculateATR'](_0x8b120a),_0x553dc3=_0x5aa785/this[_0x408ec8(0x13e)];let _0x5e843d=this[_0x408ec8(0x133)][_0x408ec8(0x185)](_0xc85bad);!_0x5e843d&&(_0x5e843d=[],this['atrHistory']['set'](_0xc85bad,_0x5e843d));_0x5e843d[_0x408ec8(0x179)](_0x5aa785);if(_0x5e843d[_0x408ec8(0x148)]>0x1f4)_0x5e843d[_0x408ec8(0x182)]();let _0x57b341=0.5;_0x5e843d['length']>=0x14&&(_0x57b341=_0x5e843d[_0x408ec8(0x172)](_0x5260f5=>_0x5260f5<=_0x5aa785)['length']/_0x5e843d['length']);let _0x2e01b2,_0x347a0e;if(_0x57b341<0.25)_0x2e01b2='low',_0x347a0e={'stopMultiplier':0.8,'targetMultiplier':0.9,'zscoreThreshold':1.2,'confidenceBonus':0.05};else _0x57b341<0.75?(_0x2e01b2='normal',_0x347a0e={'stopMultiplier':0x1,'targetMultiplier':0x1,'zscoreThreshold':1.5,'confidenceBonus':0x0}):(_0x2e01b2=_0x408ec8(0x18d),_0x347a0e={'stopMultiplier':1.3,'targetMultiplier':1.2,'zscoreThreshold':0x2,'confidenceBonus':-0.05});return{'regime':_0x2e01b2,'params':_0x347a0e};}[_0x371eb1(0x170)](_0x2d06a1,_0x169650=0xe){const _0x50f133=_0x371eb1;if(_0x2d06a1['length']<_0x169650+0x1)return 2.5;const _0x3d94b5=[];for(let _0x28cbae=_0x2d06a1['length']-_0x169650;_0x28cbae<_0x2d06a1['length'];_0x28cbae++){const _0x3038c5=_0x2d06a1[_0x28cbae],_0x4eb12b=_0x2d06a1[_0x28cbae-0x1]['close'],_0x1b7ea2=Math[_0x50f133(0x12d)](_0x3038c5[_0x50f133(0x18d)]-_0x3038c5[_0x50f133(0x135)],Math[_0x50f133(0x175)](_0x3038c5[_0x50f133(0x18d)]-_0x4eb12b),Math['abs'](_0x3038c5['low']-_0x4eb12b));_0x3d94b5[_0x50f133(0x179)](_0x1b7ea2);}return _0x3d94b5['reduce']((_0x39b5fd,_0xd20ab0)=>_0x39b5fd+_0xd20ab0,0x0)/_0x3d94b5['length'];}['_computeOrderFlowImbalance'](_0x582a89){const _0x4945c9=_0x371eb1;if(_0x582a89[_0x4945c9(0x148)]<this[_0x4945c9(0x173)])return 0x0;const _0x48d888=_0x582a89['slice'](-this['ofiLookback']);let _0x55edd9=0x0,_0x260a92=0x0;for(const _0x176c62 of _0x48d888){const _0x5b2d5a=_0x176c62['high']-_0x176c62[_0x4945c9(0x135)];if(_0x5b2d5a>0x0){const _0x54db25=(_0x176c62[_0x4945c9(0x14d)]-_0x176c62[_0x4945c9(0x135)])/_0x5b2d5a;_0x55edd9+=_0x54db25*_0x176c62[_0x4945c9(0x193)],_0x260a92+=(0x1-_0x54db25)*_0x176c62['volume'];}}const _0x5492ab=_0x55edd9+_0x260a92;if(_0x5492ab<0x1)return 0x0;return(_0x55edd9-_0x260a92)/_0x5492ab;}[_0x371eb1(0x153)](_0x317a32,_0x51668a,_0x1ee39d,_0x3b8899,_0x229d9c,_0x26fa8a,_0x22a87a,_0x38beeb,_0xd56043,_0x518297){const _0x184de5=_0x371eb1,_0x15d504=Math[_0x184de5(0x175)](_0x1ee39d);if(_0x15d504<_0x38beeb['zscoreThreshold'])return null;if(_0x3b8899>this[_0x184de5(0x17f)])return null;let _0x5759b5;if(_0x1ee39d<-_0x38beeb[_0x184de5(0x15b)])_0x5759b5='long';else{if(_0x1ee39d>_0x38beeb['zscoreThreshold'])_0x5759b5='short';else return null;}const _0x4a1fa1=_0x5759b5===_0x184de5(0x123)&&_0xd56043>0.1||_0x5759b5===_0x184de5(0x12e)&&_0xd56043<-0.1,_0x21e280=_0x51668a-_0x26fa8a,_0x493653=_0x5759b5===_0x184de5(0x123)&&_0x21e280<0x0||_0x5759b5===_0x184de5(0x12e)&&_0x21e280>0x0,_0x141172={'zscore':Math['min'](0x1,_0x15d504/0x4),'vpin':0x1-_0x3b8899,'kyleLambda':_0x229d9c>0.001?0.5:0.8,'kalman':_0x493653?0.8:0.4,'volatility':_0x22a87a==='normal'?0.8:_0x22a87a===_0x184de5(0x135)?0.7:0.6,'ofi':_0x4a1fa1?0.9:0.5,'composite':0x0};_0x141172[_0x184de5(0x17c)]=_0x141172['zscore']*this['weights'][_0x184de5(0x131)]+_0x141172['vpin']*this[_0x184de5(0x15c)]['vpin']+_0x141172['kyleLambda']*this['weights'][_0x184de5(0x124)]+_0x141172[_0x184de5(0x138)]*this['weights']['kalman']+_0x141172[_0x184de5(0x134)]*this[_0x184de5(0x15c)]['volatility']+_0x141172[_0x184de5(0x12b)]*this[_0x184de5(0x15c)]['ofi'];const _0x3b6c87=Math[_0x184de5(0x128)](0x1,_0x141172['composite']+_0x38beeb[_0x184de5(0x13c)]);if(_0x3b6c87<this[_0x184de5(0x11f)])return null;if(Date[_0x184de5(0x15f)]()-this[_0x184de5(0x154)]<this['cooldownMs'])return null;const _0x31f489=Math['round'](this[_0x184de5(0x136)]*_0x38beeb[_0x184de5(0x146)]),_0x2a44b6=Math[_0x184de5(0x176)](this[_0x184de5(0x171)]*_0x38beeb[_0x184de5(0x162)]),_0x422654=Math[_0x184de5(0x12d)](0x6,Math[_0x184de5(0x128)](0xc,_0x31f489)),_0x2353e7=Math['max'](_0x422654*1.5,Math[_0x184de5(0x128)](0x18,_0x2a44b6));let _0x1dcea3,_0x2cce06,_0x43e504,_0x495e95;_0x5759b5===_0x184de5(0x123)?(_0x1dcea3=_0x51668a-_0x422654*this[_0x184de5(0x13e)],_0x2cce06=_0x51668a+_0x2353e7*this['tickSize'],_0x43e504=_0x51668a+this['breakevenTicks']*this['tickSize'],_0x495e95=_0x51668a+_0x2353e7*this[_0x184de5(0x143)]*this[_0x184de5(0x13e)]):(_0x1dcea3=_0x51668a+_0x422654*this[_0x184de5(0x13e)],_0x2cce06=_0x51668a-_0x2353e7*this['tickSize'],_0x43e504=_0x51668a-this['breakevenTicks']*this[_0x184de5(0x13e)],_0x495e95=_0x51668a-_0x2353e7*this[_0x184de5(0x143)]*this['tickSize']);const _0x105cdf=_0x2353e7/_0x422654,_0x131f8c=Math[_0x184de5(0x176)](_0x2353e7*0.5),_0xe9a67d=Math[_0x184de5(0x176)](_0x422654*0.4);let _0x1d1787=SignalStrength['MODERATE'];if(_0x3b6c87>=0.85)_0x1d1787=SignalStrength['VERY_STRONG'];else{if(_0x3b6c87>=0.75)_0x1d1787=SignalStrength['STRONG'];else{if(_0x3b6c87<0.6)_0x1d1787=SignalStrength[_0x184de5(0x15d)];}}const _0x17213a=0.5+(_0x3b6c87-0.5)*0.4,_0x4e77a2=_0x17213a*Math[_0x184de5(0x175)](_0x2cce06-_0x51668a)-(0x1-_0x17213a)*Math['abs'](_0x51668a-_0x1dcea3);this['lastSignalTime']=Date['now'](),this['stats'][_0x184de5(0x167)]++;const _0x37f751={'id':uuidv4(),'timestamp':Date['now'](),'symbol':_0x317a32[_0x184de5(0x144)]('.')[0x0]||_0x317a32,'contractId':_0x317a32,'side':_0x5759b5===_0x184de5(0x123)?OrderSide[_0x184de5(0x142)]:OrderSide[_0x184de5(0x145)],'direction':_0x5759b5,'strategy':_0x184de5(0x13d),'strength':_0x1d1787,'edge':_0x4e77a2,'confidence':_0x3b6c87,'entry':_0x51668a,'entryPrice':_0x51668a,'stopLoss':_0x1dcea3,'takeProfit':_0x2cce06,'riskReward':_0x105cdf,'stopTicks':_0x422654,'targetTicks':_0x2353e7,'trailTriggerTicks':_0x131f8c,'trailDistanceTicks':_0xe9a67d,'beBreakeven':_0x43e504,'profitLockLevel':_0x495e95,'zScore':_0x1ee39d,'zScoreExit':this['zscoreExitThreshold'],'vpinValue':_0x3b8899,'kyleLambda':_0x229d9c,'kalmanEstimate':_0x26fa8a,'volatilityRegime':_0x22a87a,'ofiValue':_0xd56043,'models':_0x141172,'orderFlowConfirmed':_0x4a1fa1,'kalmanConfirmed':_0x493653,'expires':Date['now']()+0xea60};return this['emit'](_0x184de5(0x14f),{'side':_0x5759b5==='long'?'buy':'sell','action':'open','reason':'Z='+_0x1ee39d['toFixed'](0x2)+_0x184de5(0x12f)+(_0x3b8899*0x64)[_0x184de5(0x17b)](0x0)+'%,\x20OFI='+(_0xd56043*0x64)[_0x184de5(0x17b)](0x0)+'%,\x20cf='+(_0x3b6c87*0x64)[_0x184de5(0x17b)](0x0)+'%',..._0x37f751}),this['emit']('log',{'type':_0x184de5(0x140),'message':'[HQX]\x20SIGNAL:\x20'+_0x5759b5['toUpperCase']()+_0x184de5(0x186)+_0x51668a[_0x184de5(0x17b)](0x2)+'\x20|\x20Z:'+_0x1ee39d[_0x184de5(0x17b)](0x2)+_0x184de5(0x149)+(_0x3b8899*0x64)[_0x184de5(0x17b)](0x0)+'%\x20OFI:'+(_0xd56043*0x64)['toFixed'](0x0)+_0x184de5(0x13b)+_0x229d9c['toFixed'](0x5)+_0x184de5(0x14b)+_0x22a87a+'\x20|\x20Conf:'+(_0x3b6c87*0x64)['toFixed'](0x0)+'%'}),_0x37f751;}['shouldExitByZScore'](_0x18198d){const _0xe0018e=_0x371eb1,_0x9c72d7=this[_0xe0018e(0x12a)][_0xe0018e(0x185)](_0x18198d);if(!_0x9c72d7||_0x9c72d7[_0xe0018e(0x148)]<0x32)return![];const _0x287ecd=this[_0xe0018e(0x132)](_0x9c72d7);return Math[_0xe0018e(0x175)](_0x287ecd)<this[_0xe0018e(0x166)];}[_0x371eb1(0x17e)](_0x42ff12){const _0x453183=_0x371eb1,_0x4bc437=this[_0x453183(0x12a)][_0x453183(0x185)](_0x42ff12),_0x1d439f=this[_0x453183(0x192)][_0x453183(0x185)](_0x42ff12),_0xb50dc9=this['barHistory'][_0x453183(0x185)](_0x42ff12);if(!_0x4bc437||!_0x1d439f||!_0xb50dc9||_0xb50dc9['length']<0x32)return null;const _0x260c32=this['_computeZScore'](_0x4bc437),_0x276e0e=this[_0x453183(0x161)](_0x1d439f),_0x183dd3=this['_computeKyleLambda'](_0xb50dc9),_0x3df13c=this['_computeOrderFlowImbalance'](_0xb50dc9);return{'zscore':Math['min'](0x1,Math[_0x453183(0x175)](_0x260c32)/0x4),'vpin':0x1-_0x276e0e,'kyleLambda':_0x183dd3>0.001?0.5:0.8,'kalman':0.7,'volatility':0.7,'ofi':Math['abs'](_0x3df13c)>0.1?0.8:0.5,'composite':0.7,'raw':{'zscore':_0x260c32,'vpin':_0x276e0e,'kyleLambda':_0x183dd3,'ofi':_0x3df13c}};}[_0x371eb1(0x150)](_0x104d11,_0xe08a26){const _0x2a256e=_0x371eb1,_0xce6de4=this['barHistory'][_0x2a256e(0x185)](_0x104d11)||[];if(_0xce6de4['length']<0x32)return{'ready':![],'message':_0x2a256e(0x188)+_0xce6de4['length']+'/50\x20bars'};const _0x2b1fec=this[_0x2a256e(0x12a)][_0x2a256e(0x185)](_0x104d11)||[],_0x277c7d=this[_0x2a256e(0x192)]['get'](_0x104d11)||[],_0x529871=this[_0x2a256e(0x132)](_0x2b1fec),_0x34b9fc=this['_computeVPIN'](_0x277c7d),_0x2eab93=this['_computeOrderFlowImbalance'](_0xce6de4),_0x4e8e17=this[_0x2a256e(0x126)](_0xce6de4),{regime:_0x42fdf3,params:_0x14e667}=this[_0x2a256e(0x157)](_0x104d11,_0xce6de4);return{'ready':!![],'zScore':_0x529871,'vpin':_0x34b9fc,'ofi':_0x2eab93,'kyleLambda':_0x4e8e17,'regime':_0x42fdf3,'stopTicks':Math[_0x2a256e(0x176)](this[_0x2a256e(0x136)]*_0x14e667['stopMultiplier']),'targetTicks':Math[_0x2a256e(0x176)](this['baseTargetTicks']*_0x14e667['targetMultiplier']),'threshold':_0x14e667['zscoreThreshold'],'barsProcessed':_0xce6de4[_0x2a256e(0x148)],'models':_0x2a256e(0x191)};}[_0x371eb1(0x122)](_0x12a30f){const _0x9df8dc=_0x371eb1;this['recentTrades'][_0x9df8dc(0x179)]({'netPnl':_0x12a30f,'timestamp':Date['now']()});if(this['recentTrades'][_0x9df8dc(0x148)]>0x64)this['recentTrades']['shift']();_0x12a30f>0x0?(this['winStreak']++,this['lossStreak']=0x0,this[_0x9df8dc(0x14c)][_0x9df8dc(0x16e)]++):(this[_0x9df8dc(0x151)]++,this['winStreak']=0x0,this['stats'][_0x9df8dc(0x16b)]++),this[_0x9df8dc(0x14c)][_0x9df8dc(0x147)]++,this[_0x9df8dc(0x14c)][_0x9df8dc(0x120)]+=_0x12a30f,this[_0x9df8dc(0x187)]('log',{'type':'debug','message':'[HQX]\x20Trade\x20result:\x20'+(_0x12a30f>0x0?'WIN':'LOSS')+'\x20$'+_0x12a30f['toFixed'](0x2)+_0x9df8dc(0x168)+(_0x12a30f>0x0?this[_0x9df8dc(0x16c)]:-this['lossStreak'])});}[_0x371eb1(0x18a)](_0x48cb29){return this['barHistory']['get'](_0x48cb29)||[];}[_0x371eb1(0x155)](){return this['stats'];}[_0x371eb1(0x17a)](_0x2db903){const _0x29b967=_0x371eb1;this['barHistory']['set'](_0x2db903,[]),this[_0x29b967(0x12a)]['set'](_0x2db903,[]),this[_0x29b967(0x192)][_0x29b967(0x17d)](_0x2db903,[]),this[_0x29b967(0x133)]['set'](_0x2db903,[]),this['kalmanStates'][_0x29b967(0x17d)](_0x2db903,{'estimate':0x0,'errorCovariance':0x1}),this['emit'](_0x29b967(0x121),{'type':'info','message':'[HQX-UltraScalping]\x20Reset\x20state\x20for\x20'+_0x2db903});}}function _0x4b27(_0x5c3c89,_0x39f9b9){_0x5c3c89=_0x5c3c89-0x11f;const _0x411ae3=_0x411a();let _0x4b2782=_0x411ae3[_0x5c3c89];return _0x4b2782;}class UltraScalpingStrategy extends EventEmitter{constructor(_0x35d97c={}){const _0x594019=_0x371eb1;super(),this['config']=_0x35d97c,this[_0x594019(0x16a)]=new HQXUltraScalping(_0x35d97c),this['strategy']['on']('signal',_0x2742d2=>this['emit']('signal',_0x2742d2)),this['strategy']['on'](_0x594019(0x121),_0x3d29fb=>this['emit']('log',_0x3d29fb));}[_0x371eb1(0x14e)](_0x3b7fbe){return this['strategy']['processTick'](_0x3b7fbe);}[_0x371eb1(0x14a)](_0x56cfa0){return this['strategy']['onTick'](_0x56cfa0);}[_0x371eb1(0x18b)](_0xa016de){const _0x2f46cc=_0x371eb1;return this[_0x2f46cc(0x16a)][_0x2f46cc(0x18b)](_0xa016de);}['processBar'](_0x57a8c0,_0x277b59){const _0x126dbd=_0x371eb1;return this['strategy'][_0x126dbd(0x125)](_0x57a8c0,_0x277b59);}['initialize'](_0x23d70e,_0x18cd66,_0x2a4f00){const _0x2e7df3=_0x371eb1;return this[_0x2e7df3(0x16a)][_0x2e7df3(0x178)](_0x23d70e,_0x18cd66,_0x2a4f00);}['getAnalysisState'](_0x370971,_0x8ee12){return this['strategy']['getAnalysisState'](_0x370971,_0x8ee12);}[_0x371eb1(0x122)](_0x403f97){const _0x35f503=_0x371eb1;return this[_0x35f503(0x16a)][_0x35f503(0x122)](_0x403f97);}['reset'](_0x2adeff){const _0x3e03fc=_0x371eb1;return this['strategy'][_0x3e03fc(0x17a)](_0x2adeff);}['getStats'](){const _0x4c050e=_0x371eb1;return this[_0x4c050e(0x16a)][_0x4c050e(0x155)]();}[_0x371eb1(0x18a)](_0x3bc119){return this['strategy']['getBarHistory'](_0x3bc119);}['getModelValues'](_0x2e2674){const _0x30bb59=_0x371eb1;return this['strategy'][_0x30bb59(0x17e)](_0x2e2674);}['shouldExitByZScore'](_0x451471){const _0x2796fe=_0x371eb1;return this[_0x2796fe(0x16a)]['shouldExitByZScore'](_0x451471);}[_0x371eb1(0x174)](_0x32f693){return null;}}module[_0x371eb1(0x141)]={'HQXUltraScalping':HQXUltraScalping,'UltraScalpingStrategy':UltraScalpingStrategy,'M1':UltraScalpingStrategy,'S1':HQXUltraScalping,'OrderSide':OrderSide,'SignalStrength':SignalStrength};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.9.47",
3
+ "version": "2.9.49",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -70,6 +70,7 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "esbuild": "^0.27.2",
73
+ "javascript-obfuscator": "^5.1.0",
73
74
  "nodemon": "^3.0.2"
74
75
  }
75
76
  }
package/src/app.js CHANGED
@@ -77,7 +77,7 @@ const refreshStats = async () => {
77
77
 
78
78
  try {
79
79
  const allAccounts = await connections.getAllAccounts();
80
- // Filter active accounts: status === 0 (ProjectX) OR status === 'active' (Rithmic) OR no status
80
+ // Filter active accounts: status === 'active' (Rithmic) OR status === 0 OR no status
81
81
  const activeAccounts = allAccounts.filter(acc =>
82
82
  acc.status === 0 || acc.status === 'active' || acc.status === undefined || acc.status === null
83
83
  );
@@ -15,14 +15,7 @@ const PROPFIRMS = {
15
15
  rithmicSystem: 'Apex',
16
16
  wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443',
17
17
  },
18
- topsteptrader: {
19
- id: 'topsteptrader',
20
- name: 'TopstepTrader',
21
- displayName: 'TopstepTrader',
22
- platform: 'Rithmic',
23
- rithmicSystem: 'TopstepTrader',
24
- wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443'
25
- },
18
+
26
19
  mes_capital: {
27
20
  id: 'mes-capital',
28
21
  name: 'MES Capital',
package/src/lib/data.js CHANGED
@@ -1,328 +1,247 @@
1
1
  /**
2
2
  * =============================================================================
3
- * MARKET DATA FEED - SignalR Real-Time Data
3
+ * MARKET DATA FEED - Rithmic TICKER_PLANT Real-Time Data
4
4
  * =============================================================================
5
- * Connects to ProjectX Gateway RTC for real-time market data
5
+ * Connects to Rithmic TICKER_PLANT for real-time market data
6
6
  *
7
7
  * Events emitted:
8
8
  * - tick: Quote/trade updates (price, bid, ask, volume)
9
- * - quote: Quote updates only
10
- * - trade: Trade executions only
11
- * - depth: DOM/Level 2 updates
12
9
  * - connected: Connection established
13
10
  * - disconnected: Connection lost
14
11
  * - error: Connection error
15
- *
16
- * SOURCE: Based on ProjectX Gateway RTC API
17
12
  */
18
13
 
19
14
  'use strict';
20
15
 
21
16
  const EventEmitter = require('events');
22
- const { HubConnectionBuilder, HttpTransportType, LogLevel } = require('@microsoft/signalr');
23
-
24
- // Inline PROPFIRMS config for RTC URLs (standalone module)
25
- // RTC URL pattern: api.xxx.com -> rtc.xxx.com
26
- const PROPFIRMS = {
27
- topstep: { gatewayApi: 'api.topstepx.com' },
28
- alpha_futures: { gatewayApi: 'api.alphafutures.projectx.com' },
29
- tickticktrader: { gatewayApi: 'api.tickticktrader.projectx.com' },
30
- bulenox: { gatewayApi: 'api.bulenox.projectx.com' },
31
- tradeday: { gatewayApi: 'api.tradeday.projectx.com' },
32
- blusky: { gatewayApi: 'api.blusky.projectx.com' },
33
- goat_futures: { gatewayApi: 'api.goatfutures.projectx.com' },
34
- futures_desk: { gatewayApi: 'api.thefuturesdesk.projectx.com' },
35
- daytraders: { gatewayApi: 'api.daytraders.projectx.com' },
36
- e8_futures: { gatewayApi: 'api.e8futures.projectx.com' },
37
- blue_guardian: { gatewayApi: 'api.blueguardianfutures.projectx.com' },
38
- futures_elite: { gatewayApi: 'api.futureselite.projectx.com' },
39
- fxify: { gatewayApi: 'api.fxify.projectx.com' },
40
- hola_prime: { gatewayApi: 'api.holaprime.projectx.com' },
41
- top_one_futures: { gatewayApi: 'api.toponefutures.projectx.com' },
42
- funding_futures: { gatewayApi: 'api.fundingfutures.projectx.com' },
43
- tx3_funding: { gatewayApi: 'api.tx3funding.projectx.com' },
44
- lucid_trading: { gatewayApi: 'api.lucidtrading.projectx.com' },
45
- tradeify: { gatewayApi: 'api.tradeify.projectx.com' }
46
- };
17
+ const { RithmicConnection } = require('../services/rithmic/connection');
18
+ const { proto } = require('../services/rithmic/protobuf');
19
+ const { REQ, RES, STREAM, RITHMIC_ENDPOINTS, RITHMIC_SYSTEMS } = require('../services/rithmic/constants');
47
20
 
48
21
  // =============================================================================
49
- // MARKET DATA FEED CLASS
22
+ // MARKET DATA FEED CLASS (Rithmic TICKER_PLANT)
50
23
  // =============================================================================
51
24
 
52
25
  class MarketDataFeed extends EventEmitter {
53
26
  constructor(options = {}) {
54
27
  super();
55
28
 
56
- this.propfirmKey = (options.propfirm || 'topstep').toLowerCase().replace(/\s+/g, '_');
57
29
  this.connection = null;
58
30
  this.connected = false;
59
31
  this.subscriptions = new Set();
60
- this.reconnectAttempts = 0;
61
- this.maxReconnectAttempts = 5;
32
+ this.credentials = null;
33
+ this.config = null;
62
34
  }
63
35
 
64
36
  /**
65
- * Get market hub URL for propfirm
66
- * Pattern: api.xxx.com -> rtc.xxx.com
37
+ * Connect to Rithmic TICKER_PLANT
38
+ * @param {Object} rithmicCredentials - Credentials from RithmicService.getRithmicCredentials()
67
39
  */
68
- _getMarketHubUrl(propfirmKey) {
69
- const propfirm = PROPFIRMS[propfirmKey] || PROPFIRMS.topstep;
70
-
71
- if (propfirm.gatewayApi) {
72
- // Convert api.xxx.com to rtc.xxx.com
73
- const rtcHost = propfirm.gatewayApi.replace(/^api\./, 'rtc.');
74
- return `https://${rtcHost}/hubs/market`;
75
- }
76
-
77
- // Fallback for topstep
78
- return 'https://rtc.topstepx.com/hubs/market';
79
- }
80
-
81
- /**
82
- * Connect to market data hub
83
- */
84
- async connect(token, propfirmKey, contractId = null) {
40
+ async connect(rithmicCredentials) {
85
41
  if (this.connected) return;
86
42
 
87
- this.propfirmKey = propfirmKey || this.propfirmKey;
88
- this.token = token;
89
- const hubUrl = this._getMarketHubUrl(this.propfirmKey);
90
-
91
- // CRITICAL: Token must be in URL query string (same as HQX-TG and Python SDK)
92
- const urlWithToken = `${hubUrl}?access_token=${encodeURIComponent(this.token)}`;
93
-
94
- try {
95
- // CRITICAL: skipNegotiation=true + WebSockets transport is REQUIRED for ProjectX/TopstepX
96
- // This is how the Python SDK and HQX-TG connect successfully
97
- this.connection = new HubConnectionBuilder()
98
- .withUrl(urlWithToken, {
99
- skipNegotiation: true,
100
- transport: HttpTransportType.WebSockets
101
- })
102
- .withAutomaticReconnect({
103
- nextRetryDelayInMilliseconds: (ctx) => {
104
- if (ctx.previousRetryCount >= this.maxReconnectAttempts) return null;
105
- return Math.min(1000 * Math.pow(2, ctx.previousRetryCount), 30000);
106
- }
107
- })
108
- .configureLogging(LogLevel.Warning)
109
- .build();
110
-
111
- // Set server timeout and keepalive
112
- this.connection.serverTimeoutInMilliseconds = 60000; // 60s
113
- this.connection.keepAliveIntervalInMilliseconds = 15000; // 15s
114
-
115
- this._setupEventHandlers();
116
- await this.connection.start();
117
-
118
- this.connected = true;
119
- this.reconnectAttempts = 0;
120
- this.emit('connected');
121
-
122
- if (contractId) {
123
- await this.subscribe(null, contractId);
124
- }
125
- } catch (error) {
126
- this.connected = false;
127
- this.emit('error', error);
128
- throw error;
43
+ if (!rithmicCredentials || !rithmicCredentials.userId || !rithmicCredentials.password) {
44
+ throw new Error('Rithmic credentials required (userId, password, systemName, gateway)');
129
45
  }
130
- }
131
46
 
132
- /**
133
- * Setup SignalR event handlers
134
- */
135
- _setupEventHandlers() {
136
- if (!this.connection) return;
137
-
138
- // Quote updates - GatewayQuote receives (contractId, data)
139
- this.connection.on('GatewayQuote', (contractId, data) => {
140
- // Handle both (contractId, data) and single object formats
141
- const quote = data || contractId;
142
- const cid = data ? contractId : (quote.symbol || quote.symbolId);
143
-
144
- const tick = {
145
- type: 'quote',
146
- contractId: cid,
147
- symbol: quote.symbolName || quote.symbol || cid,
148
- price: quote.lastPrice,
149
- bid: quote.bestBid,
150
- ask: quote.bestAsk,
151
- change: quote.change,
152
- changePercent: quote.changePercent,
153
- open: quote.open,
154
- high: quote.high,
155
- low: quote.low,
156
- volume: quote.volume,
157
- timestamp: quote.timestamp ? new Date(quote.timestamp).getTime() : Date.now()
158
- };
159
- this.emit('tick', tick);
160
- this.emit('quote', tick);
161
- });
162
-
163
- // Trade executions - GatewayTrade receives (contractId, data[])
164
- this.connection.on('GatewayTrade', (contractId, trades) => {
165
- // Handle both formats
166
- const tradeList = Array.isArray(trades) ? trades : (Array.isArray(contractId) ? contractId : [trades || contractId]);
167
- const cid = typeof contractId === 'string' ? contractId : null;
168
-
169
- for (const trade of tradeList) {
170
- if (!trade) continue;
171
- const tick = {
172
- type: 'trade',
173
- contractId: cid || trade.symbolId,
174
- price: trade.price,
175
- volume: trade.volume,
176
- side: trade.type === 0 ? 'buy' : 'sell',
177
- lastTradeSide: trade.type === 0 ? 'buy' : 'sell',
178
- timestamp: trade.timestamp ? new Date(trade.timestamp).getTime() : Date.now()
179
- };
180
- this.emit('tick', tick);
181
- this.emit('trade', tick);
182
- }
183
- });
47
+ this.credentials = rithmicCredentials;
48
+ this.connection = new RithmicConnection();
184
49
 
185
- // DOM updates - GatewayDepth receives (contractId, data[])
186
- this.connection.on('GatewayDepth', (contractId, depthData) => {
187
- // Handle both formats
188
- const depthList = Array.isArray(depthData) ? depthData : (Array.isArray(contractId) ? contractId : [depthData || contractId]);
189
- const cid = typeof contractId === 'string' ? contractId : null;
190
-
191
- for (const depth of depthList) {
192
- if (!depth) continue;
193
- const domUpdate = {
194
- type: 'depth',
195
- contractId: cid,
196
- price: depth.price,
197
- volume: depth.volume || depth.totalVolume,
198
- currentVolume: depth.currentVolume,
199
- side: depth.type === 0 ? 'bid' : 'ask',
200
- timestamp: depth.timestamp ? new Date(depth.timestamp).getTime() : Date.now()
201
- };
202
- this.emit('depth', domUpdate);
203
- this.emit('dom', domUpdate);
204
- }
205
- });
206
-
207
- // Connection state
208
- this.connection.onreconnecting((error) => {
209
- this.connected = false;
210
- this.emit('reconnecting', error);
211
- });
212
-
213
- this.connection.onreconnected((connectionId) => {
214
- this.connected = true;
215
- this.reconnectAttempts = 0;
216
- this.emit('reconnected', connectionId);
217
- this._resubscribeAll();
218
- });
219
-
220
- this.connection.onclose((error) => {
221
- this.connected = false;
222
- // Emit detailed error for debugging
223
- let errMsg = 'unknown';
224
- if (error) {
225
- errMsg = error.message || error.toString();
226
- if (error.stack) errMsg += ' | ' + error.stack.split('\n')[0];
227
- }
228
- this.emit('disconnected', new Error(errMsg));
229
- });
50
+ this.config = {
51
+ uri: rithmicCredentials.gateway || RITHMIC_ENDPOINTS.CHICAGO,
52
+ systemName: rithmicCredentials.systemName || RITHMIC_SYSTEMS.PAPER,
53
+ userId: rithmicCredentials.userId,
54
+ password: rithmicCredentials.password,
55
+ appName: 'HQX-CLI',
56
+ appVersion: '2.0.0',
57
+ };
58
+
59
+ try {
60
+ await this.connection.connect(this.config);
61
+
62
+ // Setup message handler for market data
63
+ this.connection.on('message', (msg) => this._handleMessage(msg));
64
+
65
+ // Login to TICKER_PLANT
66
+ return new Promise((resolve, reject) => {
67
+ const timeout = setTimeout(() => {
68
+ reject(new Error('TICKER_PLANT login timeout'));
69
+ }, 15000);
70
+
71
+ this.connection.once('loggedIn', () => {
72
+ clearTimeout(timeout);
73
+ this.connected = true;
74
+ this.emit('connected');
75
+ resolve(true);
76
+ });
77
+
78
+ this.connection.once('loginFailed', (data) => {
79
+ clearTimeout(timeout);
80
+ reject(new Error(data.message || 'TICKER_PLANT login failed'));
81
+ });
82
+
83
+ this.connection.login('TICKER_PLANT');
84
+ });
85
+ } catch (e) {
86
+ this.emit('error', e);
87
+ throw e;
88
+ }
230
89
  }
231
90
 
232
91
  /**
233
- * Subscribe to contract market data
92
+ * Subscribe to market data for a symbol
93
+ * @param {string} symbol - Symbol name (e.g., 'ESH6')
94
+ * @param {string} exchange - Exchange (default: 'CME')
234
95
  */
235
- async subscribe(symbol, contractId) {
236
- if (!this.connection || !this.connected) {
237
- throw new Error('Not connected');
96
+ async subscribe(symbol, exchange = 'CME') {
97
+ if (!this.connected) {
98
+ throw new Error('Not connected to TICKER_PLANT');
238
99
  }
239
100
 
240
- const id = contractId || symbol;
241
-
101
+ const key = `${symbol}:${exchange}`;
102
+ if (this.subscriptions.has(key)) return;
103
+
242
104
  try {
243
- await this.connection.invoke('SubscribeContractQuotes', id);
244
- await this.connection.invoke('SubscribeContractTrades', id);
245
- await this.connection.invoke('SubscribeContractMarketDepth', id);
246
- this.subscriptions.add(id);
247
- this.emit('subscribed', { symbol, contractId: id });
248
- } catch (error) {
249
- this.emit('error', new Error(`Subscribe failed: ${error.message}`));
250
- throw error;
105
+ // Subscribe to LAST_TRADE and BBO (Best Bid/Offer)
106
+ // UpdateBits: 1 = LAST_TRADE, 2 = BBO, 3 = BOTH
107
+ this.connection.send('RequestMarketDataUpdate', {
108
+ templateId: REQ.MARKET_DATA,
109
+ symbol: symbol,
110
+ exchange: exchange,
111
+ request: 1, // SUBSCRIBE
112
+ updateBits: 3, // LAST_TRADE + BBO
113
+ });
114
+
115
+ this.subscriptions.add(key);
116
+ } catch (e) {
117
+ this.emit('error', e);
118
+ throw e;
251
119
  }
252
120
  }
253
121
 
254
122
  /**
255
- * Unsubscribe from contract
123
+ * Unsubscribe from market data for a symbol
256
124
  */
257
- async unsubscribe(contractId) {
258
- if (!this.connection || !this.connected) return;
125
+ async unsubscribe(symbol, exchange = 'CME') {
126
+ if (!this.connected) return;
127
+
128
+ const key = `${symbol}:${exchange}`;
129
+ if (!this.subscriptions.has(key)) return;
259
130
 
260
131
  try {
261
- await this.connection.invoke('UnsubscribeContractQuotes', contractId);
262
- await this.connection.invoke('UnsubscribeContractTrades', contractId);
263
- await this.connection.invoke('UnsubscribeContractMarketDepth', contractId);
264
- this.subscriptions.delete(contractId);
265
- this.emit('unsubscribed', { contractId });
266
- } catch (error) {
267
- // Silently handle
132
+ this.connection.send('RequestMarketDataUpdate', {
133
+ templateId: REQ.MARKET_DATA,
134
+ symbol: symbol,
135
+ exchange: exchange,
136
+ request: 2, // UNSUBSCRIBE
137
+ });
138
+
139
+ this.subscriptions.delete(key);
140
+ } catch (e) {
141
+ // Ignore unsubscribe errors
268
142
  }
269
143
  }
270
144
 
271
145
  /**
272
- * Resubscribe after reconnect
146
+ * Disconnect from TICKER_PLANT
273
147
  */
274
- async _resubscribeAll() {
275
- for (const contractId of this.subscriptions) {
148
+ async disconnect() {
149
+ // Unsubscribe from all
150
+ for (const key of this.subscriptions) {
151
+ const [symbol, exchange] = key.split(':');
152
+ await this.unsubscribe(symbol, exchange);
153
+ }
154
+
155
+ if (this.connection) {
276
156
  try {
277
- await this.connection.invoke('SubscribeContractQuotes', contractId);
278
- await this.connection.invoke('SubscribeContractTrades', contractId);
279
- await this.connection.invoke('SubscribeContractMarketDepth', contractId);
280
- } catch (error) {
281
- // Continue
157
+ await this.connection.disconnect();
158
+ } catch (e) {
159
+ // Ignore
282
160
  }
283
161
  }
162
+
163
+ this.connection = null;
164
+ this.connected = false;
165
+ this.subscriptions.clear();
166
+ this.emit('disconnected');
284
167
  }
285
168
 
286
169
  /**
287
- * Disconnect with timeout to prevent hanging
170
+ * Handle incoming messages from TICKER_PLANT
288
171
  */
289
- async disconnect() {
290
- if (this.connection) {
291
- const timeoutPromise = new Promise(r => setTimeout(r, 3000));
292
-
293
- try {
294
- // Race between disconnect and timeout
295
- await Promise.race([
296
- (async () => {
297
- for (const contractId of this.subscriptions) {
298
- try { await this.unsubscribe(contractId); } catch {}
299
- }
300
- await this.connection.stop();
301
- })(),
302
- timeoutPromise
303
- ]);
304
- } catch (error) {
305
- // Ignore disconnect errors
306
- }
307
-
308
- this.connection = null;
309
- this.connected = false;
310
- this.subscriptions.clear();
172
+ _handleMessage(msg) {
173
+ const { templateId, data } = msg;
174
+
175
+ switch (templateId) {
176
+ case RES.MARKET_DATA:
177
+ // Subscription confirmed
178
+ break;
179
+
180
+ case STREAM.LAST_TRADE:
181
+ this._handleLastTrade(data);
182
+ break;
183
+
184
+ case STREAM.BBO:
185
+ this._handleBBO(data);
186
+ break;
187
+
188
+ default:
189
+ // Ignore other messages
190
+ break;
311
191
  }
312
192
  }
313
193
 
314
194
  /**
315
- * Check connection status
195
+ * Handle LastTrade message
316
196
  */
317
- isConnected() {
318
- return this.connected && this.connection?.state === 'Connected';
197
+ _handleLastTrade(data) {
198
+ try {
199
+ const trade = proto.decode('LastTrade', data);
200
+
201
+ const tick = {
202
+ type: 'trade',
203
+ symbol: trade.symbol,
204
+ exchange: trade.exchange,
205
+ price: trade.tradePrice,
206
+ size: trade.tradeSize,
207
+ volume: trade.volume,
208
+ side: trade.aggressor === 1 ? 'buy' : trade.aggressor === 2 ? 'sell' : 'unknown',
209
+ timestamp: Date.now(),
210
+ ssboe: trade.ssboe,
211
+ usecs: trade.usecs,
212
+ };
213
+
214
+ this.emit('tick', tick);
215
+ } catch (e) {
216
+ // Ignore decode errors
217
+ }
319
218
  }
320
219
 
321
220
  /**
322
- * Get active subscriptions
221
+ * Handle BestBidOffer message
323
222
  */
324
- getSubscriptions() {
325
- return Array.from(this.subscriptions);
223
+ _handleBBO(data) {
224
+ try {
225
+ const bbo = proto.decode('BestBidOffer', data);
226
+
227
+ const tick = {
228
+ type: 'quote',
229
+ symbol: bbo.symbol,
230
+ exchange: bbo.exchange,
231
+ bid: bbo.bidPrice,
232
+ bidSize: bbo.bidSize,
233
+ ask: bbo.askPrice,
234
+ askSize: bbo.askSize,
235
+ price: bbo.bidPrice && bbo.askPrice ? (bbo.bidPrice + bbo.askPrice) / 2 : null,
236
+ timestamp: Date.now(),
237
+ ssboe: bbo.ssboe,
238
+ usecs: bbo.usecs,
239
+ };
240
+
241
+ this.emit('tick', tick);
242
+ } catch (e) {
243
+ // Ignore decode errors
244
+ }
326
245
  }
327
246
  }
328
247
 
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
- // Load compiled bytecode (prod) or private sources (dev)
2
+ // Load obfuscated (prod) or private sources (dev)
3
3
  try {
4
- require('bytenode');
5
- module.exports = require('../../../dist/lib/m/hqx-2b.jsc');
4
+ module.exports = require('../../../dist/lib/m/hqx-2b.js');
6
5
  } catch (e) {
7
6
  module.exports = require('../../../private/strategies/hqx-2b-liquidity-sweep');
8
7
  }
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
- // Load compiled bytecode (prod) or private sources (dev)
2
+ // Load obfuscated (prod) or private sources (dev)
3
3
  try {
4
- require('bytenode');
5
- module.exports = require('../../../dist/lib/m/ultra-scalping.jsc');
4
+ module.exports = require('../../../dist/lib/m/ultra-scalping.js');
6
5
  } catch (e) {
7
6
  module.exports = require('../../../private/strategies/ultra-scalping');
8
7
  }
@@ -13,7 +13,7 @@ const { SupervisionEngine } = require('../../services/ai-supervision');
13
13
  /**
14
14
  * Execute algo strategy with market data
15
15
  * @param {Object} params - Execution parameters
16
- * @param {Object} params.service - Trading service (Rithmic/ProjectX)
16
+ * @param {Object} params.service - Rithmic trading service
17
17
  * @param {Object} params.account - Account object
18
18
  * @param {Object} params.contract - Contract object
19
19
  * @param {Object} params.config - Algo config (contracts, target, risk, showName)
@@ -77,8 +77,8 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
77
77
  const strategy = new StrategyClass({ tickSize });
78
78
  strategy.initialize(contractId, tickSize);
79
79
 
80
- // Initialize Market Data Feed
81
- const marketFeed = new MarketDataFeed({ propfirm: account.propfirm });
80
+ // Initialize Market Data Feed (Rithmic TICKER_PLANT)
81
+ const marketFeed = new MarketDataFeed();
82
82
 
83
83
  // Log startup
84
84
  ui.addLog('info', `Strategy: ${strategyName}${supervisionEnabled ? ' + AI' : ''}`);
@@ -207,12 +207,14 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
207
207
  marketFeed.on('error', (err) => ui.addLog('error', `Market: ${err.message}`));
208
208
  marketFeed.on('disconnected', () => { stats.connected = false; ui.addLog('error', 'Market disconnected'); });
209
209
 
210
- // Connect to market data
210
+ // Connect to market data (Rithmic TICKER_PLANT)
211
211
  try {
212
- const token = service.token || service.getToken?.();
213
- const propfirmKey = (account.propfirm || 'topstep').toLowerCase().replace(/\s+/g, '_');
214
- await marketFeed.connect(token, propfirmKey, contractId);
215
- await marketFeed.subscribe(symbolName, contractId);
212
+ const rithmicCredentials = service.getRithmicCredentials?.();
213
+ if (!rithmicCredentials) {
214
+ throw new Error('Rithmic credentials not available');
215
+ }
216
+ await marketFeed.connect(rithmicCredentials);
217
+ await marketFeed.subscribe(symbolName, contract.exchange || 'CME');
216
218
  } catch (e) {
217
219
  ui.addLog('error', `Failed to connect: ${e.message}`);
218
220
  }
@@ -77,8 +77,8 @@ const launchCopyTrading = async (config) => {
77
77
  const strategy = new StrategyClass({ tickSize });
78
78
  strategy.initialize(contractId, tickSize);
79
79
 
80
- // Initialize Market Data Feed
81
- const marketFeed = new MarketDataFeed({ propfirm: leadAccount.propfirm });
80
+ // Initialize Market Data Feed (Rithmic TICKER_PLANT)
81
+ const marketFeed = new MarketDataFeed();
82
82
 
83
83
  // Log startup
84
84
  ui.addLog('info', `Lead: ${leadName} | Followers: ${followers.length}`);
@@ -186,12 +186,14 @@ const launchCopyTrading = async (config) => {
186
186
  marketFeed.on('error', (err) => ui.addLog('error', `Market: ${err.message}`));
187
187
  marketFeed.on('disconnected', () => { stats.connected = false; ui.addLog('error', 'Disconnected'); });
188
188
 
189
- // Connect to market data
189
+ // Connect to market data (Rithmic TICKER_PLANT)
190
190
  try {
191
- const token = leadService.token || leadService.getToken?.();
192
- const pk = (leadAccount.propfirm || 'topstep').toLowerCase().replace(/\s+/g, '_');
193
- await marketFeed.connect(token, pk, contractId);
194
- await marketFeed.subscribe(symbolName, contractId);
191
+ const rithmicCredentials = leadService.getRithmicCredentials?.();
192
+ if (!rithmicCredentials) {
193
+ throw new Error('Rithmic credentials not available');
194
+ }
195
+ await marketFeed.connect(rithmicCredentials);
196
+ await marketFeed.subscribe(symbolName, contract.exchange || 'CME');
195
197
  } catch (e) {
196
198
  ui.addLog('error', `Connect failed: ${e.message}`);
197
199
  }
@@ -40,7 +40,7 @@ const copyTradingMenu = async () => {
40
40
  return;
41
41
  }
42
42
 
43
- // Filter active accounts: status === 0 (ProjectX) OR status === 'active' (Rithmic) OR no status
43
+ // Filter active accounts: status === 'active' (Rithmic) OR status === 0 OR no status
44
44
  const activeAccounts = allAccounts.filter(acc =>
45
45
  acc.status === 0 || acc.status === 'active' || acc.status === undefined || acc.status === null
46
46
  );
@@ -46,7 +46,7 @@ const customStrategyMenu = async (service) => {
46
46
 
47
47
  if (!allAccounts?.length) { spinner.fail('No accounts found'); await prompts.waitForEnter(); return; }
48
48
 
49
- // Filter active accounts: status === 0 (ProjectX) OR status === 'active' (Rithmic) OR no status
49
+ // Filter active accounts: status === 'active' (Rithmic) OR status === 0 OR no status
50
50
  const activeAccounts = allAccounts.filter(acc =>
51
51
  acc.status === 0 || acc.status === 'active' || acc.status === undefined || acc.status === null
52
52
  );
@@ -41,7 +41,7 @@ const oneAccountMenu = async (service) => {
41
41
  return;
42
42
  }
43
43
 
44
- // Filter active accounts: status === 0 (ProjectX) OR status === 'active' (Rithmic) OR no status
44
+ // Filter active accounts: status === 'active' (Rithmic) OR status === 0 OR no status
45
45
  const activeAccounts = allAccounts.filter(acc =>
46
46
  acc.status === 0 || acc.status === 'active' || acc.status === undefined || acc.status === null
47
47
  );