hedgequantx 2.3.4 → 2.3.6
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/stats.js +46 -53
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
package/src/pages/stats.js
CHANGED
|
@@ -230,7 +230,7 @@ const showStats = async (service) => {
|
|
|
230
230
|
const winRate = stats.totalTrades > 0 ? ((stats.winningTrades / stats.totalTrades) * 100).toFixed(1) : '0.0';
|
|
231
231
|
const avgWin = stats.winningTrades > 0 ? (stats.totalWinAmount / stats.winningTrades).toFixed(2) : '0.00';
|
|
232
232
|
const avgLoss = stats.losingTrades > 0 ? (stats.totalLossAmount / stats.losingTrades).toFixed(2) : '0.00';
|
|
233
|
-
const profitFactor = stats.totalLossAmount > 0 ? (stats.totalWinAmount / stats.totalLossAmount).toFixed(2) : '0.00';
|
|
233
|
+
const profitFactor = stats.totalLossAmount > 0 ? (stats.totalWinAmount / stats.totalLossAmount).toFixed(2) : (stats.totalWinAmount > 0 ? '∞' : '0.00');
|
|
234
234
|
const netPnL = stats.totalWinAmount - stats.totalLossAmount;
|
|
235
235
|
const returnPercent = totalStartingBalance > 0 ? ((totalPnL / totalStartingBalance) * 100).toFixed(2) : '0.00';
|
|
236
236
|
const longWinRate = stats.longTrades > 0 ? ((stats.longWins / stats.longTrades) * 100).toFixed(1) : '0.0';
|
|
@@ -291,13 +291,18 @@ const showStats = async (service) => {
|
|
|
291
291
|
draw2ColSeparator(boxWidth);
|
|
292
292
|
draw2ColHeader('P&L METRICS', 'RISK METRICS', boxWidth);
|
|
293
293
|
|
|
294
|
-
|
|
294
|
+
// Profit Factor coloring - ∞ is best (green)
|
|
295
|
+
const pfNum = profitFactor === '∞' ? Infinity : parseFloat(profitFactor);
|
|
296
|
+
const pfColor = pfNum === Infinity ? chalk.green(profitFactor) : pfNum >= 1.5 ? chalk.green(profitFactor) : pfNum >= 1 ? chalk.yellow(profitFactor) : chalk.red(profitFactor);
|
|
295
297
|
|
|
296
|
-
|
|
298
|
+
// Worst trade display - show as negative if it's a loss
|
|
299
|
+
const worstTradeStr = stats.worstTrade < 0 ? '-$' + Math.abs(stats.worstTrade).toFixed(2) : '$' + stats.worstTrade.toFixed(2);
|
|
300
|
+
|
|
301
|
+
console.log(chalk.cyan('\u2551') + fmtRow('Net P&L:', netPnL >= 0 ? chalk.green('$' + netPnL.toFixed(2)) : chalk.red('-$' + Math.abs(netPnL).toFixed(2)), col1) + chalk.cyan('\u2502') + fmtRow('Profit Factor:', pfColor, col2) + chalk.cyan('\u2551'));
|
|
297
302
|
console.log(chalk.cyan('\u2551') + fmtRow('Gross Profit:', chalk.green('$' + stats.totalWinAmount.toFixed(2)), col1) + chalk.cyan('\u2502') + fmtRow('Max Consec. Wins:', chalk.green(String(stats.maxConsecutiveWins)), col2) + chalk.cyan('\u2551'));
|
|
298
|
-
console.log(chalk.cyan('\u2551') + fmtRow('Gross Loss:', chalk.red('-$' + stats.totalLossAmount.toFixed(2)), col1) + chalk.cyan('\u2502') + fmtRow('Max Consec. Loss:', chalk.red(String(stats.maxConsecutiveLosses)), col2) + chalk.cyan('\u2551'));
|
|
303
|
+
console.log(chalk.cyan('\u2551') + fmtRow('Gross Loss:', chalk.red('-$' + stats.totalLossAmount.toFixed(2)), col1) + chalk.cyan('\u2502') + fmtRow('Max Consec. Loss:', stats.maxConsecutiveLosses > 0 ? chalk.red(String(stats.maxConsecutiveLosses)) : chalk.green('0'), col2) + chalk.cyan('\u2551'));
|
|
299
304
|
console.log(chalk.cyan('\u2551') + fmtRow('Avg Win:', chalk.green('$' + avgWin), col1) + chalk.cyan('\u2502') + fmtRow('Best Trade:', chalk.green('$' + stats.bestTrade.toFixed(2)), col2) + chalk.cyan('\u2551'));
|
|
300
|
-
console.log(chalk.cyan('\u2551') + fmtRow('Avg Loss:', chalk.red('-$' + avgLoss), col1) + chalk.cyan('\u2502') + fmtRow('Worst Trade:', chalk.red(
|
|
305
|
+
console.log(chalk.cyan('\u2551') + fmtRow('Avg Loss:', stats.losingTrades > 0 ? chalk.red('-$' + avgLoss) : chalk.green('$0.00'), col1) + chalk.cyan('\u2502') + fmtRow('Worst Trade:', stats.worstTrade < 0 ? chalk.red(worstTradeStr) : chalk.green(worstTradeStr), col2) + chalk.cyan('\u2551'));
|
|
301
306
|
|
|
302
307
|
// Quantitative Metrics
|
|
303
308
|
draw2ColSeparator(boxWidth);
|
|
@@ -358,75 +363,63 @@ const showStats = async (service) => {
|
|
|
358
363
|
|
|
359
364
|
drawBoxFooter(boxWidth);
|
|
360
365
|
|
|
361
|
-
// Trades History
|
|
366
|
+
// Trades History - Simplified table
|
|
362
367
|
console.log();
|
|
363
368
|
drawBoxHeader('TRADES HISTORY', boxWidth);
|
|
364
369
|
|
|
365
370
|
const innerWidth = boxWidth - 2;
|
|
366
371
|
|
|
372
|
+
// Helper to extract symbol from contractId (e.g., "CON.F.US.EP.H25" -> "ES H25")
|
|
373
|
+
const extractSymbol = (contractId) => {
|
|
374
|
+
if (!contractId) return 'N/A';
|
|
375
|
+
// Format: CON.F.US.{SYMBOL}.{MONTH} -> extract symbol and month
|
|
376
|
+
const parts = contractId.split('.');
|
|
377
|
+
if (parts.length >= 5) {
|
|
378
|
+
const sym = parts[3]; // EP, ENQ, etc.
|
|
379
|
+
const month = parts[4]; // H25, M25, etc.
|
|
380
|
+
// Map common symbols
|
|
381
|
+
const symbolMap = { 'EP': 'ES', 'ENQ': 'NQ', 'MES': 'MES', 'MNQ': 'MNQ', 'YM': 'YM', 'NKD': 'NKD', 'RTY': 'RTY' };
|
|
382
|
+
return (symbolMap[sym] || sym) + ' ' + month;
|
|
383
|
+
}
|
|
384
|
+
return contractId.substring(0, 10);
|
|
385
|
+
};
|
|
386
|
+
|
|
367
387
|
if (allTrades.length > 0) {
|
|
368
|
-
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
const colExit = 10;
|
|
372
|
-
const colEntryP = 10;
|
|
373
|
-
const colExitP = 10;
|
|
374
|
-
const colPnL = 10;
|
|
375
|
-
const colDir = 6;
|
|
376
|
-
const colID = innerWidth - colTime - colSymbol - colEntry - colExit - colEntryP - colExitP - colPnL - colDir - 9;
|
|
377
|
-
|
|
378
|
-
const header =
|
|
379
|
-
chalk.white(' Time'.padEnd(colTime)) + chalk.gray('|') +
|
|
380
|
-
chalk.white('Symbol'.padEnd(colSymbol)) + chalk.gray('|') +
|
|
381
|
-
chalk.white('Entry'.padEnd(colEntry)) + chalk.gray('|') +
|
|
382
|
-
chalk.white('Exit'.padEnd(colExit)) + chalk.gray('|') +
|
|
383
|
-
chalk.white('Entry $'.padEnd(colEntryP)) + chalk.gray('|') +
|
|
384
|
-
chalk.white('Exit $'.padEnd(colExitP)) + chalk.gray('|') +
|
|
385
|
-
chalk.white('P&L'.padEnd(colPnL)) + chalk.gray('|') +
|
|
386
|
-
chalk.white('Dir'.padEnd(colDir)) + chalk.gray('|') +
|
|
387
|
-
chalk.white('ID'.padEnd(colID));
|
|
388
|
-
|
|
389
|
-
console.log(chalk.cyan('\u2551') + header + chalk.cyan('\u2551'));
|
|
388
|
+
// Simple format: Time | Symbol | Price | P&L | Side
|
|
389
|
+
const header = ' Time | Symbol | Price | P&L | Side ';
|
|
390
|
+
console.log(chalk.cyan('\u2551') + chalk.white(header.padEnd(innerWidth)) + chalk.cyan('\u2551'));
|
|
390
391
|
console.log(chalk.cyan('\u2551') + chalk.gray('\u2500'.repeat(innerWidth)) + chalk.cyan('\u2551'));
|
|
391
392
|
|
|
392
393
|
const recentTrades = allTrades.slice(-10).reverse();
|
|
393
394
|
|
|
394
395
|
for (const trade of recentTrades) {
|
|
395
|
-
const
|
|
396
|
-
const
|
|
397
|
-
const
|
|
398
|
-
const
|
|
399
|
-
const entryPrice = trade.entryPrice ? trade.entryPrice.toFixed(2) : 'N/A';
|
|
400
|
-
const exitPrice = trade.exitPrice ? trade.exitPrice.toFixed(2) : 'N/A';
|
|
396
|
+
const timestamp = trade.creationTimestamp || trade.timestamp;
|
|
397
|
+
const time = timestamp ? new Date(timestamp).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }) : '--:--';
|
|
398
|
+
const symbol = extractSymbol(trade.contractId || trade.symbol);
|
|
399
|
+
const price = (trade.price || 0).toFixed(2);
|
|
401
400
|
const pnl = trade.profitAndLoss || trade.pnl || 0;
|
|
402
|
-
const
|
|
403
|
-
const
|
|
404
|
-
const
|
|
401
|
+
const pnlText = pnl >= 0 ? `+$${pnl.toFixed(0)}` : `-$${Math.abs(pnl).toFixed(0)}`;
|
|
402
|
+
const pnlColored = pnl >= 0 ? chalk.green(pnlText.padEnd(10)) : chalk.red(pnlText.padEnd(10));
|
|
403
|
+
const side = trade.side === 0 ? 'BUY' : trade.side === 1 ? 'SELL' : 'N/A';
|
|
404
|
+
const sideColored = trade.side === 0 ? chalk.green(side.padEnd(6)) : chalk.red(side.padEnd(6));
|
|
405
405
|
|
|
406
|
-
const row =
|
|
407
|
-
|
|
408
|
-
symbol.padEnd(colSymbol) + chalk.gray('|') +
|
|
409
|
-
entryTime.padEnd(colEntry) + chalk.gray('|') +
|
|
410
|
-
exitTime.padEnd(colExit) + chalk.gray('|') +
|
|
411
|
-
entryPrice.padEnd(colEntryP) + chalk.gray('|') +
|
|
412
|
-
exitPrice.padEnd(colExitP) + chalk.gray('|') +
|
|
413
|
-
pnlStr.padEnd(colPnL + 10) + chalk.gray('|') +
|
|
414
|
-
direction.padEnd(colDir + 10) + chalk.gray('|') +
|
|
415
|
-
tradeId.padEnd(colID);
|
|
406
|
+
const row = ` ${time.padEnd(9)} | ${symbol.padEnd(9)} | ${price.padEnd(10)} | ${pnlText.padEnd(10)} | ${side.padEnd(6)}`;
|
|
407
|
+
const coloredRow = ` ${time.padEnd(9)} | ${symbol.padEnd(9)} | ${price.padEnd(10)} | ${pnlColored} | ${sideColored}`;
|
|
416
408
|
|
|
417
|
-
|
|
418
|
-
const
|
|
409
|
+
// Calculate visible length without ANSI codes
|
|
410
|
+
const visLen = row.length;
|
|
411
|
+
const padding = Math.max(0, innerWidth - visLen);
|
|
419
412
|
|
|
420
|
-
console.log(chalk.cyan('\u2551') +
|
|
413
|
+
console.log(chalk.cyan('\u2551') + coloredRow + ' '.repeat(padding) + chalk.cyan('\u2551'));
|
|
421
414
|
}
|
|
422
415
|
|
|
423
416
|
if (allTrades.length > 10) {
|
|
424
417
|
const moreMsg = ` ... and ${allTrades.length - 10} more trades`;
|
|
425
|
-
console.log(chalk.cyan('\u2551') + chalk.gray(moreMsg
|
|
418
|
+
console.log(chalk.cyan('\u2551') + chalk.gray(moreMsg.padEnd(innerWidth)) + chalk.cyan('\u2551'));
|
|
426
419
|
}
|
|
427
420
|
} else {
|
|
428
421
|
const msg = ' No trade history available';
|
|
429
|
-
console.log(chalk.cyan('\u2551') + chalk.gray(msg
|
|
422
|
+
console.log(chalk.cyan('\u2551') + chalk.gray(msg.padEnd(innerWidth)) + chalk.cyan('\u2551'));
|
|
430
423
|
}
|
|
431
424
|
|
|
432
425
|
drawBoxFooter(boxWidth);
|
|
@@ -436,7 +429,7 @@ const showStats = async (service) => {
|
|
|
436
429
|
drawBoxHeader('HQX SCORE', boxWidth);
|
|
437
430
|
|
|
438
431
|
const winRateScore = Math.min(100, parseFloat(winRate) * 1.5);
|
|
439
|
-
const profitFactorScore = Math.min(100, parseFloat(profitFactor) * 40);
|
|
432
|
+
const profitFactorScore = profitFactor === '∞' ? 100 : Math.min(100, parseFloat(profitFactor) * 40);
|
|
440
433
|
const consistencyScore = stats.maxConsecutiveLosses > 0 ? Math.max(0, 100 - (stats.maxConsecutiveLosses * 15)) : 100;
|
|
441
434
|
const riskScore = stats.worstTrade !== 0 && totalStartingBalance > 0
|
|
442
435
|
? Math.max(0, 100 - (Math.abs(stats.worstTrade) / totalStartingBalance * 1000))
|