hedgequantx 1.8.48 → 2.3.0

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.
Files changed (105) hide show
  1. package/README.md +7 -6
  2. package/bin/cli.js +13 -7
  3. package/dist/algo/copy-engine.js +3 -0
  4. package/dist/algo/copy-engine.jsc +0 -0
  5. package/dist/algo/engine.js +3 -0
  6. package/dist/algo/engine.jsc +0 -0
  7. package/dist/algo/market-data-rithmic.js +3 -0
  8. package/dist/algo/market-data-rithmic.jsc +0 -0
  9. package/dist/algo/market-data.js +3 -0
  10. package/dist/algo/market-data.jsc +0 -0
  11. package/dist/algo/rithmic/connection.js +3 -0
  12. package/dist/algo/rithmic/connection.jsc +0 -0
  13. package/dist/algo/rithmic/constants.js +3 -0
  14. package/dist/algo/rithmic/constants.jsc +0 -0
  15. package/dist/algo/rithmic/index.js +3 -0
  16. package/dist/algo/rithmic/index.jsc +0 -0
  17. package/dist/algo/rithmic/market-data.js +3 -0
  18. package/dist/algo/rithmic/market-data.jsc +0 -0
  19. package/dist/algo/rithmic/pnl.js +3 -0
  20. package/dist/algo/rithmic/pnl.jsc +0 -0
  21. package/dist/algo/rithmic/pool.js +3 -0
  22. package/dist/algo/rithmic/pool.jsc +0 -0
  23. package/dist/algo/rithmic/trading.js +3 -0
  24. package/dist/algo/rithmic/trading.jsc +0 -0
  25. package/dist/algo/rithmic-decoder.js +3 -0
  26. package/dist/algo/rithmic-decoder.jsc +0 -0
  27. package/dist/algo/strategies/ultra-scalping-v2.js +3 -0
  28. package/dist/algo/strategies/ultra-scalping-v2.jsc +0 -0
  29. package/dist/algo/strategies/ultra-scalping.js +3 -0
  30. package/dist/algo/strategies/ultra-scalping.jsc +0 -0
  31. package/dist/algo/trading-api-rithmic.js +3 -0
  32. package/dist/algo/trading-api-rithmic.jsc +0 -0
  33. package/dist/algo/trading-api.js +3 -0
  34. package/dist/algo/trading-api.jsc +0 -0
  35. package/dist/algo/utils/smart-logger.js +3 -0
  36. package/dist/algo/utils/smart-logger.jsc +0 -0
  37. package/dist/algo/utils/smart-logs.js +3 -0
  38. package/dist/algo/utils/smart-logs.jsc +0 -0
  39. package/package.json +33 -10
  40. package/protos/rithmic/account_pnl_position_update.proto +59 -0
  41. package/protos/rithmic/base.proto +7 -0
  42. package/protos/rithmic/best_bid_offer.proto +39 -0
  43. package/protos/rithmic/exchange_order_notification.proto +140 -0
  44. package/protos/rithmic/instrument_pnl_position_update.proto +50 -0
  45. package/protos/rithmic/last_trade.proto +53 -0
  46. package/protos/rithmic/request_account_list.proto +20 -0
  47. package/protos/rithmic/request_cancel_all_orders.proto +15 -0
  48. package/protos/rithmic/request_front_month_contract.proto +10 -0
  49. package/protos/rithmic/request_heartbeat.proto +13 -0
  50. package/protos/rithmic/request_login.proto +28 -0
  51. package/protos/rithmic/request_login_info.proto +10 -0
  52. package/protos/rithmic/request_logout.proto +10 -0
  53. package/protos/rithmic/request_market_data_update.proto +42 -0
  54. package/protos/rithmic/request_new_order.proto +84 -0
  55. package/protos/rithmic/request_pnl_position_snapshot.proto +14 -0
  56. package/protos/rithmic/request_pnl_position_updates.proto +20 -0
  57. package/protos/rithmic/request_product_codes.proto +9 -0
  58. package/protos/rithmic/request_rithmic_system_info.proto +8 -0
  59. package/protos/rithmic/request_show_order_history.proto +16 -0
  60. package/protos/rithmic/request_show_order_history_dates.proto +10 -0
  61. package/protos/rithmic/request_show_order_history_summary.proto +14 -0
  62. package/protos/rithmic/request_show_orders.proto +14 -0
  63. package/protos/rithmic/request_subscribe_for_order_updates.proto +14 -0
  64. package/protos/rithmic/request_tick_bar_replay.proto +48 -0
  65. package/protos/rithmic/request_trade_routes.proto +11 -0
  66. package/protos/rithmic/response_account_list.proto +18 -0
  67. package/protos/rithmic/response_front_month_contract.proto +13 -0
  68. package/protos/rithmic/response_heartbeat.proto +14 -0
  69. package/protos/rithmic/response_login.proto +18 -0
  70. package/protos/rithmic/response_login_info.proto +24 -0
  71. package/protos/rithmic/response_logout.proto +11 -0
  72. package/protos/rithmic/response_market_data_update.proto +9 -0
  73. package/protos/rithmic/response_new_order.proto +18 -0
  74. package/protos/rithmic/response_pnl_position_snapshot.proto +11 -0
  75. package/protos/rithmic/response_pnl_position_updates.proto +11 -0
  76. package/protos/rithmic/response_product_codes.proto +12 -0
  77. package/protos/rithmic/response_rithmic_system_info.proto +12 -0
  78. package/protos/rithmic/response_show_order_history.proto +11 -0
  79. package/protos/rithmic/response_show_order_history_dates.proto +13 -0
  80. package/protos/rithmic/response_show_order_history_summary.proto +11 -0
  81. package/protos/rithmic/response_show_orders.proto +11 -0
  82. package/protos/rithmic/response_subscribe_for_order_updates.proto +11 -0
  83. package/protos/rithmic/response_tick_bar_replay.proto +40 -0
  84. package/protos/rithmic/response_trade_routes.proto +19 -0
  85. package/protos/rithmic/rithmic_order_notification.proto +124 -0
  86. package/src/app.js +136 -89
  87. package/src/config/index.js +27 -8
  88. package/src/config/settings.js +155 -0
  89. package/src/pages/accounts.js +2 -3
  90. package/src/pages/algo/copy-trading.js +293 -200
  91. package/src/pages/algo/one-account.js +1 -1
  92. package/src/security/encryption.js +81 -46
  93. package/src/security/index.js +12 -8
  94. package/src/security/rateLimit.js +68 -65
  95. package/src/security/validation.js +93 -79
  96. package/src/services/hqx-server.js +538 -206
  97. package/src/services/projectx/index.js +327 -204
  98. package/src/services/rithmic/index.js +288 -285
  99. package/src/services/session.js +184 -114
  100. package/src/services/tradovate/index.js +286 -297
  101. package/src/ui/index.js +53 -1
  102. package/src/utils/http.js +236 -0
  103. package/src/utils/index.js +11 -2
  104. package/src/utils/logger.js +64 -33
  105. package/src/utils/prompts.js +79 -71
