hedgequantx 2.7.93 → 2.7.95

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.7.93",
3
+ "version": "2.7.95",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -97,12 +97,20 @@ const showAccounts = async (service) => {
97
97
  const name1 = String(acc1.accountName || acc1.rithmicAccountId || acc1.accountId || `Account #${i + 1}`);
98
98
  const name2 = acc2 ? String(acc2.accountName || acc2.rithmicAccountId || acc2.accountId || `Account #${i + 2}`) : '';
99
99
 
100
- draw2ColHeader(name1.substring(0, col1 - 4), name2 ? name2.substring(0, col2 - 4) : '', boxWidth);
100
+ // For single account, use full width; for pairs, use 2-column layout
101
+ const sep = acc2 ? '│' : '║';
102
+ const rightCol = acc2 ? col2 : col2;
103
+
104
+ // Header row with account name(s)
105
+ const h1 = centerText(name1.substring(0, col1 - 4), col1);
106
+ const h2 = acc2 ? centerText(name2.substring(0, col2 - 4), col2) : ' '.repeat(col2);
107
+ console.log(chalk.cyan('║') + chalk.cyan.bold(h1) + chalk.cyan(sep) + chalk.cyan.bold(h2) + chalk.cyan('║'));
108
+ console.log(chalk.cyan('╠') + chalk.cyan('─'.repeat(col1)) + chalk.cyan(acc2 ? '┼' : '┼') + chalk.cyan('─'.repeat(col2)) + chalk.cyan('╣'));
101
109
 
102
110
  // PropFirm
103
111
  const pf1 = chalk.magenta(acc1.propfirm || 'Unknown');
104
112
  const pf2 = acc2 ? chalk.magenta(acc2.propfirm || 'Unknown') : '';
105
- console.log(chalk.cyan('║') + fmtRow('PropFirm:', pf1, col1) + chalk.cyan('│') + (acc2 ? fmtRow('PropFirm:', pf2, col2) : ' '.repeat(col2)) + chalk.cyan('║'));
113
+ console.log(chalk.cyan('║') + fmtRow('PropFirm:', pf1, col1) + chalk.cyan(sep) + (acc2 ? fmtRow('PropFirm:', pf2, col2) : ' '.repeat(col2)) + chalk.cyan('║'));
106
114
 
107
115
  // Balance
108
116
  const bal1 = acc1.balance;
@@ -111,7 +119,7 @@ const showAccounts = async (service) => {
111
119
  const balStr2 = bal2 !== null && bal2 !== undefined ? '$' + Number(bal2).toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) : '--';
112
120
  const balColor1 = bal1 === null || bal1 === undefined ? chalk.gray : (bal1 >= 0 ? chalk.green : chalk.red);
113
121
  const balColor2 = bal2 === null || bal2 === undefined ? chalk.gray : (bal2 >= 0 ? chalk.green : chalk.red);
114
- console.log(chalk.cyan('║') + fmtRow('Balance:', balColor1(balStr1), col1) + chalk.cyan('│') + (acc2 ? fmtRow('Balance:', balColor2(balStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
122
+ console.log(chalk.cyan('║') + fmtRow('Balance:', balColor1(balStr1), col1) + chalk.cyan(sep) + (acc2 ? fmtRow('Balance:', balColor2(balStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
115
123
 
116
124
  // P&L
117
125
  const pnl1 = acc1.profitAndLoss;
@@ -120,32 +128,32 @@ const showAccounts = async (service) => {
120
128
  const pnlStr2 = pnl2 !== null && pnl2 !== undefined ? (pnl2 >= 0 ? '+' : '') + '$' + Number(pnl2).toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) : '--';
121
129
  const pnlColor1 = pnl1 === null || pnl1 === undefined ? chalk.gray : (pnl1 >= 0 ? chalk.green : chalk.red);
122
130
  const pnlColor2 = pnl2 === null || pnl2 === undefined ? chalk.gray : (pnl2 >= 0 ? chalk.green : chalk.red);
123
- console.log(chalk.cyan('║') + fmtRow('P&L:', pnlColor1(pnlStr1), col1) + chalk.cyan('│') + (acc2 ? fmtRow('P&L:', pnlColor2(pnlStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
131
+ console.log(chalk.cyan('║') + fmtRow('P&L:', pnlColor1(pnlStr1), col1) + chalk.cyan(sep) + (acc2 ? fmtRow('P&L:', pnlColor2(pnlStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
124
132
 
125
- // Status - handle both string from API and numeric lookup
133
+ // Status - from API only, N/A if not available
126
134
  const getStatusDisplay = (status) => {
127
- if (!status && status !== 0) return { text: '--', color: 'gray' };
135
+ if (status === null || status === undefined) return { text: 'N/A', color: 'gray' };
136
+ if (typeof status === 'number') {
137
+ return ACCOUNT_STATUS[status] || { text: String(status), color: 'yellow' };
138
+ }
128
139
  if (typeof status === 'string') {
129
- // Direct string from Rithmic API (e.g., "Active", "Disabled")
130
140
  const lowerStatus = status.toLowerCase();
131
141
  if (lowerStatus.includes('active') || lowerStatus.includes('open')) return { text: status, color: 'green' };
132
142
  if (lowerStatus.includes('disabled') || lowerStatus.includes('closed')) return { text: status, color: 'red' };
133
143
  if (lowerStatus.includes('halt')) return { text: status, color: 'red' };
134
144
  return { text: status, color: 'yellow' };
135
145
  }
136
- return ACCOUNT_STATUS[status] || { text: 'Unknown', color: 'gray' };
146
+ return { text: 'N/A', color: 'gray' };
137
147
  };
138
148
  const status1 = getStatusDisplay(acc1.status);
139
149
  const status2 = acc2 ? getStatusDisplay(acc2.status) : null;
140
- console.log(chalk.cyan('║') + fmtRow('Status:', chalk[status1.color](status1.text), col1) + chalk.cyan('│') + (acc2 ? fmtRow('Status:', chalk[status2.color](status2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
150
+ console.log(chalk.cyan('║') + fmtRow('Status:', chalk[status1.color](status1.text), col1) + chalk.cyan(sep) + (acc2 ? fmtRow('Status:', chalk[status2.color](status2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
141
151
 
142
- // Type/Algorithm - handle both string from API and numeric lookup
143
- const getTypeDisplay = (type, algorithm) => {
144
- // Prefer algorithm from RMS info if available
145
- const value = algorithm || type;
146
- if (!value && value !== 0) return { text: '--', color: 'gray' };
152
+ // Type - from API only (algorithm or accountType field), N/A if not available
153
+ const getTypeDisplay = (acc) => {
154
+ const value = acc.algorithm || acc.accountType || acc.type;
155
+ if (value === null || value === undefined) return { text: 'N/A', color: 'gray' };
147
156
  if (typeof value === 'string') {
148
- // Direct string from Rithmic API
149
157
  const lowerValue = value.toLowerCase();
150
158
  if (lowerValue.includes('eval')) return { text: value, color: 'yellow' };
151
159
  if (lowerValue.includes('live') || lowerValue.includes('funded')) return { text: value, color: 'green' };
@@ -153,11 +161,14 @@ const showAccounts = async (service) => {
153
161
  if (lowerValue.includes('express')) return { text: value, color: 'magenta' };
154
162
  return { text: value, color: 'cyan' };
155
163
  }
156
- return ACCOUNT_TYPE[value] || { text: 'Unknown', color: 'white' };
164
+ if (typeof value === 'number') {
165
+ return ACCOUNT_TYPE[value] || { text: String(value), color: 'white' };
166
+ }
167
+ return { text: 'N/A', color: 'gray' };
157
168
  };
158
- const type1 = getTypeDisplay(acc1.type, acc1.algorithm);
159
- const type2 = acc2 ? getTypeDisplay(acc2.type, acc2.algorithm) : null;
160
- console.log(chalk.cyan('║') + fmtRow('Type:', chalk[type1.color](type1.text), col1) + chalk.cyan('│') + (acc2 ? fmtRow('Type:', chalk[type2.color](type2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
169
+ const type1 = getTypeDisplay(acc1);
170
+ const type2 = acc2 ? getTypeDisplay(acc2) : null;
171
+ console.log(chalk.cyan('║') + fmtRow('Type:', chalk[type1.color](type1.text), col1) + chalk.cyan(sep) + (acc2 ? fmtRow('Type:', chalk[type2.color](type2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
161
172
 
162
173
  if (i + 2 < allAccounts.length) {
163
174
  console.log(chalk.cyan('╠') + chalk.cyan('═'.repeat(col1)) + chalk.cyan('╪') + chalk.cyan('═'.repeat(col2)) + chalk.cyan('╣'));