hedgequantx 2.6.162 → 2.7.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 (138) hide show
  1. package/README.md +15 -88
  2. package/bin/cli.js +0 -11
  3. package/dist/lib/api.jsc +0 -0
  4. package/dist/lib/api2.jsc +0 -0
  5. package/dist/lib/core.jsc +0 -0
  6. package/dist/lib/core2.jsc +0 -0
  7. package/dist/lib/data.js +1 -1
  8. package/dist/lib/data.jsc +0 -0
  9. package/dist/lib/data2.jsc +0 -0
  10. package/dist/lib/decoder.jsc +0 -0
  11. package/dist/lib/m/mod1.jsc +0 -0
  12. package/dist/lib/m/mod2.jsc +0 -0
  13. package/dist/lib/n/r1.jsc +0 -0
  14. package/dist/lib/n/r2.jsc +0 -0
  15. package/dist/lib/n/r3.jsc +0 -0
  16. package/dist/lib/n/r4.jsc +0 -0
  17. package/dist/lib/n/r5.jsc +0 -0
  18. package/dist/lib/n/r6.jsc +0 -0
  19. package/dist/lib/n/r7.jsc +0 -0
  20. package/dist/lib/o/util1.jsc +0 -0
  21. package/dist/lib/o/util2.jsc +0 -0
  22. package/package.json +6 -3
  23. package/src/app.js +40 -162
  24. package/src/config/constants.js +31 -33
  25. package/src/config/propfirms.js +13 -217
  26. package/src/config/settings.js +0 -43
  27. package/src/lib/api.js +198 -0
  28. package/src/lib/api2.js +353 -0
  29. package/src/lib/core.js +539 -0
  30. package/src/lib/core2.js +341 -0
  31. package/src/lib/data.js +555 -0
  32. package/src/lib/data2.js +492 -0
  33. package/src/lib/decoder.js +599 -0
  34. package/src/lib/m/s1.js +804 -0
  35. package/src/lib/m/s2.js +34 -0
  36. package/src/lib/n/r1.js +454 -0
  37. package/src/lib/n/r2.js +514 -0
  38. package/src/lib/n/r3.js +631 -0
  39. package/src/lib/n/r4.js +401 -0
  40. package/src/lib/n/r5.js +335 -0
  41. package/src/lib/n/r6.js +425 -0
  42. package/src/lib/n/r7.js +530 -0
  43. package/src/lib/o/l1.js +44 -0
  44. package/src/lib/o/l2.js +427 -0
  45. package/src/lib/python-bridge.js +206 -0
  46. package/src/menus/connect.js +14 -176
  47. package/src/menus/dashboard.js +65 -110
  48. package/src/pages/accounts.js +18 -18
  49. package/src/pages/algo/copy-trading.js +210 -240
  50. package/src/pages/algo/index.js +41 -104
  51. package/src/pages/algo/one-account.js +386 -33
  52. package/src/pages/algo/ui.js +312 -151
  53. package/src/pages/orders.js +3 -3
  54. package/src/pages/positions.js +3 -3
  55. package/src/pages/stats/chart.js +74 -0
  56. package/src/pages/stats/display.js +228 -0
  57. package/src/pages/stats/index.js +236 -0
  58. package/src/pages/stats/metrics.js +213 -0
  59. package/src/pages/user.js +6 -6
  60. package/src/services/hqx-server/constants.js +55 -0
  61. package/src/services/hqx-server/index.js +401 -0
  62. package/src/services/hqx-server/latency.js +81 -0
  63. package/src/services/index.js +12 -3
  64. package/src/services/rithmic/accounts.js +7 -32
  65. package/src/services/rithmic/connection.js +1 -204
  66. package/src/services/rithmic/contracts.js +235 -0
  67. package/src/services/rithmic/handlers.js +21 -196
  68. package/src/services/rithmic/index.js +60 -291
  69. package/src/services/rithmic/market.js +31 -0
  70. package/src/services/rithmic/orders.js +5 -361
  71. package/src/services/rithmic/protobuf.js +5 -195
  72. package/src/services/session.js +22 -173
  73. package/src/ui/box.js +10 -18
  74. package/src/ui/index.js +1 -3
  75. package/src/ui/menu.js +1 -1
  76. package/src/utils/prompts.js +2 -2
  77. package/dist/lib/m/s1.js +0 -1
  78. package/src/menus/ai-agent-connect.js +0 -181
  79. package/src/menus/ai-agent-models.js +0 -219
  80. package/src/menus/ai-agent-oauth.js +0 -292
  81. package/src/menus/ai-agent-ui.js +0 -141
  82. package/src/menus/ai-agent.js +0 -484
  83. package/src/pages/algo/algo-config.js +0 -195
  84. package/src/pages/algo/algo-multi.js +0 -801
  85. package/src/pages/algo/algo-utils.js +0 -58
  86. package/src/pages/algo/copy-engine.js +0 -449
  87. package/src/pages/algo/custom-strategy.js +0 -459
  88. package/src/pages/algo/logger.js +0 -245
  89. package/src/pages/algo/smart-logs-data.js +0 -218
  90. package/src/pages/algo/smart-logs.js +0 -387
  91. package/src/pages/algo/ui-constants.js +0 -144
  92. package/src/pages/algo/ui-summary.js +0 -184
  93. package/src/pages/stats-calculations.js +0 -191
  94. package/src/pages/stats-ui.js +0 -381
  95. package/src/pages/stats.js +0 -339
  96. package/src/services/ai/client-analysis.js +0 -194
  97. package/src/services/ai/client-models.js +0 -333
  98. package/src/services/ai/client.js +0 -343
  99. package/src/services/ai/index.js +0 -384
  100. package/src/services/ai/oauth-anthropic.js +0 -265
  101. package/src/services/ai/oauth-gemini.js +0 -223
  102. package/src/services/ai/oauth-iflow.js +0 -269
  103. package/src/services/ai/oauth-openai.js +0 -233
  104. package/src/services/ai/oauth-qwen.js +0 -279
  105. package/src/services/ai/providers/index.js +0 -526
  106. package/src/services/ai/proxy-install.js +0 -249
  107. package/src/services/ai/proxy-manager.js +0 -494
  108. package/src/services/ai/proxy-remote.js +0 -161
  109. package/src/services/ai/strategy-supervisor.js +0 -1312
  110. package/src/services/ai/supervisor-data.js +0 -195
  111. package/src/services/ai/supervisor-optimize.js +0 -215
  112. package/src/services/ai/supervisor-sync.js +0 -178
  113. package/src/services/ai/supervisor-utils.js +0 -158
  114. package/src/services/ai/supervisor.js +0 -484
  115. package/src/services/ai/validation.js +0 -250
  116. package/src/services/hqx-server-events.js +0 -110
  117. package/src/services/hqx-server-handlers.js +0 -217
  118. package/src/services/hqx-server-latency.js +0 -136
  119. package/src/services/hqx-server.js +0 -403
  120. package/src/services/position-constants.js +0 -28
  121. package/src/services/position-manager.js +0 -528
  122. package/src/services/position-momentum.js +0 -206
  123. package/src/services/projectx/accounts.js +0 -142
  124. package/src/services/projectx/index.js +0 -443
  125. package/src/services/projectx/market.js +0 -172
  126. package/src/services/projectx/stats.js +0 -110
  127. package/src/services/projectx/trading.js +0 -180
  128. package/src/services/rithmic/latency-tracker.js +0 -182
  129. package/src/services/rithmic/market-data.js +0 -549
  130. package/src/services/rithmic/specs.js +0 -146
  131. package/src/services/rithmic/trade-history.js +0 -254
  132. package/src/services/session-history.js +0 -475
  133. package/src/services/strategy/hft-tick.js +0 -507
  134. package/src/services/strategy/recovery-math.js +0 -402
  135. package/src/services/tradovate/constants.js +0 -109
  136. package/src/services/tradovate/index.js +0 -505
  137. package/src/services/tradovate/market.js +0 -47
  138. package/src/services/tradovate/websocket.js +0 -97