@@ -1,33 +1,16 @@
1
1
  /**
2
- * Centralized prompts utility
2
+ * @fileoverview Centralized prompts utility
3
+ * @module utils/prompts
4
+ *
3
5
  * Uses native readline for reliable stdin handling
4
6
  */
5
7
 
6
8
  const inquirer = require('inquirer');
7
9
  const readline = require('readline');
8
10
 
9
- // Shared readline instance
11
+ /** @type {readline.Interface|null} */
10
12
  let rl = null;
11
13
 
12
- // Prevent readline from exiting on SIGINT during prompts
13
- process.on('SIGINT', () => {
14
- // Let the main app handle SIGINT
15
- });
16
-
17
- /**
18
- * Get or create readline interface
19
- */
20
- const getReadline = () => {
21
- if (!rl || rl.closed) {
22
- rl = readline.createInterface({
23
- input: process.stdin,
24
- output: process.stdout,
25
- terminal: true
26
- });
27
- }
28
- return rl;
29
- };
30
-
31
14
  /**
32
15
  * Ensure stdin is ready and flush any buffered input
33
16
  */
@@ -37,56 +20,68 @@ const prepareStdin = () => {
37
20
  if (process.stdin.isTTY && process.stdin.setRawMode) {
38
21
  process.stdin.setRawMode(false);
39
22
  }
40
- // Flush any buffered input by reading without waiting
41
23
  process.stdin.read();
42
- } catch (e) {}
24
+ } catch {
25
+ // Ignore stdin errors
26
+ }
27
+ };
28
+
29
+ /**
30
+ * Close existing readline if open
31
+ * @private
32
+ */
33
+ const closeReadline = () => {
34
+ if (rl && !rl.closed) {
35
+ try {
36
+ rl.close();
37
+ } catch {
38
+ // Ignore close errors
39
+ }
40
+ rl = null;
41
+ }
43
42
  };
