hedgequantx 1.8.14 → 1.8.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": "1.8.14",
3
+ "version": "1.8.15",
4
4
  "description": "Prop Futures Algo Trading CLI - Connect to Topstep, Alpha Futures, and other prop firms",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -213,7 +213,7 @@ const launchCopyTrading = async (config) => {
213
213
  const leadName = showNames ? (lead.account.accountName || lead.account.accountId) : 'HQX Lead *****';
214
214
  const followerName = showNames ? (follower.account.accountName || follower.account.accountId) : 'HQX Follower *****';
215
215
 
216
- const ui = new AlgoUI({ subtitle: 'HQX Copy Trading' });
216
+ const ui = new AlgoUI({ subtitle: 'HQX Copy Trading', mode: 'copy-trading' });
217
217
 
218
218
  const stats = {
219
219
  leadName, followerName,
@@ -132,7 +132,7 @@ const launchAlgo = async (service, account, contract, config) => {
132
132
  const accountName = showName ? (account.accountName || account.accountId) : 'HQX *****';
133
133
  const symbolName = contract.name || contract.symbol;
134
134
 
135
- const ui = new AlgoUI({ subtitle: 'HQX Ultra-Scalping' });
135
+ const ui = new AlgoUI({ subtitle: 'HQX Ultra-Scalping', mode: 'one-account' });
136
136
 
137
137
  const stats = {
138
138
  accountName, symbol: symbolName, contracts,
@@ -126,20 +126,83 @@ class AlgoUI {
126
126
 
127
127
  _drawStats(stats) {
128
128
  const { W } = this;
129
- const colL = 48, colR = 47;
130
- const pad = (len) => ' '.repeat(Math.max(0, len));
129
+ const isCopyTrading = this.config.mode === 'copy-trading';
131
130
 
132
131
  const pnlColor = stats.pnl >= 0 ? chalk.green : chalk.red;
133
132
  const pnlStr = (stats.pnl >= 0 ? '+$' : '-$') + Math.abs(stats.pnl).toFixed(2);
134
133
  const latencyColor = stats.latency < 100 ? chalk.green : (stats.latency < 300 ? chalk.yellow : chalk.red);
135
134
  const serverColor = stats.connected ? chalk.green : chalk.red;
136
135
 
137
- // Grid borders
136
+ if (isCopyTrading) {
137
+ this._drawCopyTradingStats(stats, pnlColor, pnlStr, latencyColor, serverColor);
138
+ } else {
139
+ this._drawOneAccountStats(stats, pnlColor, pnlStr, latencyColor, serverColor);
140
+ }
141
+ }
142
+
143
+ _drawOneAccountStats(stats, pnlColor, pnlStr, latencyColor, serverColor) {
144
+ const { W } = this;
145
+ const colL = 48, colR = 47;
146
+ const pad = (len) => ' '.repeat(Math.max(0, len));
147
+
148
+ const GT = BOX.ML + BOX.H.repeat(colL) + BOX.TM + BOX.H.repeat(colR) + BOX.MR;
149
+ const GM = BOX.ML + BOX.H.repeat(colL) + BOX.MM + BOX.H.repeat(colR) + BOX.MR;
150
+ const GB = BOX.ML + BOX.H.repeat(colL) + BOX.BM + BOX.H.repeat(colR) + BOX.MR;
151
+
152
+ const row = (c1, c2) => {
153
+ this._line(chalk.cyan(BOX.V) + c1 + chalk.cyan(BOX.VS) + c2 + chalk.cyan(BOX.V));
154
+ };
155
+
156
+ this._line(chalk.cyan(GT));
157
+
158
+ // Row 1: Account | Symbol
159
+ const accountName = (stats.accountName || 'N/A').substring(0, 40);
160
+ const symbol = (stats.symbol || 'N/A').substring(0, 35);
161
+ const r1c1 = buildCell('Account', accountName, chalk.cyan, colL);
162
+ const r1c2 = buildCell('Symbol', symbol, chalk.yellow, colR);
163
+ row(r1c1.padded, r1c2.padded);
164
+
165
+ this._line(chalk.cyan(GM));
166
+
167
+ // Row 2: Qty | P&L
168
+ const r2c1 = buildCell('Qty', (stats.qty || '1').toString(), chalk.cyan, colL);
169
+ const r2c2 = buildCell('P&L', pnlStr, pnlColor, colR);
170
+ row(r2c1.padded, r2c2.padded);
171
+
172
+ this._line(chalk.cyan(GM));
173
+
174
+ // Row 3: Target | Risk
175
+ const r3c1 = buildCell('Target', '$' + (stats.target || 0).toFixed(2), chalk.green, colL);
176
+ const r3c2 = buildCell('Risk', '$' + (stats.risk || 0).toFixed(2), chalk.red, colR);
177
+ row(r3c1.padded, r3c2.padded);
178
+
179
+ this._line(chalk.cyan(GM));
180
+
181
+ // Row 4: Trades | Server
182
+ const r4c1t = ` Trades: ${chalk.cyan(stats.trades || 0)} W/L: ${chalk.green(stats.wins || 0)}/${chalk.red(stats.losses || 0)}`;
183
+ const r4c1p = ` Trades: ${stats.trades || 0} W/L: ${stats.wins || 0}/${stats.losses || 0}`;
184
+ const r4c2 = buildCell('Server', stats.connected ? 'ON' : 'OFF', serverColor, colR);
185
+ row(r4c1t + pad(colL - r4c1p.length), r4c2.padded);
186
+
187
+ this._line(chalk.cyan(GM));
188
+
189
+ // Row 5: Latency | Platform
190
+ const r5c1 = buildCell('Latency', `${stats.latency || 0}ms`, latencyColor, colL);
191
+ const r5c2 = buildCell('Platform', stats.platform || 'N/A', chalk.cyan, colR);
192
+ row(r5c1.padded, r5c2.padded);
193
+
194
+ this._line(chalk.cyan(GB));
195
+ }
196
+
197
+ _drawCopyTradingStats(stats, pnlColor, pnlStr, latencyColor, serverColor) {
198
+ const { W } = this;
199
+ const colL = 48, colR = 47;
200
+ const pad = (len) => ' '.repeat(Math.max(0, len));
201
+
138
202
  const GT = BOX.ML + BOX.H.repeat(colL) + BOX.TM + BOX.H.repeat(colR) + BOX.MR;
139
203
  const GM = BOX.ML + BOX.H.repeat(colL) + BOX.MM + BOX.H.repeat(colR) + BOX.MR;
140
204
  const GB = BOX.ML + BOX.H.repeat(colL) + BOX.BM + BOX.H.repeat(colR) + BOX.MR;
141
205
 
142
- // Row builders
143
206
  const row = (c1, c2) => {
144
207
  this._line(chalk.cyan(BOX.V) + c1 + chalk.cyan(BOX.VS) + c2 + chalk.cyan(BOX.V));
145
208
  };
@@ -147,9 +210,8 @@ class AlgoUI {
147
210
  this._line(chalk.cyan(GT));
148
211
 
149
212
  // Row 1: Lead Account | Follower Account
150
- const leadName = (stats.leadName || stats.accountName || 'N/A').substring(0, 40);
213
+ const leadName = (stats.leadName || 'N/A').substring(0, 40);
151
214
  const followerName = (stats.followerName || 'N/A').substring(0, 40);
152
-
153
215
  const r1c1 = buildCell('Lead', leadName, chalk.cyan, colL);
154
216
  const r1c2 = buildCell('Follower', followerName, chalk.magenta, colR);
155
217
  row(r1c1.padded, r1c2.padded);
@@ -158,8 +220,7 @@ class AlgoUI {
158
220
 
159
221
  // Row 2: Lead Symbol | Follower Symbol
160
222
  const leadSymbol = (stats.leadSymbol || stats.symbol || 'N/A').substring(0, 35);
161
- const followerSymbol = (stats.followerSymbol || 'N/A').substring(0, 35);
162
-
223
+ const followerSymbol = (stats.followerSymbol || stats.symbol || 'N/A').substring(0, 35);
163
224
  const r2c1 = buildCell('Symbol', leadSymbol, chalk.yellow, colL);
164
225
  const r2c2 = buildCell('Symbol', followerSymbol, chalk.yellow, colR);
165
226
  row(r2c1.padded, r2c2.padded);
@@ -167,11 +228,8 @@ class AlgoUI {
167
228
  this._line(chalk.cyan(GM));
168
229
 
169
230
  // Row 3: Lead Qty | Follower Qty
170
- const leadQty = stats.leadQty || '1';
171
- const followerQty = stats.followerQty || '1';
172
-
173
- const r3c1 = buildCell('Qty', leadQty.toString(), chalk.cyan, colL);
174
- const r3c2 = buildCell('Qty', followerQty.toString(), chalk.cyan, colR);
231
+ const r3c1 = buildCell('Qty', (stats.leadQty || '1').toString(), chalk.cyan, colL);
232
+ const r3c2 = buildCell('Qty', (stats.followerQty || '1').toString(), chalk.cyan, colR);
175
233
  row(r3c1.padded, r3c2.padded);
176
234
 
177
235
  this._line(chalk.cyan(GM));