hedgequantx 2.9.35 → 2.9.37

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": "2.9.35",
3
+ "version": "2.9.37",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * One Account Mode - HQX Ultra Scalping
2
+ * One Account Mode - Trading with Strategy Selection
3
3
  * Supports multi-agent AI supervision
4
4
  */
5
5
 
@@ -12,6 +12,7 @@ const { checkMarketHours } = require('../../services/rithmic/market');
12
12
  const { executeAlgo } = require('./algo-executor');
13
13
  const { getActiveAgentCount, getSupervisionConfig, getActiveAgents } = require('../ai-agents');
14
14
  const { runPreflightCheck, formatPreflightResults, getPreflightSummary } = require('../../services/ai-supervision');
15
+ const { getAvailableStrategies } = require('../../lib/m');
15
16
 
16
17
 
17
18
 
@@ -77,8 +78,12 @@ const oneAccountMenu = async (service) => {
77
78
  const contract = await selectSymbol(accountService, selectedAccount);
78
79
  if (!contract) return;
79
80
 
81
+ // Select strategy
82
+ const strategy = await selectStrategy();
83
+ if (!strategy) return;
84
+
80
85
  // Configure algo
81
- const config = await configureAlgo(selectedAccount, contract);
86
+ const config = await configureAlgo(selectedAccount, contract, strategy);
82
87
  if (!config) return;
83
88
 
84
89
  // Check for AI Supervision
@@ -129,6 +134,7 @@ const oneAccountMenu = async (service) => {
129
134
  account: selectedAccount,
130
135
  contract,
131
136
  config,
137
+ strategy,
132
138
  options: { supervisionConfig }
133
139
  });
134
140
  };
@@ -182,12 +188,42 @@ const selectSymbol = async (service, account) => {
182
188
  return contract === 'back' || contract === null ? null : contract;
183
189
  };
184
190
 
191
+ /**
192
+ * Select trading strategy
193
+ */
194
+ const selectStrategy = async () => {
195
+ console.log();
196
+ console.log(chalk.cyan(' Select Strategy'));
197
+ console.log();
198
+
199
+ const strategies = getAvailableStrategies();
200
+
201
+ const options = strategies.map(s => ({
202
+ label: `${s.name} (${s.backtest.winRate} WR, R:R ${s.params.riskReward})`,
203
+ value: s
204
+ }));
205
+ options.push({ label: chalk.gray('< Back'), value: 'back' });
206
+
207
+ // Show strategy details
208
+ for (const s of strategies) {
209
+ console.log(chalk.white(` ${s.name}`));
210
+ console.log(chalk.gray(` ${s.description}`));
211
+ console.log(chalk.gray(` Backtest: ${s.backtest.pnl} | ${s.backtest.winRate} WR | ${s.backtest.trades} trades`));
212
+ console.log(chalk.gray(` Stop: ${s.params.stopTicks} ticks | Target: ${s.params.targetTicks} ticks | R:R ${s.params.riskReward}`));
213
+ console.log();
214
+ }
215
+
216
+ const selected = await prompts.selectOption(chalk.yellow('Select Strategy:'), options);
217
+ return selected === 'back' || selected === null ? null : selected;
218
+ };
219
+
185
220
  /**
186
221
  * Configure algo
187
222
  */
