hedgequantx 2.6.163 → 2.7.0

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.
Files changed (146) hide show
  1. package/README.md +15 -88
  2. package/bin/cli.js +0 -11
  3. package/dist/lib/api.jsc +0 -0
  4. package/dist/lib/api2.jsc +0 -0
  5. package/dist/lib/core.jsc +0 -0
  6. package/dist/lib/core2.jsc +0 -0
  7. package/dist/lib/data.js +1 -1
  8. package/dist/lib/data.jsc +0 -0
  9. package/dist/lib/data2.jsc +0 -0
  10. package/dist/lib/decoder.jsc +0 -0
  11. package/dist/lib/m/mod1.jsc +0 -0
  12. package/dist/lib/m/mod2.jsc +0 -0
  13. package/dist/lib/n/r1.jsc +0 -0
  14. package/dist/lib/n/r2.jsc +0 -0
  15. package/dist/lib/n/r3.jsc +0 -0
  16. package/dist/lib/n/r4.jsc +0 -0
  17. package/dist/lib/n/r5.jsc +0 -0
  18. package/dist/lib/n/r6.jsc +0 -0
  19. package/dist/lib/n/r7.jsc +0 -0
  20. package/dist/lib/o/util1.jsc +0 -0
  21. package/dist/lib/o/util2.jsc +0 -0
  22. package/package.json +6 -3
  23. package/src/app.js +40 -162
  24. package/src/config/constants.js +31 -33
  25. package/src/config/propfirms.js +13 -217
  26. package/src/config/settings.js +0 -43
  27. package/src/lib/api.js +198 -0
  28. package/src/lib/api2.js +353 -0
  29. package/src/lib/core.js +539 -0
  30. package/src/lib/core2.js +341 -0
  31. package/src/lib/data.js +555 -0
  32. package/src/lib/data2.js +492 -0
  33. package/src/lib/decoder.js +599 -0
  34. package/src/lib/m/s1.js +804 -0
  35. package/src/lib/m/s2.js +34 -0
  36. package/src/lib/n/r1.js +454 -0
  37. package/src/lib/n/r2.js +514 -0
  38. package/src/lib/n/r3.js +631 -0
  39. package/src/lib/n/r4.js +401 -0
  40. package/src/lib/n/r5.js +335 -0
  41. package/src/lib/n/r6.js +425 -0
  42. package/src/lib/n/r7.js +530 -0
  43. package/src/lib/o/l1.js +44 -0
  44. package/src/lib/o/l2.js +427 -0
  45. package/src/lib/python-bridge.js +206 -0
  46. package/src/menus/connect.js +14 -176
  47. package/src/menus/dashboard.js +65 -110
  48. package/src/pages/accounts.js +18 -18
  49. package/src/pages/algo/copy-trading.js +210 -240
  50. package/src/pages/algo/index.js +41 -104
  51. package/src/pages/algo/one-account.js +386 -33
  52. package/src/pages/algo/ui.js +312 -151
  53. package/src/pages/orders.js +3 -3
  54. package/src/pages/positions.js +3 -3
  55. package/src/pages/stats/chart.js +74 -0
  56. package/src/pages/stats/display.js +228 -0
  57. package/src/pages/stats/index.js +236 -0
  58. package/src/pages/stats/metrics.js +213 -0
  59. package/src/pages/user.js +6 -6
  60. package/src/services/hqx-server/constants.js +55 -0
  61. package/src/services/hqx-server/index.js +401 -0
  62. package/src/services/hqx-server/latency.js +81 -0
  63. package/src/services/index.js +12 -3
  64. package/src/services/rithmic/accounts.js +7 -32
  65. package/src/services/rithmic/connection.js +1 -204
  66. package/src/services/rithmic/contracts.js +116 -99
  67. package/src/services/rithmic/handlers.js +21 -196
  68. package/src/services/rithmic/index.js +63 -120
  69. package/src/services/rithmic/market.js +31 -0
  70. package/src/services/rithmic/orders.js +5 -111
  71. package/src/services/rithmic/protobuf.js +384 -138
  72. package/src/services/session.js +22 -173
  73. package/src/ui/box.js +10 -18
  74. package/src/ui/index.js +1 -3
  75. package/src/ui/menu.js +1 -1
  76. package/src/utils/prompts.js +2 -2
  77. package/dist/lib/m/s1.js +0 -1
  78. package/src/menus/ai-agent-connect.js +0 -181
  79. package/src/menus/ai-agent-models.js +0 -219
  80. package/src/menus/ai-agent-oauth.js +0 -292
  81. package/src/menus/ai-agent-ui.js +0 -141
  82. package/src/menus/ai-agent.js +0 -484
  83. package/src/pages/algo/algo-config.js +0 -195
  84. package/src/pages/algo/algo-multi.js +0 -801
  85. package/src/pages/algo/algo-utils.js +0 -58
  86. package/src/pages/algo/copy-engine.js +0 -449
  87. package/src/pages/algo/custom-strategy.js +0 -459
  88. package/src/pages/algo/logger.js +0 -245
  89. package/src/pages/algo/smart-logs-data.js +0 -218
  90. package/src/pages/algo/smart-logs.js +0 -387
  91. package/src/pages/algo/ui-constants.js +0 -144
  92. package/src/pages/algo/ui-summary.js +0 -184
  93. package/src/pages/stats-calculations.js +0 -191
  94. package/src/pages/stats-ui.js +0 -381
  95. package/src/pages/stats.js +0 -339
  96. package/src/services/ai/client-analysis.js +0 -194
  97. package/src/services/ai/client-models.js +0 -333
  98. package/src/services/ai/client.js +0 -343
  99. package/src/services/ai/index.js +0 -384
  100. package/src/services/ai/oauth-anthropic.js +0 -265
  101. package/src/services/ai/oauth-gemini.js +0 -223
  102. package/src/services/ai/oauth-iflow.js +0 -269
  103. package/src/services/ai/oauth-openai.js +0 -233
  104. package/src/services/ai/oauth-qwen.js +0 -279
  105. package/src/services/ai/providers/direct-providers.js +0 -323
  106. package/src/services/ai/providers/index.js +0 -62
  107. package/src/services/ai/providers/other-providers.js +0 -104
  108. package/src/services/ai/proxy-install.js +0 -249
  109. package/src/services/ai/proxy-manager.js +0 -494
  110. package/src/services/ai/proxy-remote.js +0 -161
  111. package/src/services/ai/strategy-supervisor.js +0 -1312
  112. package/src/services/ai/supervisor-data.js +0 -195
  113. package/src/services/ai/supervisor-optimize.js +0 -215
  114. package/src/services/ai/supervisor-sync.js +0 -178
  115. package/src/services/ai/supervisor-utils.js +0 -158
  116. package/src/services/ai/supervisor.js +0 -484
  117. package/src/services/ai/validation.js +0 -250
  118. package/src/services/hqx-server-events.js +0 -110
  119. package/src/services/hqx-server-handlers.js +0 -217
  120. package/src/services/hqx-server-latency.js +0 -136
  121. package/src/services/hqx-server.js +0 -403
  122. package/src/services/position-constants.js +0 -28
  123. package/src/services/position-exit-logic.js +0 -174
  124. package/src/services/position-manager.js +0 -438
  125. package/src/services/position-momentum.js +0 -206
  126. package/src/services/projectx/accounts.js +0 -142
  127. package/src/services/projectx/index.js +0 -443
  128. package/src/services/projectx/market.js +0 -172
  129. package/src/services/projectx/stats.js +0 -110
  130. package/src/services/projectx/trading.js +0 -180
  131. package/src/services/rithmic/latency-tracker.js +0 -182
  132. package/src/services/rithmic/market-data-decoders.js +0 -229
  133. package/src/services/rithmic/market-data.js +0 -272
  134. package/src/services/rithmic/orders-fast.js +0 -246
  135. package/src/services/rithmic/proto-decoders.js +0 -403
  136. package/src/services/rithmic/specs.js +0 -146
  137. package/src/services/rithmic/trade-history.js +0 -254
  138. package/src/services/session-history.js +0 -475
  139. package/src/services/strategy/hft-signal-calc.js +0 -147
  140. package/src/services/strategy/hft-tick.js +0 -407
  141. package/src/services/strategy/recovery-math.js +0 -402
  142. package/src/services/tradovate/constants.js +0 -109
  143. package/src/services/tradovate/index.js +0 -392
  144. package/src/services/tradovate/market.js +0 -47
  145. package/src/services/tradovate/orders.js +0 -145
  146. package/src/services/tradovate/websocket.js +0 -97
