hedgequantx 2.7.13 → 2.7.15

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.13",
3
+ "version": "2.7.15",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -219,8 +219,8 @@ const selectSymbol = async (service) => {
219
219
  });
220
220
  }
221
221
 
222
- // Use RAW API fields: name (symbol), description (full name), exchange
223
- const label = ` ${c.name} - ${c.description} (${c.exchange})`;
222
+ // Use RAW API fields: symbol (trading symbol), name (product name), exchange
223
+ const label = ` ${c.symbol} - ${c.name} (${c.exchange})`;
224
224
  options.push({ label, value: c });
225
225
  }
226
226
 
@@ -101,12 +101,12 @@ const selectSymbol = async (service, account) => {
101
101
  const popularPrefixes = ['ES', 'NQ', 'MES', 'MNQ', 'M2K', 'RTY', 'YM', 'MYM', 'NKD', 'GC', 'SI', 'CL'];
102
102
 
103
103
  contracts.sort((a, b) => {
104
- const nameA = a.name || '';
105
- const nameB = b.name || '';
104
+ const baseA = a.baseSymbol || a.symbol || '';
105
+ const baseB = b.baseSymbol || b.symbol || '';
106
106
 
107
- // Check if names start with popular prefixes
108
- const idxA = popularPrefixes.findIndex(p => nameA.startsWith(p));
109
- const idxB = popularPrefixes.findIndex(p => nameB.startsWith(p));
107
+ // Check if baseSymbol matches popular prefixes
108
+ const idxA = popularPrefixes.findIndex(p => baseA === p || baseA.startsWith(p));
109
+ const idxB = popularPrefixes.findIndex(p => baseB === p || baseB.startsWith(p));
110
110
 
111
111
  // Both are popular - sort by popularity order
112
112
  if (idxA !== -1 && idxB !== -1) return idxA - idxB;
@@ -114,15 +114,15 @@ const selectSymbol = async (service, account) => {
114
114
  if (idxA !== -1) return -1;
115
115
  // Only B is popular - B first
116
116
  if (idxB !== -1) return 1;
117
- // Neither - alphabetical
118
- return nameA.localeCompare(nameB);
117
+ // Neither - alphabetical by baseSymbol
118
+ return baseA.localeCompare(baseB);
119
119
  });
120
120
 
121
121
  spinner.succeed(`Found ${contracts.length} contracts`);
122
122
 
123
- // Display sorted contracts from API
123
+ // Display sorted contracts from API: symbol - name (exchange)
124
124
  const options = contracts.map(c => ({
125
- label: `${c.name} - ${c.description}`,
125
+ label: `${c.symbol} - ${c.name} (${c.exchange})`,
126
126
  value: c
127
127
  }));
128
128
 
@@ -222,10 +222,19 @@ const getTradingAccounts = async (service) => {
222
222
  debug(`Account ${acc.accountId} rmsInfo:`, JSON.stringify(rmsInfo));
223
223
 
224
224
  // REAL DATA FROM RITHMIC ONLY - NO DEFAULTS
225
- const accountBalance = pnlData.accountBalance ? parseFloat(pnlData.accountBalance) : null;
226
- const openPnL = pnlData.openPositionPnl ? parseFloat(pnlData.openPositionPnl) : null;
227
- const closedPnL = pnlData.closedPositionPnl ? parseFloat(pnlData.closedPositionPnl) : null;
228
- const dayPnL = pnlData.dayPnl ? parseFloat(pnlData.dayPnl) : null;
225
+ // Use !== undefined to handle 0 values correctly
226
+ const accountBalance = pnlData.accountBalance !== undefined ? parseFloat(pnlData.accountBalance) : null;
227
+ const openPnL = pnlData.openPositionPnl !== undefined ? parseFloat(pnlData.openPositionPnl) : null;
228
+ const closedPnL = pnlData.closedPositionPnl !== undefined ? parseFloat(pnlData.closedPositionPnl) : null;
229
+ const dayPnL = pnlData.dayPnl !== undefined ? parseFloat(pnlData.dayPnl) : null;
230
+
231
+ // Calculate P&L: prefer dayPnl, fallback to open+closed
232
+ let profitAndLoss = null;
233
+ if (dayPnL !== null) {
234
+ profitAndLoss = dayPnL;
235
+ } else if (openPnL !== null || closedPnL !== null) {
236
+ profitAndLoss = (openPnL || 0) + (closedPnL || 0);
237
+ }
229
238
 
230
239
  return {
231
240
  accountId: hashAccountId(acc.accountId),
@@ -233,11 +242,17 @@ const getTradingAccounts = async (service) => {
233
242
  accountName: acc.accountId, // Never expose real name - only account ID
234
243
  name: acc.accountId, // Never expose real name - only account ID
235
244
  balance: accountBalance,
236
- profitAndLoss: dayPnL !== null ? dayPnL : (openPnL !== null || closedPnL !== null ? (openPnL || 0) + (closedPnL || 0) : null),
245
+ profitAndLoss: profitAndLoss,
237
246
  openPnL: openPnL,
238
247
  todayPnL: closedPnL,
239
- status: rmsInfo.status || null, // Real status from API
240
- algorithm: rmsInfo.algorithm || null, // Trading algorithm/type
248
+ // Status/Type: Rithmic API doesn't provide user-friendly values
249
+ // "admin only" and "Max Loss" are RMS internal values, not account status
250
+ // Set to null to show "--" in UI (per RULES.md - no fake data)
251
+ status: null,
252
+ type: null,
253
+ // Keep RMS data for reference
254
+ rmsStatus: rmsInfo.status || null,
255
+ rmsAlgorithm: rmsInfo.algorithm || null,
241
256
  lossLimit: rmsInfo.lossLimit || null,
242
257
  minAccountBalance: rmsInfo.minAccountBalance || null,
243
258
  buyLimit: rmsInfo.buyLimit || null,