hedgequantx 1.8.29 → 1.8.31
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/menus/connect.js +20 -18
- package/src/pages/algo/one-account.js +7 -2
- package/src/services/rithmic/index.js +39 -11
package/package.json
CHANGED
package/src/menus/connect.js
CHANGED
|
@@ -71,11 +71,11 @@ const projectXMenu = async () => {
|
|
|
71
71
|
console.log(chalk.cyan('║') + ' ' + chalk.red('[X] Back') + ' '.repeat(W - 10) + chalk.cyan('║'));
|
|
72
72
|
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
73
73
|
|
|
74
|
-
const
|
|
75
|
-
|
|
74
|
+
const input = await prompts.textInput(chalk.cyan('Select number (or X):'));
|
|
75
|
+
if (!input || input.toLowerCase() === 'x') return null;
|
|
76
76
|
|
|
77
|
-
const action =
|
|
78
|
-
if (
|
|
77
|
+
const action = parseInt(input);
|
|
78
|
+
if (isNaN(action) || action < 1 || action > numbered.length) return null;
|
|
79
79
|
|
|
80
80
|
const selectedPropfirm = numbered[action - 1];
|
|
81
81
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
@@ -142,11 +142,11 @@ const rithmicMenu = async () => {
|
|
|
142
142
|
console.log(chalk.cyan('║') + ' ' + chalk.red('[X] Back') + ' '.repeat(innerWidth - 10) + chalk.cyan('║'));
|
|
143
143
|
console.log(chalk.cyan('╚' + '═'.repeat(innerWidth) + '╝'));
|
|
144
144
|
|
|
145
|
-
const
|
|
146
|
-
|
|
145
|
+
const input = await prompts.textInput(chalk.cyan('Select number (or X):'));
|
|
146
|
+
if (!input || input.toLowerCase() === 'x') return null;
|
|
147
147
|
|
|
148
|
-
const action =
|
|
149
|
-
if (
|
|
148
|
+
const action = parseInt(input);
|
|
149
|
+
if (isNaN(action) || action < 1 || action > numbered.length) return null;
|
|
150
150
|
|
|
151
151
|
const selectedPropfirm = numbered[action - 1];
|
|
152
152
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
@@ -203,11 +203,11 @@ const tradovateMenu = async () => {
|
|
|
203
203
|
console.log(chalk.cyan('║') + ' ' + chalk.red('[X] Back') + ' '.repeat(innerWidth - 10) + chalk.cyan('║'));
|
|
204
204
|
console.log(chalk.cyan('╚' + '═'.repeat(innerWidth) + '╝'));
|
|
205
205
|
|
|
206
|
-
const
|
|
207
|
-
|
|
206
|
+
const input = await prompts.textInput(chalk.cyan('Select number (or X):'));
|
|
207
|
+
if (!input || input.toLowerCase() === 'x') return null;
|
|
208
208
|
|
|
209
|
-
const action =
|
|
210
|
-
if (
|
|
209
|
+
const action = parseInt(input);
|
|
210
|
+
if (isNaN(action) || action < 1 || action > numbered.length) return null;
|
|
211
211
|
|
|
212
212
|
const selectedPropfirm = numbered[action - 1];
|
|
213
213
|
const credentials = await loginPrompt(selectedPropfirm.name);
|
|
@@ -261,12 +261,14 @@ const addPropAccountMenu = async () => {
|
|
|
261
261
|
|
|
262
262
|
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
264
|
+
const input = await prompts.textInput(chalk.cyan('Select (1/2/3/X):'));
|
|
265
|
+
if (!input || input.toLowerCase() === 'x') return null;
|
|
266
|
+
|
|
267
|
+
const num = parseInt(input);
|
|
268
|
+
if (num === 1) return 'projectx';
|
|
269
|
+
if (num === 2) return 'rithmic';
|
|
270
|
+
if (num === 3) return 'tradovate';
|
|
271
|
+
return null;
|
|
270
272
|
};
|
|
271
273
|
|
|
272
274
|
module.exports = { loginPrompt, projectXMenu, rithmicMenu, tradovateMenu, addPropAccountMenu };
|
|
@@ -57,7 +57,8 @@ const oneAccountMenu = async (service) => {
|
|
|
57
57
|
const selectedAccount = await prompts.selectOption('Select Account:', options);
|
|
58
58
|
if (!selectedAccount || selectedAccount === 'back') return;
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
// Use the service attached to the account (from getAllAccounts), fallback to getServiceForAccount
|
|
61
|
+
const accountService = selectedAccount.service || connections.getServiceForAccount(selectedAccount.accountId) || service;
|
|
61
62
|
|
|
62
63
|
// Select symbol
|
|
63
64
|
const contract = await selectSymbol(accountService, selectedAccount);
|
|
@@ -150,6 +151,7 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
150
151
|
const stats = {
|
|
151
152
|
accountName, symbol: symbolName, contracts,
|
|
152
153
|
target: dailyTarget, risk: maxRisk,
|
|
154
|
+
propfirm: account.propfirm || 'Unknown',
|
|
153
155
|
pnl: 0, trades: 0, wins: 0, losses: 0,
|
|
154
156
|
latency: 0, connected: false
|
|
155
157
|
};
|
|
@@ -208,8 +210,11 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
208
210
|
if (stats.connected) {
|
|
209
211
|
ui.addLog('info', 'Starting algo...');
|
|
210
212
|
|
|
213
|
+
// Get Rithmic credentials from the account's service
|
|
211
214
|
let rithmicCreds = null;
|
|
212
|
-
if (service
|
|
215
|
+
if (service && service.getRithmicCredentials) {
|
|
216
|
+
rithmicCreds = service.getRithmicCredentials();
|
|
217
|
+
}
|
|
213
218
|
|
|
214
219
|
hqx.startAlgo({
|
|
215
220
|
accountId: account.accountId,
|
|
@@ -216,18 +216,46 @@ class RithmicService extends EventEmitter {
|
|
|
216
216
|
* For now, returns common futures contracts that are available on Rithmic
|
|
217
217
|
*/
|
|
218
218
|
async getContracts() {
|
|
219
|
-
//
|
|
219
|
+
// Calculate current front month dynamically
|
|
220
|
+
const now = new Date();
|
|
221
|
+
const month = now.getMonth();
|
|
222
|
+
const year = now.getFullYear() % 100;
|
|
223
|
+
|
|
224
|
+
// Quarterly months for index futures: H=Mar, M=Jun, U=Sep, Z=Dec
|
|
225
|
+
const quarterlyMonths = ['H', 'M', 'U', 'Z'];
|
|
226
|
+
const monthNames = ['Mar', 'Jun', 'Sep', 'Dec'];
|
|
227
|
+
const quarterIndex = Math.floor(month / 3);
|
|
228
|
+
|
|
229
|
+
// If past 15th of expiry month, use next quarter
|
|
230
|
+
let frontMonth = quarterlyMonths[quarterIndex];
|
|
231
|
+
let frontMonthName = monthNames[quarterIndex];
|
|
232
|
+
let frontYear = year;
|
|
233
|
+
|
|
234
|
+
if (now.getDate() > 15 && [2, 5, 8, 11].includes(month)) {
|
|
235
|
+
const nextIdx = (quarterIndex + 1) % 4;
|
|
236
|
+
frontMonth = quarterlyMonths[nextIdx];
|
|
237
|
+
frontMonthName = monthNames[nextIdx];
|
|
238
|
+
if (nextIdx === 0) frontYear++;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const y = frontYear; // e.g., 26 for 2026
|
|
242
|
+
const fy = `${frontYear}`; // full year string
|
|
243
|
+
|
|
220
244
|
const contracts = [
|
|
221
|
-
{ symbol:
|
|
222
|
-
{ symbol:
|
|
223
|
-
{ symbol:
|
|
224
|
-
{ symbol:
|
|
225
|
-
{ symbol:
|
|
226
|
-
{ symbol:
|
|
227
|
-
{ symbol:
|
|
228
|
-
{ symbol:
|
|
229
|
-
{ symbol:
|
|
230
|
-
{ symbol:
|
|
245
|
+
{ symbol: `ES${frontMonth}${y}`, name: `E-mini S&P 500 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
246
|
+
{ symbol: `NQ${frontMonth}${y}`, name: `E-mini NASDAQ-100 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
247
|
+
{ symbol: `MES${frontMonth}${y}`, name: `Micro E-mini S&P 500 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
248
|
+
{ symbol: `MNQ${frontMonth}${y}`, name: `Micro E-mini NASDAQ-100 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
249
|
+
{ symbol: `RTY${frontMonth}${y}`, name: `E-mini Russell 2000 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
250
|
+
{ symbol: `M2K${frontMonth}${y}`, name: `Micro E-mini Russell 2000 (${frontMonthName} ${fy})`, exchange: 'CME' },
|
|
251
|
+
{ symbol: `YM${frontMonth}${y}`, name: `E-mini Dow Jones (${frontMonthName} ${fy})`, exchange: 'CBOT' },
|
|
252
|
+
{ symbol: `MYM${frontMonth}${y}`, name: `Micro E-mini Dow Jones (${frontMonthName} ${fy})`, exchange: 'CBOT' },
|
|
253
|
+
{ symbol: `CL${frontMonth}${y}`, name: `Crude Oil (${frontMonthName} ${fy})`, exchange: 'NYMEX' },
|
|
254
|
+
{ symbol: `MCL${frontMonth}${y}`, name: `Micro Crude Oil (${frontMonthName} ${fy})`, exchange: 'NYMEX' },
|
|
255
|
+
{ symbol: `GC${frontMonth}${y}`, name: `Gold (${frontMonthName} ${fy})`, exchange: 'COMEX' },
|
|
256
|
+
{ symbol: `MGC${frontMonth}${y}`, name: `Micro Gold (${frontMonthName} ${fy})`, exchange: 'COMEX' },
|
|
257
|
+
{ symbol: `SI${frontMonth}${y}`, name: `Silver (${frontMonthName} ${fy})`, exchange: 'COMEX' },
|
|
258
|
+
{ symbol: `NG${frontMonth}${y}`, name: `Natural Gas (${frontMonthName} ${fy})`, exchange: 'NYMEX' },
|
|
231
259
|
];
|
|
232
260
|
return { success: true, contracts };
|
|
233
261
|
}
|