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.
- package/dist/lib/m/hqx-2b.js +1 -0
- package/dist/lib/m/ultra-scalping.js +1 -0
- package/package.json +2 -1
- package/src/app.js +1 -1
- package/src/config/propfirms.js +1 -8
- package/src/lib/data.js +175 -256
- package/src/lib/m/hqx-2b.js +2 -3
- package/src/lib/m/ultra-scalping.js +2 -3
- package/src/pages/algo/algo-executor.js +10 -8
- package/src/pages/algo/copy-executor.js +9 -7
- package/src/pages/algo/copy-trading.js +1 -1
- package/src/pages/algo/custom-strategy.js +1 -1
- package/src/pages/algo/one-account.js +1 -1
|
@@ -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.
|
|
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 ===
|
|
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
|
);
|
package/src/config/propfirms.js
CHANGED
|
@@ -15,14 +15,7 @@ const PROPFIRMS = {
|
|
|
15
15
|
rithmicSystem: 'Apex',
|
|
16
16
|
wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443',
|
|
17
17
|
},
|
|
18
|
-
|
|
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 -
|
|
3
|
+
* MARKET DATA FEED - Rithmic TICKER_PLANT Real-Time Data
|
|
4
4
|
* =============================================================================
|
|
5
|
-
* Connects to
|
|
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 {
|
|
23
|
-
|
|
24
|
-
|
|
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.
|
|
61
|
-
this.
|
|
32
|
+
this.credentials = null;
|
|
33
|
+
this.config = null;
|
|
62
34
|
}
|
|
63
35
|
|
|
64
36
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
37
|
+
* Connect to Rithmic TICKER_PLANT
|
|
38
|
+
* @param {Object} rithmicCredentials - Credentials from RithmicService.getRithmicCredentials()
|
|
67
39
|
*/
|
|
68
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
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,
|
|
236
|
-
if (!this.
|
|
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
|
|
241
|
-
|
|
101
|
+
const key = `${symbol}:${exchange}`;
|
|
102
|
+
if (this.subscriptions.has(key)) return;
|
|
103
|
+
|
|
242
104
|
try {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
|
123
|
+
* Unsubscribe from market data for a symbol
|
|
256
124
|
*/
|
|
257
|
-
async unsubscribe(
|
|
258
|
-
if (!this.
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
*
|
|
146
|
+
* Disconnect from TICKER_PLANT
|
|
273
147
|
*/
|
|
274
|
-
async
|
|
275
|
-
|
|
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.
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
*
|
|
170
|
+
* Handle incoming messages from TICKER_PLANT
|
|
288
171
|
*/
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
*
|
|
195
|
+
* Handle LastTrade message
|
|
316
196
|
*/
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
*
|
|
221
|
+
* Handle BestBidOffer message
|
|
323
222
|
*/
|
|
324
|
-
|
|
325
|
-
|
|
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
|
|
package/src/lib/m/hqx-2b.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
// Load
|
|
2
|
+
// Load obfuscated (prod) or private sources (dev)
|
|
3
3
|
try {
|
|
4
|
-
require('
|
|
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
|
|
2
|
+
// Load obfuscated (prod) or private sources (dev)
|
|
3
3
|
try {
|
|
4
|
-
require('
|
|
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 -
|
|
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(
|
|
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
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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(
|
|
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
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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 ===
|
|
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 ===
|
|
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 ===
|
|
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
|
);
|