hedgequantx 1.3.9 → 1.3.11
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 +1 -1
- package/src/app.js +1 -1
- package/src/menus/connect.js +3 -3
- package/src/menus/dashboard.js +2 -2
- package/src/pages/accounts.js +1 -1
- package/src/pages/algo/copy-trading.js +1 -1
- package/src/pages/algo/one-account.js +3 -3
- package/src/pages/orders.js +1 -1
- package/src/pages/positions.js +1 -1
- package/src/pages/stats.js +1 -1
- package/src/pages/user.js +1 -1
- package/src/services/projectx/index.js +38 -4
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -286,7 +286,7 @@ const run = async () => {
|
|
|
286
286
|
await banner();
|
|
287
287
|
|
|
288
288
|
// Try to restore session
|
|
289
|
-
const spinner = ora('Restoring session...').start();
|
|
289
|
+
const spinner = ora({ text: 'Restoring session...', color: 'yellow' }).start();
|
|
290
290
|
const restored = await connections.restoreFromStorage();
|
|
291
291
|
|
|
292
292
|
if (restored) {
|
package/src/menus/connect.js
CHANGED
|
@@ -136,7 +136,7 @@ const projectXMenu = async () => {
|
|
|
136
136
|
const selectedPropfirm = numbered[selectedIdx];
|
|
137
137
|
|
|
138
138
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
139
|
-
const spinner = ora('Authenticating...').start();
|
|
139
|
+
const spinner = ora({ text: 'Authenticating...', color: 'yellow' }).start();
|
|
140
140
|
|
|
141
141
|
try {
|
|
142
142
|
const service = new ProjectXService(selectedPropfirm.key);
|
|
@@ -232,7 +232,7 @@ const rithmicMenu = async () => {
|
|
|
232
232
|
const selectedPropfirm = numbered[selectedIdx];
|
|
233
233
|
|
|
234
234
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
235
|
-
const spinner = ora('Connecting to Rithmic...').start();
|
|
235
|
+
const spinner = ora({ text: 'Connecting to Rithmic...', color: 'yellow' }).start();
|
|
236
236
|
|
|
237
237
|
try {
|
|
238
238
|
const service = new RithmicService(selectedPropfirm.key);
|
|
@@ -317,7 +317,7 @@ const tradovateMenu = async () => {
|
|
|
317
317
|
const selectedPropfirm = numbered[selectedIdx];
|
|
318
318
|
|
|
319
319
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
320
|
-
const spinner = ora('Connecting to Tradovate...').start();
|
|
320
|
+
const spinner = ora({ text: 'Connecting to Tradovate...', color: 'yellow' }).start();
|
|
321
321
|
|
|
322
322
|
try {
|
|
323
323
|
const service = new TradovateService(selectedPropfirm.key);
|
package/src/menus/dashboard.js
CHANGED
|
@@ -178,7 +178,7 @@ const handleUpdate = async () => {
|
|
|
178
178
|
currentVersion = 'unknown';
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
spinner = ora('Checking for updates...').start();
|
|
181
|
+
spinner = ora({ text: 'Checking for updates...', color: 'yellow' }).start();
|
|
182
182
|
|
|
183
183
|
// Check latest version on npm with timeout
|
|
184
184
|
spinner.text = 'Checking npm registry...';
|
|
@@ -235,7 +235,7 @@ const handleUpdate = async () => {
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
// Update via npm
|
|
238
|
-
spinner = ora(`Updating v${currentVersion} -> v${latestVersion}
|
|
238
|
+
spinner = ora({ text: `Updating v${currentVersion} -> v${latestVersion}...`, color: 'yellow' }).start();
|
|
239
239
|
|
|
240
240
|
try {
|
|
241
241
|
execSync('npm install -g hedgequantx@latest 2>/dev/null', {
|
package/src/pages/accounts.js
CHANGED
|
@@ -16,7 +16,7 @@ const { getLogoWidth, getColWidths, drawBoxHeader, drawBoxFooter, draw2ColHeader
|
|
|
16
16
|
* @param {Object} service - Current service
|
|
17
17
|
*/
|
|
18
18
|
const showAccounts = async (service) => {
|
|
19
|
-
const spinner = ora('Fetching accounts...').start();
|
|
19
|
+
const spinner = ora({ text: 'Fetching accounts...', color: 'yellow' }).start();
|
|
20
20
|
const boxWidth = getLogoWidth();
|
|
21
21
|
const { col1, col2 } = getColWidths(boxWidth);
|
|
22
22
|
|
|
@@ -249,7 +249,7 @@ const launchCopyTrading = async (config) => {
|
|
|
249
249
|
// Connect to HQX Server
|
|
250
250
|
const hqx = new HQXServerService();
|
|
251
251
|
|
|
252
|
-
const spinner = ora('Connecting to HQX Server...').start();
|
|
252
|
+
const spinner = ora({ text: 'Connecting to HQX Server...', color: 'yellow' }).start();
|
|
253
253
|
|
|
254
254
|
try {
|
|
255
255
|
const auth = await hqx.authenticate(lead.account.accountId.toString(), lead.propfirm || 'topstep');
|
|
@@ -17,7 +17,7 @@ const { AlgoUI, checkMarketStatus } = require('./ui');
|
|
|
17
17
|
* One Account Menu - Select account and launch
|
|
18
18
|
*/
|
|
19
19
|
const oneAccountMenu = async (service) => {
|
|
20
|
-
const spinner = ora('Fetching active accounts...').start();
|
|
20
|
+
const spinner = ora({ text: 'Fetching active accounts...', color: 'yellow' }).start();
|
|
21
21
|
|
|
22
22
|
// Get ALL accounts from ALL connections
|
|
23
23
|
const allAccounts = await connections.getAllAccounts();
|
|
@@ -76,7 +76,7 @@ const oneAccountMenu = async (service) => {
|
|
|
76
76
|
* Symbol selection
|
|
77
77
|
*/
|
|
78
78
|
const selectSymbol = async (service, account) => {
|
|
79
|
-
const spinner = ora('Loading contracts...').start();
|
|
79
|
+
const spinner = ora({ text: 'Loading contracts...', color: 'yellow' }).start();
|
|
80
80
|
|
|
81
81
|
const contractsResult = await service.getContracts();
|
|
82
82
|
if (!contractsResult.success) {
|
|
@@ -199,7 +199,7 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
199
199
|
// Connect to HQX Server
|
|
200
200
|
const hqx = new HQXServerService();
|
|
201
201
|
|
|
202
|
-
const spinner = ora('Connecting to HQX Server...').start();
|
|
202
|
+
const spinner = ora({ text: 'Connecting to HQX Server...', color: 'yellow' }).start();
|
|
203
203
|
|
|
204
204
|
try {
|
|
205
205
|
const auth = await hqx.authenticate(account.accountId.toString(), account.propfirm || 'topstep');
|
package/src/pages/orders.js
CHANGED
|
@@ -16,7 +16,7 @@ const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator
|
|
|
16
16
|
* @param {Object} service - Current service
|
|
17
17
|
*/
|
|
18
18
|
const showOrders = async (service) => {
|
|
19
|
-
const spinner = ora('Fetching orders...').start();
|
|
19
|
+
const spinner = ora({ text: 'Fetching orders...', color: 'yellow' }).start();
|
|
20
20
|
const boxWidth = getLogoWidth();
|
|
21
21
|
|
|
22
22
|
// Get all accounts first
|
package/src/pages/positions.js
CHANGED
|
@@ -16,7 +16,7 @@ const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator
|
|
|
16
16
|
* @param {Object} service - Current service
|
|
17
17
|
*/
|
|
18
18
|
const showPositions = async (service) => {
|
|
19
|
-
const spinner = ora('Fetching positions...').start();
|
|
19
|
+
const spinner = ora({ text: 'Fetching positions...', color: 'yellow' }).start();
|
|
20
20
|
const boxWidth = getLogoWidth();
|
|
21
21
|
const innerWidth = boxWidth - 2;
|
|
22
22
|
|
package/src/pages/stats.js
CHANGED
|
@@ -24,7 +24,7 @@ const {
|
|
|
24
24
|
* Show Stats Page
|
|
25
25
|
*/
|
|
26
26
|
const showStats = async (service) => {
|
|
27
|
-
const spinner = ora('Fetching stats for all accounts...').start();
|
|
27
|
+
const spinner = ora({ text: 'Fetching stats for all accounts...', color: 'yellow' }).start();
|
|
28
28
|
|
|
29
29
|
let allAccountsData = [];
|
|
30
30
|
|
package/src/pages/user.js
CHANGED
|
@@ -15,7 +15,7 @@ const { getLogoWidth, getColWidths, drawBoxHeader, drawBoxFooter, draw2ColHeader
|
|
|
15
15
|
* @param {Object} service - Current service
|
|
16
16
|
*/
|
|
17
17
|
const showUserInfo = async (service) => {
|
|
18
|
-
const spinner = ora('Fetching user info...').start();
|
|
18
|
+
const spinner = ora({ text: 'Fetching user info...', color: 'yellow' }).start();
|
|
19
19
|
const boxWidth = getLogoWidth();
|
|
20
20
|
const { col1, col2 } = getColWidths(boxWidth);
|
|
21
21
|
|
|
@@ -211,7 +211,10 @@ class ProjectXService {
|
|
|
211
211
|
|
|
212
212
|
// Get P&L for active accounts only
|
|
213
213
|
if (account.status === 0) {
|
|
214
|
-
|
|
214
|
+
let openPnL = 0;
|
|
215
|
+
let todayPnL = 0;
|
|
216
|
+
|
|
217
|
+
// 1. Get unrealized P&L from open positions
|
|
215
218
|
try {
|
|
216
219
|
const posRes = await this._request(
|
|
217
220
|
this.propfirm.userApi,
|
|
@@ -221,18 +224,49 @@ class ProjectXService {
|
|
|
221
224
|
debug(`Positions for ${account.accountId}:`, JSON.stringify(posRes.data, null, 2));
|
|
222
225
|
|
|
223
226
|
if (posRes.statusCode === 200 && Array.isArray(posRes.data)) {
|
|
224
|
-
let openPnL = 0;
|
|
225
227
|
for (const pos of posRes.data) {
|
|
226
228
|
if (pos.profitAndLoss !== undefined && pos.profitAndLoss !== null) {
|
|
227
229
|
openPnL += pos.profitAndLoss;
|
|
228
230
|
}
|
|
229
231
|
}
|
|
230
|
-
enriched.openPnL = openPnL;
|
|
231
|
-
enriched.profitAndLoss = openPnL; // Open P&L from positions
|
|
232
232
|
}
|
|
233
233
|
} catch (e) {
|
|
234
234
|
debug('Failed to get positions:', e.message);
|
|
235
235
|
}
|
|
236
|
+
|
|
237
|
+
// 2. Get realized P&L from today's closed trades
|
|
238
|
+
try {
|
|
239
|
+
const today = new Date();
|
|
240
|
+
today.setHours(0, 0, 0, 0);
|
|
241
|
+
const now = new Date();
|
|
242
|
+
|
|
243
|
+
const tradesRes = await this._request(
|
|
244
|
+
this.propfirm.gatewayApi,
|
|
245
|
+
'/api/Trade/search',
|
|
246
|
+
'POST',
|
|
247
|
+
{
|
|
248
|
+
accountId: account.accountId,
|
|
249
|
+
startTimestamp: today.toISOString(),
|
|
250
|
+
endTimestamp: now.toISOString()
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
debug(`Today trades for ${account.accountId}:`, JSON.stringify(tradesRes.data, null, 2));
|
|
254
|
+
|
|
255
|
+
if (tradesRes.statusCode === 200) {
|
|
256
|
+
const trades = Array.isArray(tradesRes.data) ? tradesRes.data : (tradesRes.data.trades || []);
|
|
257
|
+
for (const trade of trades) {
|
|
258
|
+
if (trade.profitAndLoss !== undefined && trade.profitAndLoss !== null) {
|
|
259
|
+
todayPnL += trade.profitAndLoss;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
} catch (e) {
|
|
264
|
+
debug('Failed to get today trades:', e.message);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
enriched.openPnL = openPnL;
|
|
268
|
+
enriched.todayPnL = todayPnL;
|
|
269
|
+
enriched.profitAndLoss = openPnL + todayPnL; // Total day P&L = unrealized + realized
|
|
236
270
|
}
|
|
237
271
|
|
|
238
272
|
debug(`Account ${account.accountId}:`, {
|