@@ -1,194 +1,12 @@
1
1
  /**
2
- * @fileoverview PropFirm API Configurations - Synced with Admin Dashboard
2
+ * @fileoverview PropFirm API Configurations - Rithmic Only
3
3
  * @module config/propfirms
4
4
  */
5
5
 
6
6
  /**
7
- * PropFirm configurations
8
- * Synced with: /root/HQX-Dev/hqx_tg/src/propfirms/config.ts
7
+ * PropFirm configurations (Rithmic platform only)
9
8
  */
10
9
  const PROPFIRMS = {
11
- // ==================== ProjectX Platform ====================
12
- topstep: {
13
- id: 'topstepx',
14
- name: 'TopStep',
15
- displayName: 'TopStep',
16
- platform: 'ProjectX',
17
- userApi: 'userapi.topstepx.com',
18
- gatewayApi: 'api.topstepx.com'
19
- },
20
- alpha_futures: {
21
- id: 'alphafutures',
22
- name: 'Alpha Futures',
23
- displayName: 'Alpha Futures',
24
- platform: 'ProjectX',
25
- userApi: 'userapi.alphafutures.projectx.com',
26
- gatewayApi: 'api.alphafutures.projectx.com'
27
- },
28
- tickticktrader: {
29
- id: 'tickticktrader',
30
- name: 'TickTickTrader',
31
- displayName: 'TickTickTrader',
32
- platform: 'ProjectX',
33
- userApi: 'userapi.tickticktrader.projectx.com',
34
- gatewayApi: 'api.tickticktrader.projectx.com'
35
- },
36
- bulenox: {
37
- id: 'bulenox',
38
- name: 'Bulenox',
39
- displayName: 'Bulenox',
40
- platform: 'ProjectX',
41
- userApi: 'userapi.bulenox.projectx.com',
42
- gatewayApi: 'api.bulenox.projectx.com'
43
- },
44
- tradeday: {
45
- id: 'tradeday',
46
- name: 'TradeDay',
47
- displayName: 'TradeDay',
48
- platform: 'ProjectX',
49
- userApi: 'userapi.tradeday.projectx.com',
50
- gatewayApi: 'api.tradeday.projectx.com'
51
- },
52
- blusky: {
53
- id: 'blusky',
54
- name: 'Blusky',
55
- displayName: 'Blusky',
56
- platform: 'ProjectX',
57
- userApi: 'userapi.blusky.projectx.com',
58
- gatewayApi: 'api.blusky.projectx.com'
59
- },
60
- goat_futures: {
61
- id: 'goatfutures',
62
- name: 'Goat Futures',
63
- displayName: 'Goat Futures',
64
- platform: 'ProjectX',
65
- userApi: 'userapi.goatfutures.projectx.com',
66
- gatewayApi: 'api.goatfutures.projectx.com'
67
- },
68
- futures_desk: {
69
- id: 'thefuturesdesk',
70
- name: 'The Futures Desk',
71
- displayName: 'The Futures Desk',
72
- platform: 'ProjectX',
73
- userApi: 'userapi.thefuturesdesk.projectx.com',
74
- gatewayApi: 'api.thefuturesdesk.projectx.com'
75
- },
76
- daytraders: {
77
- id: 'daytraders',
78
- name: 'DayTraders',
79
- displayName: 'DayTraders',
80
- platform: 'ProjectX',
81
- userApi: 'userapi.daytraders.projectx.com',
82
- gatewayApi: 'api.daytraders.projectx.com'
83
- },
84
- e8_futures: {
85
- id: 'e8futures',
86
- name: 'E8 Futures',
87
- displayName: 'E8 Futures',
88
- platform: 'ProjectX',
89
- userApi: 'userapi.e8futures.projectx.com',
90
- gatewayApi: 'api.e8futures.projectx.com'
91
- },
92
- blue_guardian: {
93
- id: 'blueguardianfutures',
94
- name: 'Blue Guardian Futures',
95
- displayName: 'Blue Guardian Futures',
96
- platform: 'ProjectX',
97
- userApi: 'userapi.blueguardianfutures.projectx.com',
98
- gatewayApi: 'api.blueguardianfutures.projectx.com'
99
- },
100
- futures_elite: {
101
- id: 'futureselite',
102
- name: 'FuturesElite',
103
- displayName: 'FuturesElite',
104
- platform: 'ProjectX',
105
- userApi: 'userapi.futureselite.projectx.com',
106
- gatewayApi: 'api.futureselite.projectx.com'
107
- },
108
- fxify: {
109
- id: 'fxify',
110
- name: 'FXIFY',
111
- displayName: 'FXIFY',
112
- platform: 'ProjectX',
113
- userApi: 'userapi.fxify.projectx.com',
114
- gatewayApi: 'api.fxify.projectx.com'
115
- },
116
- hola_prime: {
117
- id: 'holaprime',
118
- name: 'Hola Prime',
119
- displayName: 'Hola Prime',
120
- platform: 'ProjectX',
121
- userApi: 'userapi.holaprime.projectx.com',
122
- gatewayApi: 'api.holaprime.projectx.com'
123
- },
124
- top_one_futures: {
125
- id: 'toponefutures',
126
- name: 'Top One Futures',
127
- displayName: 'Top One Futures',
128
- platform: 'ProjectX',
129
- userApi: 'userapi.toponefutures.projectx.com',
130
- gatewayApi: 'api.toponefutures.projectx.com'
131
- },
132
- funding_futures: {
133
- id: 'fundingfutures',
134
- name: 'Funding Futures',
135
- displayName: 'Funding Futures',
136
- platform: 'ProjectX',
137
- userApi: 'userapi.fundingfutures.projectx.com',
138
- gatewayApi: 'api.fundingfutures.projectx.com'
139
- },
140
- tx3_funding: {
141
- id: 'tx3funding',
142
- name: 'TX3 Funding',
143
- displayName: 'TX3 Funding',
144
- platform: 'ProjectX',
145
- userApi: 'userapi.tx3funding.projectx.com',
146
- gatewayApi: 'api.tx3funding.projectx.com'
147
- },
148
- lucid_trading: {
149
- id: 'lucidtrading',
150
- name: 'Lucid Trading',
151
- displayName: 'Lucid Trading',
152
- platform: 'ProjectX',
153
- userApi: 'userapi.lucidtrading.projectx.com',
154
- gatewayApi: 'api.lucidtrading.projectx.com'
155
- },
156
- tradeify: {
157
- id: 'tradeify',
158
- name: 'Tradeify',
159
- displayName: 'Tradeify',
160
- platform: 'ProjectX',
161
- userApi: 'userapi.tradeify.projectx.com',
162
- gatewayApi: 'api.tradeify.projectx.com'
163
- },
164
-
165
- // ==================== Tradovate Platform ====================
166
- apex_tradovate: {
167
- id: 'apex',
168
- name: 'Apex',
169
- displayName: 'Apex (Tradovate)',
170
- platform: 'Tradovate',
171
- userApi: 'userapi.apex.tradovate.com',
172
- gatewayApi: 'api.apex.tradovate.com'
173
- },
174
- takeprofittrader: {
175
- id: 'takeprofittrader',
176
- name: 'TakeProfitTrader',
177
- displayName: 'TakeProfitTrader',
178
- platform: 'Tradovate',
179
- userApi: 'userapi.takeprofittrader.tradovate.com',
180
- gatewayApi: 'api.takeprofittrader.tradovate.com'
181
- },
182
- myfundedfutures: {
183
- id: 'myfundedfutures',
184
- name: 'MyFundedFutures',
185
- displayName: 'MyFundedFutures',
186
- platform: 'Tradovate',
187
- userApi: 'live.tradovateapi.com',
188
- gatewayApi: 'live.tradovateapi.com'
189
- },
190
-
191
- // ==================== Rithmic Platform ====================
192
10
  apex_rithmic: {
193
11
  id: 'rithmic-apex',
194
12
  name: 'Apex',
@@ -196,7 +14,6 @@ const PROPFIRMS = {
196
14
  platform: 'Rithmic',
197
15
  rithmicSystem: 'Apex',
198
16
  wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443',
199
-
200
17
  },
201
18
  topsteptrader: {
202
19
  id: 'topsteptrader',
@@ -265,7 +82,7 @@ const PROPFIRMS = {
265
82
  daytraders_rithmic: {
266
83
  id: 'rithmic-daytraders',
267
84
  name: 'DayTraders.com',
268
- displayName: 'DayTraders.com (Rithmic)',
85
+ displayName: 'DayTraders.com',
269
86
  platform: 'Rithmic',
270
87
  rithmicSystem: 'DayTraders.com',
271
88
  wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443'
@@ -281,7 +98,7 @@ const PROPFIRMS = {
281
98
  lucidtrading_rithmic: {
282
99
  id: 'rithmic-lucidtrading',
283
100
  name: 'LucidTrading',
284
- displayName: 'LucidTrading (Rithmic)',
101
+ displayName: 'LucidTrading',
285
102
  platform: 'Rithmic',
286
103
  rithmicSystem: 'LucidTrading',
287
104
  wsEndpoint: 'wss://ritpa11120.11.rithmic.com:443'
@@ -321,50 +138,29 @@ const PROPFIRMS = {
321
138
  };
322
139
 
323
140
  /**
324
- * PropFirm choices for menus (grouped by platform)
141
+ * PropFirm choices for menus
325
142
  */
326
- const PROPFIRM_CHOICES = {
327
- projectx: Object.entries(PROPFIRMS)
328
- .filter(([_, v]) => v.platform === 'ProjectX')
329
- .map(([key, val]) => ({ name: val.displayName, value: key })),
330
-
331
- tradovate: Object.entries(PROPFIRMS)
332
- .filter(([_, v]) => v.platform === 'Tradovate')
333
- .map(([key, val]) => ({ name: val.displayName, value: key })),
334
-
335
- rithmic: Object.entries(PROPFIRMS)
336
- .filter(([_, v]) => v.platform === 'Rithmic')
337
- .map(([key, val]) => ({ name: val.displayName, value: key })),
338
-
339
- all: Object.entries(PROPFIRMS)
340
- .map(([key, val]) => ({ name: `${val.displayName} (${val.platform})`, value: key }))
341
- };
143
+ const PROPFIRM_CHOICES = Object.entries(PROPFIRMS)
144
+ .map(([key, val]) => ({ name: val.displayName, value: key }))
145
+ .sort((a, b) => a.name.localeCompare(b.name));
342
146
 
343
147
  /**
344
148
  * Gets a PropFirm by key
345
- * @param {string} key - PropFirm key
346
- * @returns {Object|undefined} PropFirm config
347
149
  */
348
150
  const getPropFirm = (key) => PROPFIRMS[key];
349
151
 
350
152
  /**
351
- * Gets PropFirm by ID (synced with dashboard)
352
- * @param {string} id - PropFirm ID
353
- * @returns {Object|undefined} PropFirm config
153
+ * Gets PropFirm by ID
354
154
  */
355
155
  const getPropFirmById = (id) => {
356
156
  return Object.values(PROPFIRMS).find(pf => pf.id === id);
357
157
  };
358
158
 
359
159
  /**
360
- * Gets all PropFirms for a platform
361
- * @param {string} platform - Platform name (ProjectX, Tradovate, Rithmic)
362
- * @returns {Array} PropFirm configs
160
+ * Gets all PropFirms
363
161
  */
364
- const getPropFirmsByPlatform = (platform) => {
365
- return Object.entries(PROPFIRMS)
366
- .filter(([_, v]) => v.platform === platform)
367
- .map(([key, val]) => ({ key, ...val }));
162
+ const getAllPropFirms = () => {
163
+ return Object.entries(PROPFIRMS).map(([key, val]) => ({ key, ...val }));
368
164
  };
369
165
 
370
166
  module.exports = {
@@ -372,5 +168,5 @@ module.exports = {
372
168
  PROPFIRM_CHOICES,
373
169
  getPropFirm,
374
170
  getPropFirmById,
375
- getPropFirmsByPlatform
171
+ getAllPropFirms
376
172
  };
@@ -136,48 +136,6 @@ const CACHE = {
136
136
  STATS_TTL: 60000, // 1 minute
137
137
  };
138
138
 
139
- // ==================== FAST SCALPING (Ultra-Low Latency) ====================
140
- const FAST_SCALPING = {
141
- // Hold constraints (prop firm rules - NON-NEGOTIABLE)
142
- MIN_HOLD_MS: 10000, // 10 seconds minimum hold
143
- MAX_HOLD_MS: 60000, // 60 seconds failsafe (force exit if stuck)
144
-
145
- // Exit targets (in ticks) - defaults, override per symbol
146
- TARGET_TICKS: 16, // Take profit target (+$80 on NQ)
147
- STOP_TICKS: 20, // Stop loss (-$100 on NQ)
148
-
149
- // Breakeven (BE) - move SL to entry price after profit threshold
150
- BREAKEVEN_ACTIVATION_TICKS: 6, // Activate BE after +6 ticks profit (+$30 on NQ)
151
- BREAKEVEN_OFFSET_TICKS: 1, // BE at entry + 1 tick (small profit lock)
152
-
153
- // Trailing stop (activates after MIN_HOLD + profit threshold)
154
- TRAILING_ACTIVATION_TICKS: 8, // Start trailing after +8 ticks profit (+$40 on NQ)
155
- TRAILING_DISTANCE_TICKS: 4, // Trail 4 ticks behind high/low
156
-
157
- // Position monitoring
158
- MONITOR_INTERVAL_MS: 100, // Check position every 100ms after hold
159
-
160
- // Momentum thresholds (cumulative delta over 5 seconds)
161
- MOMENTUM_STRONG_THRESHOLD: 50, // Delta > 50 = strong momentum, HOLD
162
- MOMENTUM_WEAK_THRESHOLD: 20, // Delta < 20 = weak momentum, consider EXIT
163
- MOMENTUM_WINDOW_MS: 5000, // 5 second window for momentum calc
164
-
165
- // Latency monitoring
166
- LOG_LATENCY: true,
167
- LATENCY_TARGET_MS: 50, // Target entry latency
168
- LATENCY_WARN_MS: 100, // Warn if entry takes > 100ms
169
-
170
- // ═══════════════════════════════════════════════════════════════════════════
171
- // RECOVERY MODE - Math-based adaptive strategy when in drawdown
172
- // Uses Kelly Criterion, Volatility scaling, and Win Rate adjustment
173
- // ═══════════════════════════════════════════════════════════════════════════
174
- RECOVERY: {
175
- ENABLED: true,
176
- ACTIVATION_PNL: -300, // Activate recovery at -$300 session P&L
177
- DEACTIVATION_PNL: -100, // Deactivate when recovered to -$100
178
- },
179
- };
180
-
181
139
  // ==================== DEBUG ====================
182
140
  const DEBUG = {
183
141
  get enabled() {
@@ -194,5 +152,4 @@ module.exports = {
194
152
  HQX_SERVER,
195
153
  CACHE,
196
154
  DEBUG,
197
- FAST_SCALPING,
198
155
  };
package/src/lib/api.js ADDED
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Trading API - REAL ORDER EXECUTION
3
+ * Connects to ProjectX/TopstepX API for real trades
4
+ */
5
+
6
+ const https = require('https');
7
+
8
+ const PROPFIRM_APIS = {
9
+ topstep: 'api.topstepx.com',
10
+ alpha_futures: 'api.alphafutures.projectx.com',
11
+ tickticktrader: 'api.tickticktrader.projectx.com',
12
+ bulenox: 'api.bulenox.projectx.com',
13
+ tradeday: 'api.tradeday.projectx.com'
14
+ };
15
+
16
+ class TradingAPI {
17
+ constructor(token, propfirm = 'topstep') {
18
+ this.token = token;
19
+ this.apiHost = PROPFIRM_APIS[propfirm] || PROPFIRM_APIS.topstep;
20
+ }
21
+
22
+ async _request(path, method = 'POST', data = null) {
23
+ return new Promise((resolve, reject) => {
24
+ const options = {
25
+ hostname: this.apiHost,
26
+ port: 443,
27
+ path: path,
28
+ method: method,
29
+ headers: {
30
+ 'Content-Type': 'application/json',
31
+ 'Accept': 'application/json',
32
+ 'Authorization': `Bearer ${this.token}`
33
+ },
34
+ timeout: 10000
35
+ };
36
+
37
+ const req = https.request(options, (res) => {
38
+ let body = '';
39
+ res.on('data', chunk => body += chunk);
40
+ res.on('end', () => {
41
+ try {
42
+ resolve({ status: res.statusCode, data: JSON.parse(body) });
43
+ } catch (e) {
44
+ resolve({ status: res.statusCode, data: body });
45
+ }
46
+ });
47
+ });
48
+
49
+ req.on('error', reject);
50
+ req.on('timeout', () => {
51
+ req.destroy();
52
+ reject(new Error('Request timeout'));
53
+ });
54
+
55
+ if (data) req.write(JSON.stringify(data));
56
+ req.end();
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Place a market order - REAL EXECUTION
62
+ * ProjectX API order types:
63
+ * 1 = Limit (requires limitPrice)
64
+ * 2 = Market (no price required)
65
+ * 3 = Stop Market (requires stopPrice)
66
+ * 4 = Stop Limit (requires both)
67
+ */
68
+ async placeMarketOrder(accountId, contractId, side, quantity, currentPrice = 0) {
69
+ // Type 2 = Market order - tested and confirmed working
70
+ const orderData = {
71
+ accountId: parseInt(accountId),
72
+ contractId: contractId,
73
+ type: 2, // Market order
74
+ side: side === 'buy' ? 0 : 1, // 0=Buy, 1=Sell
75
+ size: quantity
76
+ };
77
+
78
+ console.log(`[TRADING] MARKET ${side.toUpperCase()} ${quantity}x ${contractId}`);
79
+
80
+ const response = await this._request('/api/Order/place', 'POST', orderData);
81
+
82
+ if (response.status === 200 && response.data.success) {
83
+ console.log(`[TRADING] FILLED - OrderId: ${response.data.orderId}`);
84
+ return { success: true, order: response.data };
85
+ } else {
86
+ console.log(`[TRADING] REJECTED: ${response.data.errorMessage || 'Unknown error'}`);
87
+ return { success: false, error: response.data.errorMessage || 'Order failed' };
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Place a limit order - REAL EXECUTION
93
+ */
94
+ async placeLimitOrder(accountId, contractId, side, quantity, price) {
95
+ const orderData = {
96
+ accountId: parseInt(accountId),
97
+ contractId: contractId,
98
+ type: 0, // Limit order
99
+ side: side === 'buy' ? 0 : 1,
100
+ size: quantity,
101
+ limitPrice: price
102
+ };
103
+
104
+ console.log(`[TRADING] Placing LIMIT order: ${side.toUpperCase()} ${quantity}x ${contractId} @ ${price}`);
105
+
106
+ const response = await this._request('/api/Order/place', 'POST', orderData);
107
+
108
+ if (response.status === 200 && response.data.success) {
109
+ console.log(`[TRADING] Limit order placed: ${JSON.stringify(response.data)}`);
110
+ return { success: true, order: response.data };
111
+ } else {
112
+ return { success: false, error: response.data.errorMessage || 'Order failed' };
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Place a stop order - REAL EXECUTION
118
+ * ProjectX API: type 2 = Stop Market
119
+ */
120
+ async placeStopOrder(accountId, contractId, side, quantity, stopPrice) {
121
+ const orderData = {
122
+ accountId: parseInt(accountId),
123
+ contractId: contractId,
124
+ type: 2, // Stop Market order
125
+ side: side === 'buy' ? 0 : 1,
126
+ size: quantity,
127
+ stopPrice: stopPrice
128
+ };
129
+
130
+ console.log(`[TRADING] Placing STOP order: ${side.toUpperCase()} ${quantity}x ${contractId} @ stop ${stopPrice}`);
131
+
132
+ const response = await this._request('/api/Order/place', 'POST', orderData);
133
+
134
+ console.log(`[TRADING] Stop response: ${JSON.stringify(response.data)}`);
135
+
136
+ if (response.status === 200 && response.data.success) {
137
+ console.log(`[TRADING] Stop order placed - OrderId: ${response.data.orderId}`);
138
+ return { success: true, order: response.data };
139
+ } else {
140
+ console.log(`[TRADING] Stop order REJECTED: ${response.data.errorMessage || 'Unknown error'}`);
141
+ return { success: false, error: response.data.errorMessage || 'Order failed' };
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Cancel an order
147
+ */
148
+ async cancelOrder(orderId) {
149
+ const response = await this._request('/api/Order/cancel', 'POST', { orderId: parseInt(orderId) });
150
+ return { success: response.status === 200 && response.data.success };
151
+ }
152
+
153
+ /**
154
+ * Close a position - REAL EXECUTION
155
+ */
156
+ async closePosition(accountId, contractId) {
157
+ console.log(`[TRADING] Closing position: ${contractId}`);
158
+
159
+ const response = await this._request('/api/Position/closeContract', 'POST', {
160
+ accountId: parseInt(accountId),
161
+ contractId: contractId
162
+ });
163
+
164
+ if (response.status === 200 && response.data.success) {
165
+ console.log(`[TRADING] Position CLOSED`);
166
+ return { success: true };
167
+ } else {
168
+ console.log(`[TRADING] Close FAILED: ${JSON.stringify(response.data)}`);
169
+ return { success: false, error: response.data.errorMessage || 'Close failed' };
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Get open positions
175
+ */
176
+ async getPositions(accountId) {
177
+ const response = await this._request('/api/Position/searchOpen', 'POST', { accountId: parseInt(accountId) });
178
+
179
+ if (response.status === 200) {
180
+ return { success: true, positions: response.data.positions || response.data || [] };
181
+ }
182
+ return { success: false, positions: [] };
183
+ }
184
+
185
+ /**
186
+ * Get open orders
187
+ */
188
+ async getOrders(accountId) {
189
+ const response = await this._request('/api/Order/searchOpen', 'POST', { accountId: parseInt(accountId) });
190
+
191
+ if (response.status === 200) {
192
+ return { success: true, orders: response.data.orders || response.data || [] };
193
+ }
194
+ return { success: false, orders: [] };
195
+ }
196
+ }
197
+
198
+ module.exports = { TradingAPI };