188
- const configureAlgo = async (account, contract) => {
223
+ const configureAlgo = async (account, contract, strategy) => {
189
224
  console.log();
190
225
  console.log(chalk.cyan(' Configure Algo Parameters'));
226
+ console.log(chalk.gray(` Strategy: ${strategy.name}`));
191
227
  console.log();
192
228
 
193
229
  const contracts = await prompts.numberInput('Number of contracts:', 1, 1, 10);
@@ -176,10 +176,13 @@ const fetchAllFrontMonths = (service) => {
176
176
 
177
177
  /**
178
178
  * Decode ProductCodes response
179
- * @param {Buffer} buffer - Protobuf buffer
179
+ * @param {Buffer} buffer - Protobuf buffer (with 4-byte length prefix)
180
180
  * @returns {Object} Decoded product data
181
181
  */
182
182
  const decodeProductCodes = (buffer) => {
183
+ // Skip 4-byte length prefix
184
+ const data = buffer.length > 4 ? buffer.slice(4) : buffer;
185
+
183
186
  const result = {};
184
187
  let offset = 0;
185
188
 
@@ -200,18 +203,18 @@ const decodeProductCodes = (buffer) => {
200
203
  return [buf.slice(newOff, newOff + len).toString('utf8'), newOff + len];
201
204
  };
202
205
 
203
- while (offset < buffer.length) {
206
+ while (offset < data.length) {
204
207
  try {
205
- const [tag, tagOff] = readVarint(buffer, offset);
208
+ const [tag, tagOff] = readVarint(data, offset);
206
209
  const wireType = tag & 0x7;
207
210
  const fieldNumber = tag >>> 3;
208
211
  offset = tagOff;
209
212
 
210
213
  if (wireType === 0) {
211
- const [, newOff] = readVarint(buffer, offset);
214
+ const [, newOff] = readVarint(data, offset);
212
215
  offset = newOff;
213
216
  } else if (wireType === 2) {
214
- const [val, newOff] = readString(buffer, offset);
217
+ const [val, newOff] = readString(data, offset);
215
218
  offset = newOff;
216
219
  if (fieldNumber === 110101) result.exchange = val;
217
220
  if (fieldNumber === 100749) result.productCode = val;
@@ -459,44 +459,48 @@ function decodeProductCodes(buffer) {
459
459
 
460
460
  /**
461
461
  * Decode ResponseFrontMonthContract (template 114) - current tradeable contract
462
+ * Skips 4-byte length prefix if present
462
463
  */
463
464
  function decodeFrontMonthContract(buffer) {
465
+ // Skip 4-byte length prefix
466
+ const data = buffer.length > 4 ? buffer.slice(4) : buffer;
467
+
464
468
  const result = { rpCode: [] };
465
469
  let offset = 0;
466
470
 
467
- while (offset < buffer.length) {
471
+ while (offset < data.length) {
468
472
  try {
469
- const [tag, tagOffset] = readVarint(buffer, offset);
473
+ const [tag, tagOffset] = readVarint(data, offset);
470
474
  const wireType = tag & 0x7;
471
475
  const fieldNumber = tag >>> 3;
472
476
  offset = tagOffset;
473
477
 
474
478
  switch (fieldNumber) {
475
479
  case SYMBOL_FIELDS.TEMPLATE_ID:
476
- [result.templateId, offset] = readVarint(buffer, offset);
480
+ [result.templateId, offset] = readVarint(data, offset);
477
481
  break;
478
482
  case SYMBOL_FIELDS.RP_CODE:
479
483
  let rpCode;
480
- [rpCode, offset] = readLengthDelimited(buffer, offset);
484
+ [rpCode, offset] = readLengthDelimited(data, offset);
481
485
  result.rpCode.push(rpCode);
482
486
  break;
483
487
  case SYMBOL_FIELDS.SYMBOL:
484
- [result.symbol, offset] = readLengthDelimited(buffer, offset);
488
+ [result.symbol, offset] = readLengthDelimited(data, offset);
485
489
  break;
486
490
  case SYMBOL_FIELDS.EXCHANGE:
487
- [result.exchange, offset] = readLengthDelimited(buffer, offset);
491
+ [result.exchange, offset] = readLengthDelimited(data, offset);
488
492
  break;
489
493
  case SYMBOL_FIELDS.TRADING_SYMBOL:
490
- [result.tradingSymbol, offset] = readLengthDelimited(buffer, offset);
494
+ [result.tradingSymbol, offset] = readLengthDelimited(data, offset);
491
495
  break;
492
496
  case SYMBOL_FIELDS.DESCRIPTION:
493
- [result.description, offset] = readLengthDelimited(buffer, offset);
497
+ [result.description, offset] = readLengthDelimited(data, offset);
494
498
  break;
495
499
  case SYMBOL_FIELDS.USER_MSG:
496
- [result.userMsg, offset] = readLengthDelimited(buffer, offset);
500
+ [result.userMsg, offset] = readLengthDelimited(data, offset);
497
501
  break;
498
502
  default:
499
- offset = skipField(buffer, offset, wireType);
503
+ offset = skipField(data, offset, wireType);
500
504
  }
501
505
  } catch (error) {
502
506
  break;