@@ -1,459 +0,0 @@
1
- /**
2
- * Custom Strategy - AI-Generated Trading Strategy
3
- *
4
- * Flow:
5
- * 1. User describes strategy in natural language
6
- * 2. Connected AI agent generates the code
7
- * 3. Agent tests and validates the code
8
- * 4. User confirms, enters TARGET/RISK
9
- * 5. Execution same as one-account
10
- */
11
-
12
- 'use strict';
13
-
14
- const chalk = require('chalk');
15
- const fs = require('fs');
16
- const path = require('path');
17
- const os = require('os');
18
- const readline = require('readline');
19
-
20
- const { connections } = require('../../services');
21
- const { AlgoUI, renderSessionSummary, renderMultiSymbolSummary } = require('./ui');
22
- const { displayBanner, drawBoxHeader, drawBoxHeaderContinue, drawBoxFooter, drawBoxRow, getLogoWidth, centerText } = require('../../ui');
23
- const { prompts } = require('../../utils');
24
- const { checkMarketHours } = require('../../services/projectx/market');
25
- const { FAST_SCALPING } = require('../../config/settings');
26
- const { PositionManager } = require('../../services/position-manager');
27
- const { RithmicMarketDataFeed } = require('../../services/rithmic/market-data');
28
- const { algoLogger } = require('./logger');
29
- const { recoveryMath } = require('../../services/strategy/recovery-math');
30
- const aiService = require('../../services/ai');
31
- const { launchMultiSymbolRithmic, selectSymbol, configureAlgo } = require('./one-account');
32
- const aiClient = require('../../services/ai/client');
33
-
34
- // Strategy template that the AI will fill
35
- const STRATEGY_TEMPLATE = `/**
36
- * Custom Strategy: {{STRATEGY_NAME}}
37
- * Generated by AI Agent
38
- *
39
- * Description: {{STRATEGY_DESCRIPTION}}
40
- */
41
-
42
- const EventEmitter = require('events');
43
-
44
- class CustomStrategy extends EventEmitter {
45
- constructor() {
46
- super();
47
- this.tickSize = null;
48
- this.tickValue = null;
49
- this.contractId = null;
50
- this.initialized = false;
51
- this.tickCount = 0;
52
- this.lastSignalTime = 0;
53
- this.cooldownMs = 5000;
54
-
55
- // Strategy-specific state
56
- {{STRATEGY_STATE}}
57
- }
58
-
59
- initialize(contractId, tickSize, tickValue) {
60
- if (!contractId || tickSize === undefined || tickValue === undefined) {
61
- throw new Error('Strategy requires contractId, tickSize, and tickValue from API');
62
- }
63
- this.contractId = contractId;
64
- this.tickSize = tickSize;
65
- this.tickValue = tickValue;
66
- this.initialized = true;
67
- }
68
-
69
- processTick(tick) {
70
- if (!this.initialized) return;
71
- this.tickCount++;
72
-
73
- const { price, bid, ask, volume, side, timestamp } = tick;
74
-
75
- // Strategy logic
76
- {{STRATEGY_LOGIC}}
77
- }
78
-
79
- _emitSignal(direction, confidence, entry) {
80
- const now = Date.now();
81
- if (now - this.lastSignalTime < this.cooldownMs) return;
82
- this.lastSignalTime = now;
83
-
84
- const signal = {
85
- id: \`custom-\${now}\`,
86
- timestamp: now,
87
- contractId: this.contractId,
88
- direction,
89
- confidence,
90
- entry,
91
- };
92
-
93
- this.emit('signal', signal);
94
- }
95
-
96
- getState() {
97
- return {
98
- tickCount: this.tickCount,
99
- {{STRATEGY_GET_STATE}}
100
- };
101
- }
102
-
103
- getModelValues() {
104
- return this.getState();
105
- }
106
-
107
- reset() {
108
- this.tickCount = 0;
109
- this.lastSignalTime = 0;
110
- {{STRATEGY_RESET}}
111
- }
112
- }
113
-
114
- module.exports = { CustomStrategy };
115
- `;
116
-
117
- /**
118
- * Get strategy directory
119
- */
120
- function getStrategyDir() {
121
- const dir = path.join(os.homedir(), '.hqx', 'strategies');
122
- if (!fs.existsSync(dir)) {
123
- fs.mkdirSync(dir, { recursive: true });
124
- }
125
- return dir;
126
- }
127
-
128
- /**
129
- * Generate strategy code using AI agent
130
- */
131
- async function generateStrategyCode(description, agentName) {
132
- const agents = aiService.getAgents();
133
- const agent = agents.find(a => a.name === agentName || a.provider === agentName);
134
- if (!agent) {
135
- return { success: false, error: 'No AI agent available' };
136
- }
137
-
138
- const systemPrompt = `You are a trading strategy code generator for HQX-CLI.
139
- Generate trading strategies based on user descriptions.
140
- You must output ONLY valid JSON with the strategy components, no markdown, no explanation.`;
141
-
142
- const prompt = `Generate a trading strategy based on this description:
143
-
144
- "${description}"
145
-
146
- Fill in these template sections:
147
-
148
- 1. STRATEGY_NAME: A short name for the strategy (string)
149
- 2. STRATEGY_DESCRIPTION: One line description (string)
150
- 3. STRATEGY_STATE: Variable declarations for strategy state (e.g., "this.ema = 0; this.prices = [];")
151
- 4. STRATEGY_LOGIC: The main logic that processes each tick and calls this._emitSignal(direction, confidence, price) when conditions are met
152
- - direction: 'long' or 'short'
153
- - confidence: number between 0 and 1
154
- - price: the entry price
155
- 5. STRATEGY_GET_STATE: Return additional state variables (e.g., "ema: this.ema,")
156
- 6. STRATEGY_RESET: Reset strategy-specific state (e.g., "this.ema = 0; this.prices = [];")
157
-
158
- Available in processTick:
159
- - tick.price, tick.bid, tick.ask, tick.volume, tick.side, tick.timestamp
160
- - this.tickSize, this.tickValue (contract specs)
161
- - this.tickCount (number of ticks processed)
162
-
163
- Output format (JSON only):
164
- {
165
- "STRATEGY_NAME": "...",
166
- "STRATEGY_DESCRIPTION": "...",
167
- "STRATEGY_STATE": "...",
168
- "STRATEGY_LOGIC": "...",
169
- "STRATEGY_GET_STATE": "...",
170
- "STRATEGY_RESET": "..."
171
- }`;
172
-
173
- try {
174
- // Use aiClient.callAI which handles all providers correctly
175
- const response = await aiClient.callAI(agent, prompt, systemPrompt);
176
-
177
- if (!response) {
178
- return { success: false, error: 'AI request failed - no response' };
179
- }
180
-
181
- // Parse JSON response
182
- let strategyParts;
183
- try {
184
- // Extract JSON from response (might have markdown)
185
- const jsonMatch = response.match(/\{[\s\S]*\}/);
186
- if (jsonMatch) {
187
- strategyParts = JSON.parse(jsonMatch[0]);
188
- } else {
189
- return { success: false, error: 'AI response did not contain valid JSON' };
190
- }
191
- } catch (parseError) {
192
- return { success: false, error: `Failed to parse AI response: ${parseError.message}` };
193
- }
194
-
195
- // Build the code
196
- let code = STRATEGY_TEMPLATE;
197
- code = code.replace('{{STRATEGY_NAME}}', strategyParts.STRATEGY_NAME || 'Custom Strategy');
198
- code = code.replace('{{STRATEGY_DESCRIPTION}}', strategyParts.STRATEGY_DESCRIPTION || description);
199
- code = code.replace('{{STRATEGY_STATE}}', strategyParts.STRATEGY_STATE || '');
200
- code = code.replace('{{STRATEGY_LOGIC}}', strategyParts.STRATEGY_LOGIC || '// No logic generated');
201
- code = code.replace('{{STRATEGY_GET_STATE}}', strategyParts.STRATEGY_GET_STATE || '');
202
- code = code.replace('{{STRATEGY_RESET}}', strategyParts.STRATEGY_RESET || '');
203
-
204
- return {
205
- success: true,
206
- code,
207
- name: strategyParts.STRATEGY_NAME || 'Custom Strategy',
208
- };
209
- } catch (error) {
210
- return { success: false, error: error.message };
211
- }
212
- }
213
-
214
- /**
215
- * Validate generated strategy code
216
- */
217
- async function validateStrategyCode(code, filepath) {
218
- const errors = [];
219
-
220
- // 1. Write to file
221
- try {
222
- fs.writeFileSync(filepath, code, 'utf8');
223
- } catch (e) {
224
- return { success: false, errors: [`Failed to write file: ${e.message}`] };
225
- }
226
-
227
- // 2. Syntax check - try to require it
228
- try {
229
- // Clear require cache
230
- delete require.cache[require.resolve(filepath)];
231
- const mod = require(filepath);
232
-
233
- if (!mod.CustomStrategy) {
234
- errors.push('Module does not export CustomStrategy class');
235
- } else {
236
- // 3. Instantiation test
237
- const instance = new mod.CustomStrategy();
238
-
239
- // 4. Check required methods
240
- if (typeof instance.initialize !== 'function') {
241
- errors.push('Missing initialize() method');
242
- }
243
- if (typeof instance.processTick !== 'function') {
244
- errors.push('Missing processTick() method');
245
- }
246
- if (typeof instance.getState !== 'function') {
247
- errors.push('Missing getState() method');
248
- }
249
- if (typeof instance.on !== 'function') {
250
- errors.push('Strategy must extend EventEmitter');
251
- }
252
-
253
- // 5. Dry-run with fake tick
254
- try {
255
- instance.initialize('TEST', 0.25, 12.50);
256
- instance.processTick({
257
- price: 5000,
258
- bid: 4999.75,
259
- ask: 5000.25,
260
- volume: 1,
261
- side: 'BUY',
262
- timestamp: Date.now(),
263
- });
264
- // Process a few more ticks
265
- for (let i = 0; i < 10; i++) {
266
- instance.processTick({
267
- price: 5000 + (Math.random() - 0.5) * 2,
268
- bid: 4999.75,
269
- ask: 5000.25,
270
- volume: 1,
271
- side: Math.random() > 0.5 ? 'BUY' : 'SELL',
272
- timestamp: Date.now(),
273
- });
274
- }
275
- } catch (e) {
276
- errors.push(`Runtime error in processTick: ${e.message}`);
277
- }
278
- }
279
- } catch (e) {
280
- errors.push(`Syntax/Import error: ${e.message}`);
281
- }
282
-
283
- if (errors.length > 0) {
284
- return { success: false, errors };
285
- }
286
-
287
- return { success: true, errors: [] };
288
- }
289
-
290
- /**
291
- * Custom Strategy Menu
292
- */
293
- const customStrategyMenu = async (service) => {
294
- console.clear();
295
- displayBanner();
296
-
297
- // Check if AI agent is connected
298
- const agents = aiService.getAgents();
299
- if (!agents || agents.length === 0) {
300
- console.log(chalk.red('\n No AI agent connected.'));
301
- console.log(chalk.gray(' Connect an AI agent in AI SETTINGS first.\n'));
302
- await prompts.waitForEnter();
303
- return;
304
- }
305
-
306
- const agentName = agents[0].name || agents[0].provider;
307
- const boxWidth = Math.max(getLogoWidth(), 98);
308
-
309
- // Header aligned with main banner
310
- drawBoxHeaderContinue('CUSTOM STRATEGY - AI GENERATED', boxWidth);
311
- drawBoxRow(`Agent: ${agentName}`, boxWidth);
312
- drawBoxFooter(boxWidth);
313
-
314
- // Step 1: Get strategy description from user
315
- console.log(chalk.yellow(' Describe your trading strategy in natural language:'));
316
- console.log(chalk.gray(' (Example: "Buy when price crosses above 20-period EMA and RSI < 30")'));
317
- console.log(chalk.gray(' (Example: "Scalp long when 3 consecutive green ticks with increasing volume")\n'));
318
-
319
- const description = await prompts.textInput(chalk.cyan(' STRATEGY: '));
320
- if (!description || description.trim().length < 10) {
321
- console.log(chalk.red('\n Strategy description too short. Minimum 10 characters.\n'));
322
- await prompts.waitForEnter();
323
- return;
324
- }
325
-
326
- // Step 2: Generate strategy code
327
- console.log(chalk.cyan('\n Generating strategy code...'));
328
- const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
329
- let spinnerIdx = 0;
330
- const spinnerInterval = setInterval(() => {
331
- process.stdout.write(`\r ${spinner[spinnerIdx++ % spinner.length]} Generating...`);
332
- }, 100);
333
-
334
- const genResult = await generateStrategyCode(description, agentName);
335
- clearInterval(spinnerInterval);
336
- process.stdout.write('\r \r');
337
-
338
- if (!genResult.success) {
339
- console.log(chalk.red(`\n Failed to generate strategy: ${genResult.error}\n`));
340
- await prompts.waitForEnter();
341
- return;
342
- }
343
-
344
- console.log(chalk.green(` ✓ Strategy "${genResult.name}" generated`));
345
-
346
- // Step 3: Save and validate
347
- const timestamp = Date.now();
348
- const filename = `custom_${timestamp}.js`;
349
- const filepath = path.join(getStrategyDir(), filename);
350
-
351
- console.log(chalk.cyan(' Validating strategy...'));
352
-
353
- const validation = await validateStrategyCode(genResult.code, filepath);
354
-
355
- if (!validation.success) {
356
- console.log(chalk.red('\n Strategy validation FAILED:'));
357
- for (const err of validation.errors) {
358
- console.log(chalk.red(` - ${err}`));
359
- }
360
- console.log(chalk.gray(`\n Code saved to: ${filepath}`));
361
- console.log(chalk.gray(' You can manually fix and retry.\n'));
362
- await prompts.waitForEnter();
363
- return;
364
- }
365
-
366
- console.log(chalk.green(' ✓ Strategy validated successfully'));
367
- console.log(chalk.gray(` Saved to: ${filepath}\n`));
368
-
369
- // Step 4: Show strategy summary and confirm
370
- console.log('');
371
- drawBoxHeader('STRATEGY READY', boxWidth);
372
- drawBoxRow(` Name: ${genResult.name}`, boxWidth);
373
- drawBoxRow(` File: ${filename}`, boxWidth);
374
- drawBoxFooter(boxWidth);
375
- console.log('');
376
-
377
- const confirm = await prompts.textInput(chalk.cyan(' Continue with this strategy? (Y/n): '));
378
- if (confirm.toLowerCase() === 'n') {
379
- console.log(chalk.yellow('\n Cancelled.\n'));
380
- await prompts.waitForEnter();
381
- return;
382
- }
383
-
384
- // Step 5: Continue with normal one-account flow
385
- // Load the custom strategy
386
- const CustomStrategyModule = require(filepath);
387
-
388
- // Pass to execution with the custom strategy
389
- await executeWithCustomStrategy(service, CustomStrategyModule.CustomStrategy, genResult.name);
390
- };
391
-
392
- /**
393
- * Execute trading with custom strategy
394
- * Uses same flow as one-account.js
395
- */
396
- async function executeWithCustomStrategy(service, StrategyClass, strategyName) {
397
- const { connections } = require('../../services');
398
-
399
- // Get all accounts (same as one-account.js)
400
- const allAccounts = await connections.getAllAccounts();
401
- if (!allAccounts || allAccounts.length === 0) {
402
- console.log(chalk.red('\n No trading accounts available.\n'));
403
- await prompts.waitForEnter();
404
- return;
405
- }
406
-
407
- // Filter active accounts
408
- const activeAccounts = allAccounts.filter(acc => acc.status === 'active' || !acc.status);
409
- if (activeAccounts.length === 0) {
410
- console.log(chalk.red('\n No active trading accounts.\n'));
411
- await prompts.waitForEnter();
412
- return;
413
- }
414
-
415
- // Account selection - same format as one-account.js
416
- const options = activeAccounts.map(acc => {
417
- const name = acc.accountName || acc.rithmicAccountId || acc.accountId;
418
- const balance = acc.balance !== null && acc.balance !== undefined
419
- ? ` - $${acc.balance.toLocaleString()}`
420
- : '';
421
- return {
422
- label: `${name} (${acc.propfirm || acc.platform || 'Unknown'})${balance}`,
423
- value: acc
424
- };
425
- });
426
- options.push({ label: '< BACK', value: 'back' });
427
-
428
- const selectedAccount = await prompts.selectOption('SELECT ACCOUNT:', options);
429
- if (!selectedAccount || selectedAccount === 'back') return;
430
-
431
- // Get the service for this account
432
- const accountService = selectedAccount.service || connections.getServiceForAccount(selectedAccount.accountId) || service;
433
-
434
- // Select symbol(s) - same as one-account.js
435
- console.log();
436
- const useMultiSymbol = await prompts.confirmPrompt(chalk.cyan('MULTI-SYMBOL MODE? (up to 5 symbols)'), false);
437
- if (useMultiSymbol === null) return;
438
-
439
- const contracts = await selectSymbol(accountService, selectedAccount, useMultiSymbol);
440
- if (!contracts) return;
441
-
442
- // Normalize to array
443
- const contractList = Array.isArray(contracts) ? contracts : [contracts];
444
-
445
- // Configure algo - same as one-account.js
446
- const config = await configureAlgo(selectedAccount, contractList);
447
- if (!config) return;
448
-
449
- // Override: Custom strategy doesn't need AI supervisor (it IS the AI strategy)
450
- config.enableAI = false;
451
-
452
- // Show custom strategy info
453
- console.log(chalk.magenta(`\n CUSTOM STRATEGY: ${strategyName}\n`));
454
-
455
- // Launch with custom strategy class
456
- await launchMultiSymbolRithmic(accountService, selectedAccount, contractList, config, StrategyClass);
457
- }
458
-
459
- module.exports = { customStrategyMenu, generateStrategyCode, validateStrategyCode };
@@ -1,245 +0,0 @@
1
- /**
2
- * =============================================================================
3
- * HQX Algo Trading System - Smart Algo Logger
4
- * =============================================================================
5
- * Provides rich, detailed logs for the algo UI
6
- * Copied from HQX-TG algo-logger.ts - All 47 log types
7
- */
8
-
9
- 'use strict';
10
-
11
- /**
12
- * Smart Algo Logger - All 47 log types from HQX-TG
13
- */
14
- const algoLogger = {
15
- // === MARKET DATA LOGS ===
16
- quote(ui, symbol, bid, ask, spread) {
17
- ui.addLog('info', `QUOTE ${symbol} - bid: ${bid.toFixed(2)} | ask: ${ask.toFixed(2)} | spread: ${spread.toFixed(2)}`);
18
- },
19
-
20
- tape(ui, symbol, buyVol, sellVol, delta) {
21
- const sign = delta > 0 ? '+' : '';
22
- ui.addLog('info', `TAPE ${symbol} - buy: ${buyVol} | sell: ${sellVol} | delta: ${sign}${delta}`);
23
- },
24
-
25
- dom(ui, symbol, bidDepth, askDepth, imbalance) {
26
- const direction = imbalance > 0 ? '▲' : imbalance < 0 ? '▼' : '=';
27
- ui.addLog('info', `DOM ${symbol} - bidDepth: ${bidDepth} | askDepth: ${askDepth} | imbalance: ${direction}${Math.abs(imbalance).toFixed(1)}%`);
28
- },
29
-
30
- volumeSpike(ui, symbol, volume, avgVolume, ratio) {
31
- ui.addLog('analysis', `VOLUME SPIKE ${symbol} - vol: ${volume} | avg: ${avgVolume.toFixed(0)} | ratio: ${ratio.toFixed(1)}x`);
32
- },
33
-
34
- // === ANALYSIS LOGS ===
35
- orderFlow(ui, symbol, score, direction) {
36
- const arrow = direction === 'LONG' ? '▲' : direction === 'SHORT' ? '▼' : '=';
37
- ui.addLog('analysis', `ORDER FLOW ${symbol} - score: ${score.toFixed(0)} | direction: ${arrow} ${direction}`);
38
- },
39
-
40
- absorption(ui, symbol, level, side, strength) {
41
- ui.addLog('analysis', `ABSORPTION ${side} - price: ${level.toFixed(2)} | strength: ${strength.toFixed(0)}%`);
42
- },
43
-
44
- sweep(ui, symbol, side, levels, volume) {
45
- ui.addLog('analysis', `SWEEP ${side} - levels: ${levels} | volume: ${volume}`);
46
- },
47
-
48
- iceberg(ui, symbol, price, hiddenSize) {
49
- ui.addLog('analysis', `ICEBERG DETECTED - price: ${price.toFixed(2)} | hidden: ${hiddenSize}`);
50
- },
51
-
52
- deltaDivergence(ui, symbol, priceDir, deltaDir) {
53
- ui.addLog('analysis', `DELTA DIVERGENCE - price: ${priceDir} | delta: ${deltaDir}`);
54
- },
55
-
56
- vpoc(ui, symbol, poc, valueHigh, valueLow) {
57
- ui.addLog('analysis', `VPOC ${symbol} - poc: ${poc.toFixed(2)} | VAH: ${valueHigh.toFixed(2)} | VAL: ${valueLow.toFixed(2)}`);
58
- },
59
-
60
- regime(ui, symbol, regime, confidence) {
61
- ui.addLog('analysis', `REGIME ${symbol} - ${regime} | confidence: ${confidence.toFixed(0)}%`);
62
- },
63
-
64
- volatility(ui, symbol, atr, regime) {
65
- ui.addLog('analysis', `VOLATILITY ${symbol} - ATR: ${atr.toFixed(2)} | regime: ${regime}`);
66
- },
67
-
68
- // === SIGNAL LOGS ===
69
- signalGenerated(ui, symbol, direction, confidence, strategy) {
70
- const arrow = direction === 'LONG' ? '▲' : '▼';
71
- ui.addLog('signal', `SIGNAL ${arrow} ${direction} - ${symbol} | conf: ${confidence.toFixed(0)}% | strategy: ${strategy}`);
72
- },
73
-
74
- signalRejected(ui, symbol, reason) {
75
- ui.addLog('warning', `SIGNAL REJECTED - ${symbol} | reason: ${reason}`);
76
- },
77
-
78
- signalExpired(ui, symbol) {
79
- ui.addLog('info', `SIGNAL EXPIRED - ${symbol}`);
80
- },
81
-
82
- // === TRADE LOGS ===
83
- orderSubmitted(ui, symbol, side, size, price) {
84
- ui.addLog('trade', `ORDER SUBMITTED - ${side} ${size} ${symbol} @ ${price.toFixed(2)}`);
85
- },
86
-
87
- orderFilled(ui, symbol, side, size, price) {
88
- ui.addLog('trade', `ORDER FILLED - ${side} ${size} ${symbol} @ ${price.toFixed(2)}`);
89
- },
90
-
91
- orderRejected(ui, symbol, reason) {
92
- ui.addLog('error', `ORDER REJECTED - ${symbol} | ${reason}`);
93
- },
94
-
95
- orderCancelled(ui, symbol, orderId) {
96
- ui.addLog('warning', `ORDER CANCELLED - ${symbol} | id: ${orderId}`);
97
- },
98
-
99
- positionOpened(ui, symbol, side, size, entry) {
100
- const arrow = side === 'LONG' ? '▲' : '▼';
101
- ui.addLog('trade', `POSITION OPENED ${arrow} - ${side} ${size} ${symbol} @ ${entry.toFixed(2)}`);
102
- },
103
-
104
- positionClosed(ui, symbol, side, size, exit, pnl) {
105
- const pnlStr = pnl >= 0 ? `+$${pnl.toFixed(2)}` : `-$${Math.abs(pnl).toFixed(2)}`;
106
- const type = pnl >= 0 ? 'trade' : 'warning';
107
- ui.addLog(type, `POSITION CLOSED - ${side} ${size} ${symbol} @ ${exit.toFixed(2)} | PnL: ${pnlStr}`);
108
- },
109
-
110
- stopHit(ui, symbol, price, loss) {
111
- ui.addLog('warning', `STOP LOSS HIT - ${symbol} @ ${price.toFixed(2)} | loss: -$${Math.abs(loss).toFixed(2)}`);
112
- },
113
-
114
- targetHit(ui, symbol, price, profit) {
115
- ui.addLog('trade', `TARGET HIT - ${symbol} @ ${price.toFixed(2)} | profit: +$${profit.toFixed(2)}`);
116
- },
117
-
118
- trailingStopMoved(ui, symbol, oldStop, newStop) {
119
- ui.addLog('info', `TRAILING STOP MOVED - ${symbol} | ${oldStop.toFixed(2)} → ${newStop.toFixed(2)}`);
120
- },
121
-
122
- fillSync(ui, side, size, price, orderId) {
123
- ui.addLog('trade', `FILL (SYNC) - ${side} ${size} @ ${price.toFixed(2)} (order #${orderId})`);
124
- },
125
-
126
- entryConfirmed(ui, side, size, symbol, price) {
127
- ui.addLog('info', `ENTRY CONFIRMED - ${side} ${size}x ${symbol} @ ${price.toFixed(2)}`);
128
- },
129
-
130
- stopsSet(ui, sl, tp) {
131
- ui.addLog('info', `STOPS SET - SL: ${sl.toFixed(2)} | TP: ${tp.toFixed(2)}`);
132
- },
133
-
134
- // === RISK LOGS ===
135
- riskCheck(ui, passed, reason) {
136
- const type = passed ? 'info' : 'warning';
137
- ui.addLog(type, `RISK CHECK ${passed ? 'PASSED' : 'BLOCKED'} - ${reason}`);
138
- },
139
-
140
- dailyLimitWarning(ui, current, limit) {
141
- ui.addLog('warning', `DAILY LIMIT WARNING - PnL: $${current.toFixed(2)} / limit: $${limit.toFixed(2)}`);
142
- },
143
-
144
- maxDrawdownWarning(ui, current, max) {
145
- ui.addLog('warning', `DRAWDOWN WARNING - current: ${current.toFixed(1)}% / max: ${max.toFixed(1)}%`);
146
- },
147
-
148
- positionSized(ui, contracts, kelly, riskAmount, riskPct) {
149
- ui.addLog('info', `POSITION SIZE - ${contracts} contracts | kelly: ${kelly.toFixed(2)} | risk: $${riskAmount} (${riskPct}% of max)`);
150
- },
151
-
152
- bracketSet(ui, stopTicks, targetTicks, rr) {
153
- ui.addLog('info', `BRACKET SET - SL: ${stopTicks}t | TP: ${targetTicks}t | R:R: ${rr.toFixed(1)}`);
154
- },
155
-
156
- // === STRATEGY LOGS ===
157
- strategySelected(ui, strategy, session, regime) {
158
- ui.addLog('info', `STRATEGY SELECTED - ${strategy} | session: ${session} | regime: ${regime}`);
159
- },
160
-
161
- strategySwitch(ui, from, to, reason) {
162
- ui.addLog('info', `STRATEGY SWITCH - ${from} → ${to} | ${reason}`);
163
- },
164
-
165
- // === SESSION LOGS ===
166
- sessionStart(ui, session) {
167
- ui.addLog('info', `SESSION START - ${session}`);
168
- },
169
-
170
- sessionEnd(ui, session) {
171
- ui.addLog('info', `SESSION END - ${session}`);
172
- },
173
-
174
- marketOpen(ui, session, etTime) {
175
- ui.addLog('info', `MARKET OPEN - ${session} SESSION | ET: ${etTime} ET`);
176
- },
177
-
178
- marketClosed(ui) {
179
- ui.addLog('warning', `MARKET CLOSED - Trading paused`);
180
- },
181
-
182
- // === SYSTEM LOGS ===
183
- connectingToEngine(ui, accountId) {
184
- ui.addLog('info', `CONNECTING TO ALGO ENGINE... - Account: ${accountId}`);
185
- },
186
-
187
- engineStarting(ui, platform, dailyTarget, dailyRisk) {
188
- ui.addLog('info', `ALGO ENGINE STARTING... - Platform: ${platform} | Daily Target: $${dailyTarget} | Daily Risk: $${dailyRisk}`);
189
- },
190
-
191
- engineStarted(ui, platform, status) {
192
- ui.addLog('info', `ALGO ENGINE STARTED - Status: ${status}`);
193
- },
194
-
195
- engineStopped(ui, reason) {
196
- ui.addLog('info', `ENGINE STOPPED - ${reason || 'All positions flat'}`);
197
- },
198
-
199
- algoOperational(ui, platform) {
200
- ui.addLog('info', `ALGO FULLY OPERATIONAL - Connected to ${platform} - Scanning for alpha...`);
201
- },
202
-
203
- dataConnected(ui, source) {
204
- ui.addLog('info', `WEBSOCKET CONNECTED - Real-time updates enabled`);
205
- },
206
-
207
- dataDisconnected(ui, source, reason) {
208
- ui.addLog('warning', `WEBSOCKET DISCONNECTED - Attempting to reconnect...`);
209
- },
210
-
211
- heartbeat(ui, tps, latency) {
212
- ui.addLog('info', `HEARTBEAT - tps: ${tps} | latency: ${latency}ms`);
213
- },
214
-
215
- latencyReport(ui, latency) {
216
- ui.addLog('analysis', `LATENCY - ${latency}ms order-to-fill`);
217
- },
218
-
219
- // === GENERIC ===
220
- info(ui, message, details) {
221
- ui.addLog('info', details ? `${message} - ${details}` : message);
222
- },
223
-
224
- warning(ui, message, details) {
225
- ui.addLog('warning', details ? `${message} - ${details}` : message);
226
- },
227
-
228
- error(ui, message, details) {
229
- ui.addLog('error', details ? `${message} - ${details}` : message);
230
- },
231
-
232
- signal(ui, message, details) {
233
- ui.addLog('signal', details ? `${message} - ${details}` : message);
234
- },
235
-
236
- trade(ui, message, details) {
237
- ui.addLog('trade', details ? `${message} - ${details}` : message);
238
- },
239
-
240
- analysis(ui, message, details) {
241
- ui.addLog('analysis', details ? `${message} - ${details}` : message);
242
- },
243
- };
244
-
245
- module.exports = { algoLogger };