hedgequantx 2.3.15 → 2.3.17
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/api.jsc +0 -0
- package/dist/lib/api2.jsc +0 -0
- package/dist/lib/core.jsc +0 -0
- package/dist/lib/core2.jsc +0 -0
- package/dist/lib/data.jsc +0 -0
- package/dist/lib/data2.jsc +0 -0
- package/dist/lib/decoder.jsc +0 -0
- package/dist/lib/m/mod1.jsc +0 -0
- package/dist/lib/m/mod2.jsc +0 -0
- package/dist/lib/n/r1.jsc +0 -0
- package/dist/lib/n/r2.jsc +0 -0
- package/dist/lib/n/r3.jsc +0 -0
- package/dist/lib/n/r4.jsc +0 -0
- package/dist/lib/n/r5.jsc +0 -0
- package/dist/lib/n/r6.jsc +0 -0
- package/dist/lib/n/r7.jsc +0 -0
- package/dist/lib/o/util1.jsc +0 -0
- package/dist/lib/o/util2.jsc +0 -0
- package/package.json +1 -1
- package/src/pages/algo/one-account.js +86 -43
- package/src/pages/algo/ui.js +9 -5
package/dist/lib/api.jsc
CHANGED
|
Binary file
|
package/dist/lib/api2.jsc
CHANGED
|
Binary file
|
package/dist/lib/core.jsc
CHANGED
|
Binary file
|
package/dist/lib/core2.jsc
CHANGED
|
Binary file
|
package/dist/lib/data.jsc
CHANGED
|
Binary file
|
package/dist/lib/data2.jsc
CHANGED
|
Binary file
|
package/dist/lib/decoder.jsc
CHANGED
|
Binary file
|
package/dist/lib/m/mod1.jsc
CHANGED
|
Binary file
|
package/dist/lib/m/mod2.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r1.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r2.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r3.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r4.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r5.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r6.jsc
CHANGED
|
Binary file
|
package/dist/lib/n/r7.jsc
CHANGED
|
Binary file
|
package/dist/lib/o/util1.jsc
CHANGED
|
Binary file
|
package/dist/lib/o/util2.jsc
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -11,6 +11,8 @@ const { AlgoUI, renderSessionSummary } = require('./ui');
|
|
|
11
11
|
const { prompts } = require('../../utils');
|
|
12
12
|
const { checkMarketHours } = require('../../services/projectx/market');
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
|
|
14
16
|
/**
|
|
15
17
|
* One Account Menu
|
|
16
18
|
*/
|
|
@@ -154,28 +156,49 @@ const configureAlgo = async (account, contract) => {
|
|
|
154
156
|
|
|
155
157
|
/**
|
|
156
158
|
* Launch algo trading
|
|
159
|
+
* 100% API data - no simulation, no mock data, no local calculations
|
|
157
160
|
*/
|
|
158
161
|
const launchAlgo = async (service, account, contract, config) => {
|
|
159
162
|
const { contracts, dailyTarget, maxRisk, showName } = config;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const accountName = showName
|
|
163
|
-
|
|
163
|
+
|
|
164
|
+
// Use RAW API fields
|
|
165
|
+
const accountName = showName
|
|
166
|
+
? (account.accountName || account.rithmicAccountId || account.accountId)
|
|
167
|
+
: 'HQX *****';
|
|
164
168
|
const symbolName = contract.name;
|
|
169
|
+
const connectionType = account.platform || 'ProjectX';
|
|
165
170
|
|
|
166
171
|
const ui = new AlgoUI({ subtitle: 'HQX Algo Trading', mode: 'one-account' });
|
|
167
172
|
|
|
168
173
|
const stats = {
|
|
169
|
-
accountName,
|
|
170
|
-
|
|
174
|
+
accountName,
|
|
175
|
+
symbol: symbolName,
|
|
176
|
+
qty: contracts,
|
|
177
|
+
target: dailyTarget,
|
|
178
|
+
risk: maxRisk,
|
|
171
179
|
propfirm: account.propfirm || 'Unknown',
|
|
172
|
-
platform:
|
|
173
|
-
pnl: 0,
|
|
174
|
-
|
|
175
|
-
|
|
180
|
+
platform: connectionType,
|
|
181
|
+
pnl: 0,
|
|
182
|
+
trades: 0,
|
|
183
|
+
wins: 0,
|
|
184
|
+
losses: 0,
|
|
185
|
+
latency: 0,
|
|
186
|
+
connected: true,
|
|
187
|
+
startTime: Date.now()
|
|
176
188
|
};
|
|
177
189
|
|
|
178
|
-
|
|
190
|
+
let running = true;
|
|
191
|
+
let stopReason = null;
|
|
192
|
+
let lastPnL = 0;
|
|
193
|
+
|
|
194
|
+
// Log startup info from API
|
|
195
|
+
ui.addLog('info', `Connection: ${connectionType}`);
|
|
196
|
+
ui.addLog('info', `Account: ${accountName}`);
|
|
197
|
+
ui.addLog('info', `Symbol: ${symbolName} | Qty: ${contracts}`);
|
|
198
|
+
ui.addLog('info', `Target: $${dailyTarget} | Max Risk: $${maxRisk}`);
|
|
199
|
+
ui.addLog('info', 'Monitoring positions from API...');
|
|
200
|
+
|
|
201
|
+
// Measure API latency (real network round-trip)
|
|
179
202
|
const measureLatency = async () => {
|
|
180
203
|
try {
|
|
181
204
|
const start = Date.now();
|
|
@@ -186,45 +209,64 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
186
209
|
}
|
|
187
210
|
};
|
|
188
211
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// Local algo - no external server needed
|
|
193
|
-
ui.addLog('info', `Starting algo on ${stats.platform}...`);
|
|
194
|
-
ui.addLog('info', `Symbol: ${symbolName} | Qty: ${contracts}`);
|
|
195
|
-
ui.addLog('info', `Target: $${dailyTarget} | Risk: $${maxRisk}`);
|
|
196
|
-
stats.connected = true;
|
|
197
|
-
|
|
198
|
-
// Poll P&L from API every 2 seconds
|
|
199
|
-
const pollPnL = async () => {
|
|
212
|
+
// Poll data from API - 100% real data
|
|
213
|
+
const pollAPI = async () => {
|
|
200
214
|
try {
|
|
201
|
-
// Get positions
|
|
215
|
+
// Get positions from API
|
|
202
216
|
const posResult = await service.getPositions(account.accountId);
|
|
217
|
+
|
|
203
218
|
if (posResult.success && posResult.positions) {
|
|
204
|
-
// Find position for
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
219
|
+
// Find position for selected contract
|
|
220
|
+
const position = posResult.positions.find(p => {
|
|
221
|
+
const posSymbol = p.contractId || p.symbol || '';
|
|
222
|
+
return posSymbol.includes(contract.name) || posSymbol.includes(contract.id);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
if (position) {
|
|
226
|
+
// P&L directly from API - no calculation
|
|
227
|
+
const apiPnL = position.profitAndLoss || 0;
|
|
211
228
|
|
|
212
|
-
// Detect trade completion
|
|
213
|
-
if (Math.abs(
|
|
214
|
-
const tradePnL =
|
|
229
|
+
// Detect trade completion (P&L changed)
|
|
230
|
+
if (lastPnL !== 0 && Math.abs(apiPnL - lastPnL) > 0.01) {
|
|
231
|
+
const tradePnL = apiPnL - lastPnL;
|
|
215
232
|
stats.trades++;
|
|
216
|
-
|
|
233
|
+
|
|
234
|
+
if (tradePnL > 0) {
|
|
217
235
|
stats.wins++;
|
|
218
|
-
ui.addLog('trade',
|
|
236
|
+
ui.addLog('trade', `+$${tradePnL.toFixed(2)} (from API)`);
|
|
219
237
|
} else {
|
|
220
238
|
stats.losses++;
|
|
221
|
-
ui.addLog('loss',
|
|
239
|
+
ui.addLog('loss', `-$${Math.abs(tradePnL).toFixed(2)} (from API)`);
|
|
222
240
|
}
|
|
223
241
|
}
|
|
242
|
+
|
|
243
|
+
lastPnL = apiPnL;
|
|
244
|
+
stats.pnl = apiPnL;
|
|
245
|
+
|
|
246
|
+
// Log position info from API
|
|
247
|
+
if (position.quantity && position.quantity !== 0) {
|
|
248
|
+
const side = position.quantity > 0 ? 'LONG' : 'SHORT';
|
|
249
|
+
const qty = Math.abs(position.quantity);
|
|
250
|
+
ui.addLog('info', `Position: ${side} ${qty}x | P&L: $${apiPnL.toFixed(2)}`);
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
// No position - flat
|
|
254
|
+
if (stats.pnl !== 0) {
|
|
255
|
+
ui.addLog('info', 'Position closed - Flat');
|
|
256
|
+
}
|
|
224
257
|
}
|
|
225
258
|
}
|
|
226
259
|
|
|
227
|
-
//
|
|
260
|
+
// Get account balance from API
|
|
261
|
+
const accountResult = await service.getTradingAccounts();
|
|
262
|
+
if (accountResult.success && accountResult.accounts) {
|
|
263
|
+
const acc = accountResult.accounts.find(a => a.accountId === account.accountId);
|
|
264
|
+
if (acc && acc.profitAndLoss !== undefined) {
|
|
265
|
+
stats.pnl = acc.profitAndLoss;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Check target/risk limits (using API P&L)
|
|
228
270
|
if (stats.pnl >= dailyTarget) {
|
|
229
271
|
stopReason = 'target';
|
|
230
272
|
running = false;
|
|
@@ -232,10 +274,11 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
232
274
|
} else if (stats.pnl <= -maxRisk) {
|
|
233
275
|
stopReason = 'risk';
|
|
234
276
|
running = false;
|
|
235
|
-
ui.addLog('error', `MAX RISK
|
|
277
|
+
ui.addLog('error', `MAX RISK! -$${Math.abs(stats.pnl).toFixed(2)}`);
|
|
236
278
|
}
|
|
279
|
+
|
|
237
280
|
} catch (e) {
|
|
238
|
-
|
|
281
|
+
ui.addLog('error', `API Error: ${e.message}`);
|
|
239
282
|
}
|
|
240
283
|
};
|
|
241
284
|
|
|
@@ -245,9 +288,9 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
245
288
|
measureLatency(); // Initial measurement
|
|
246
289
|
const latencyInterval = setInterval(() => { if (running) measureLatency(); }, 5000);
|
|
247
290
|
|
|
248
|
-
// Poll
|
|
249
|
-
|
|
250
|
-
const
|
|
291
|
+
// Poll data from API every 2 seconds
|
|
292
|
+
pollAPI(); // Initial poll
|
|
293
|
+
const apiInterval = setInterval(() => { if (running) pollAPI(); }, 2000);
|
|
251
294
|
|
|
252
295
|
// Keyboard
|
|
253
296
|
const setupKeyHandler = () => {
|
|
@@ -276,7 +319,7 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
276
319
|
|
|
277
320
|
clearInterval(refreshInterval);
|
|
278
321
|
clearInterval(latencyInterval);
|
|
279
|
-
clearInterval(
|
|
322
|
+
clearInterval(apiInterval);
|
|
280
323
|
if (cleanupKeys) cleanupKeys();
|
|
281
324
|
ui.cleanup();
|
|
282
325
|
|
package/src/pages/algo/ui.js
CHANGED
|
@@ -275,14 +275,18 @@ class AlgoUI {
|
|
|
275
275
|
const dateStr = now.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
276
276
|
|
|
277
277
|
const leftText = ` EXECUTION LOG ${spinner}`;
|
|
278
|
-
const rightText =
|
|
279
|
-
|
|
280
|
-
const
|
|
278
|
+
const rightText = `[X] STOP `;
|
|
279
|
+
|
|
280
|
+
const totalFixed = leftText.length + rightText.length;
|
|
281
|
+
const centerSpace = W - totalFixed;
|
|
282
|
+
const centerPadLeft = Math.floor((centerSpace - dateStr.length) / 2);
|
|
283
|
+
const centerPadRight = centerSpace - dateStr.length - centerPadLeft;
|
|
281
284
|
|
|
282
285
|
const left = ` EXECUTION LOG ${chalk.yellow(spinner)}`;
|
|
283
|
-
const
|
|
286
|
+
const center = ' '.repeat(Math.max(0, centerPadLeft)) + chalk.white(dateStr) + ' '.repeat(Math.max(0, centerPadRight));
|
|
287
|
+
const right = chalk.yellow('[X] STOP') + ' ';
|
|
284
288
|
|
|
285
|
-
this._line(chalk.cyan(BOX.V) + chalk.white.bold(left) +
|
|
289
|
+
this._line(chalk.cyan(BOX.V) + chalk.white.bold(left) + center + right + chalk.cyan(BOX.V));
|
|
286
290
|
this._line(chalk.cyan(BOX.ML + BOX.H.repeat(W) + BOX.MR));
|
|
287
291
|
|
|
288
292
|
// Logs: newest at top
|