44
43
 
45
44
  /**
46
45
  * Native readline prompt
46
+ * @param {string} message - Prompt message
47
+ * @returns {Promise<string>}
47
48
  */
48
49
  const nativePrompt = (message) => {
49
50
  return new Promise((resolve) => {
50
51
  try {
51
52
  prepareStdin();
52
-
53
- // Always create a fresh readline for each prompt to avoid state issues
54
- if (rl && !rl.closed) {
55
- try { rl.close(); } catch (e) {}
56
- rl = null;
57
- }
58
-
53
+ closeReadline();
54
+
59
55
  rl = readline.createInterface({
60
56
  input: process.stdin,
61
57
  output: process.stdout,
62
- terminal: true
58
+ terminal: true,
63
59
  });
64
-
60
+
65
61
  let answered = false;
66
-
67
- rl.question(message + ' ', (answer) => {
62
+
63
+ rl.question(`${message} `, (answer) => {
68
64
  answered = true;
69
- try { rl.close(); } catch (e) {}
70
- rl = null;
65
+ closeReadline();
71
66
  resolve(answer || '');
72
67
  });
73
-
74
- // Handle readline close (e.g., Ctrl+C)
68
+
75
69
  rl.on('close', () => {
76
70
  if (!answered) {
77
71
  rl = null;
78
72
  resolve('');
79
73
  }
80
74
  });
81
-
82
- } catch (e) {
75
+ } catch {
83
76
  resolve('');
84
77
  }
85
78
  });
86
79
  };
87
80
 
88
81
  /**
89
- * Wait for Enter
82
+ * Wait for Enter key
83
+ * @param {string} [message='Press Enter to continue...'] - Message to display
84
+ * @returns {Promise<void>}
90
85
  */
91
86
  const waitForEnter = async (message = 'Press Enter to continue...') => {
92
87
  await nativePrompt(message);
@@ -94,6 +89,9 @@ const waitForEnter = async (message = 'Press Enter to continue...') => {
94
89
 
95
90
  /**
96
91
  * Text input
92
+ * @param {string} message - Prompt message
93
+ * @param {string} [defaultVal=''] - Default value
94
+ * @returns {Promise<string>}
97
95
  */
98
96
  const textInput = async (message, defaultVal = '') => {
99
97
  const value = await nativePrompt(message);
@@ -101,48 +99,63 @@ const textInput = async (message, defaultVal = '') => {
101
99
  };
102
100
 
103
101
  /**
104
- * Password input
102
+ * Password input (masked)
103
+ * @param {string} message - Prompt message
104
+ * @returns {Promise<string>}
105
105
  */
106
106
  const passwordInput = async (message) => {
107
- if (rl && !rl.closed) { rl.close(); rl = null; }
107
+ closeReadline();
108
108
  prepareStdin();
109
+
109
110
  const { value } = await inquirer.prompt([{
110
111
  type: 'password',
111
112
  name: 'value',
112
113
  message,
113
114
  mask: '*',
114
- prefix: ''
115
+ prefix: '',
115
116
  }]);
117
+
116
118
  return value;
117
119
  };
118
120
 
119
121
  /**
120
- * Confirm - arrow keys selection
122
+ * Confirm prompt with arrow keys
123
+ * @param {string} message - Prompt message
124
+ * @param {boolean} [defaultVal=true] - Default value
125
+ * @returns {Promise<boolean>}
121
126
  */
122
127
  const confirmPrompt = async (message, defaultVal = true) => {
123
- if (rl && !rl.closed) { rl.close(); rl = null; }
128
+ closeReadline();
124
129
  prepareStdin();
125
- const choices = defaultVal
130
+
131
+ const choices = defaultVal
126
132
  ? [{ name: 'Yes', value: true }, { name: 'No', value: false }]
127
133
  : [{ name: 'No', value: false }, { name: 'Yes', value: true }];
128
-
134
+
129
135
  const { value } = await inquirer.prompt([{
130
136
  type: 'list',
131
137
  name: 'value',
132
138
  message,
133
139
  choices,
134
140
  prefix: '',
135
- loop: false
141
+ loop: false,
136
142
  }]);
143
+
137
144
  return value;
138
145
  };
139
146
 
140
147
  /**
141
- * Number input
148
+ * Number input with validation
149
+ * @param {string} message - Prompt message
150
+ * @param {number} [defaultVal=1] - Default value
151
+ * @param {number} [min=1] - Minimum value
152
+ * @param {number} [max=1000] - Maximum value
153
+ * @returns {Promise<number>}
142
154
  */
143
155
  const numberInput = async (message, defaultVal = 1, min = 1, max = 1000) => {
144
- if (rl && !rl.closed) { rl.close(); rl = null; }
156
+ closeReadline();
145
157
  prepareStdin();
158
+
146
159
  const { value } = await inquirer.prompt([{
147
160
  type: 'input',
148
161
  name: 'value',
@@ -150,39 +163,34 @@ const numberInput = async (message, defaultVal = 1, min = 1, max = 1000) => {
150
163
  default: String(defaultVal),
151
164
  prefix: '',
152
165
  validate: (v) => {
153
- const n = parseInt(v);
166
+ const n = parseInt(v, 10);
154
167
  if (isNaN(n)) return 'Enter a number';
155
168
  if (n < min) return `Min: ${min}`;
156
169
  if (n > max) return `Max: ${max}`;
157
170
  return true;
158
- }
171
+ },
159
172
  }]);
160
- return parseInt(value) || defaultVal;
173
+
174
+ return parseInt(value, 10) || defaultVal;
161
175
  };
162
176
 
163
177
  /**
164
- * Select - arrow keys navigation
165
- * Supports disabled options (separators) via opt.disabled
178
+ * Select from options with arrow keys
179
+ * @param {string} message - Prompt message
180
+ * @param {Array<{label: string, value: any, disabled?: boolean}>} options - Options
181
+ * @returns {Promise<any>}
166
182
  */
167
183
  const selectOption = async (message, options) => {
168
- // Close shared readline before inquirer to avoid conflicts
169
- if (rl && !rl.closed) {
170
- rl.close();
171
- rl = null;
172
- }
184
+ closeReadline();
173
185
  prepareStdin();
174
-
186
+
175
187
  const choices = options.map(opt => {
176
188
  if (opt.disabled) {
177
- // Use inquirer Separator for disabled items (category headers)
178
189
  return new inquirer.Separator(opt.label);
179
190
  }
180
- return {
181
- name: opt.label,
182
- value: opt.value
183
- };
191
+ return { name: opt.label, value: opt.value };
184
192
  });
185
-
193
+
186
194
  const { value } = await inquirer.prompt([{
187
195
  type: 'list',
188
196
  name: 'value',
@@ -190,9 +198,9 @@ const selectOption = async (message, options) => {
190
198
  choices,
191
199
  prefix: '',
192
200
  loop: false,
193
- pageSize: 20 // Increased to show more symbols
201
+ pageSize: 20,
194
202
  }]);
195
-
203
+
196
204
  return value;
197
205
  };
198
206
 
@@ -203,5 +211,5 @@ module.exports = {
203
211
  passwordInput,
204
212
  confirmPrompt,
205
213
  numberInput,
206
- selectOption
214
+ selectOption,
207
215
  };