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.
- package/README.md +15 -88
- package/bin/cli.js +0 -11
- package/dist/lib/api.jsc +0 -0
- package/dist/lib/api2.jsc +0 -0
- package/dist/lib/core.jsc +0 -0
- package/dist/lib/core2.jsc +0 -0
- package/dist/lib/data.js +1 -1
- package/dist/lib/data.jsc +0 -0
- package/dist/lib/data2.jsc +0 -0
- package/dist/lib/decoder.jsc +0 -0
- package/dist/lib/m/mod1.jsc +0 -0
- package/dist/lib/m/mod2.jsc +0 -0
- package/dist/lib/n/r1.jsc +0 -0
- package/dist/lib/n/r2.jsc +0 -0
- package/dist/lib/n/r3.jsc +0 -0
- package/dist/lib/n/r4.jsc +0 -0
- package/dist/lib/n/r5.jsc +0 -0
- package/dist/lib/n/r6.jsc +0 -0
- package/dist/lib/n/r7.jsc +0 -0
- package/dist/lib/o/util1.jsc +0 -0
- package/dist/lib/o/util2.jsc +0 -0
- package/package.json +6 -3
- package/src/app.js +40 -162
- package/src/config/constants.js +31 -33
- package/src/config/propfirms.js +13 -217
- package/src/config/settings.js +0 -43
- package/src/lib/api.js +198 -0
- package/src/lib/api2.js +353 -0
- package/src/lib/core.js +539 -0
- package/src/lib/core2.js +341 -0
- package/src/lib/data.js +555 -0
- package/src/lib/data2.js +492 -0
- package/src/lib/decoder.js +599 -0
- package/src/lib/m/s1.js +804 -0
- package/src/lib/m/s2.js +34 -0
- package/src/lib/n/r1.js +454 -0
- package/src/lib/n/r2.js +514 -0
- package/src/lib/n/r3.js +631 -0
- package/src/lib/n/r4.js +401 -0
- package/src/lib/n/r5.js +335 -0
- package/src/lib/n/r6.js +425 -0
- package/src/lib/n/r7.js +530 -0
- package/src/lib/o/l1.js +44 -0
- package/src/lib/o/l2.js +427 -0
- package/src/lib/python-bridge.js +206 -0
- package/src/menus/connect.js +14 -176
- package/src/menus/dashboard.js +65 -110
- package/src/pages/accounts.js +18 -18
- package/src/pages/algo/copy-trading.js +210 -240
- package/src/pages/algo/index.js +41 -104
- package/src/pages/algo/one-account.js +386 -33
- package/src/pages/algo/ui.js +312 -151
- package/src/pages/orders.js +3 -3
- package/src/pages/positions.js +3 -3
- package/src/pages/stats/chart.js +74 -0
- package/src/pages/stats/display.js +228 -0
- package/src/pages/stats/index.js +236 -0
- package/src/pages/stats/metrics.js +213 -0
- package/src/pages/user.js +6 -6
- package/src/services/hqx-server/constants.js +55 -0
- package/src/services/hqx-server/index.js +401 -0
- package/src/services/hqx-server/latency.js +81 -0
- package/src/services/index.js +12 -3
- package/src/services/rithmic/accounts.js +7 -32
- package/src/services/rithmic/connection.js +1 -204
- package/src/services/rithmic/contracts.js +235 -0
- package/src/services/rithmic/handlers.js +21 -196
- package/src/services/rithmic/index.js +60 -291
- package/src/services/rithmic/market.js +31 -0
- package/src/services/rithmic/orders.js +5 -361
- package/src/services/rithmic/protobuf.js +5 -195
- package/src/services/session.js +22 -173
- package/src/ui/box.js +10 -18
- package/src/ui/index.js +1 -3
- package/src/ui/menu.js +1 -1
- package/src/utils/prompts.js +2 -2
- package/dist/lib/m/s1.js +0 -1
- package/src/menus/ai-agent-connect.js +0 -181
- package/src/menus/ai-agent-models.js +0 -219
- package/src/menus/ai-agent-oauth.js +0 -292
- package/src/menus/ai-agent-ui.js +0 -141
- package/src/menus/ai-agent.js +0 -484
- package/src/pages/algo/algo-config.js +0 -195
- package/src/pages/algo/algo-multi.js +0 -801
- package/src/pages/algo/algo-utils.js +0 -58
- package/src/pages/algo/copy-engine.js +0 -449
- package/src/pages/algo/custom-strategy.js +0 -459
- package/src/pages/algo/logger.js +0 -245
- package/src/pages/algo/smart-logs-data.js +0 -218
- package/src/pages/algo/smart-logs.js +0 -387
- package/src/pages/algo/ui-constants.js +0 -144
- package/src/pages/algo/ui-summary.js +0 -184
- package/src/pages/stats-calculations.js +0 -191
- package/src/pages/stats-ui.js +0 -381
- package/src/pages/stats.js +0 -339
- package/src/services/ai/client-analysis.js +0 -194
- package/src/services/ai/client-models.js +0 -333
- package/src/services/ai/client.js +0 -343
- package/src/services/ai/index.js +0 -384
- package/src/services/ai/oauth-anthropic.js +0 -265
- package/src/services/ai/oauth-gemini.js +0 -223
- package/src/services/ai/oauth-iflow.js +0 -269
- package/src/services/ai/oauth-openai.js +0 -233
- package/src/services/ai/oauth-qwen.js +0 -279
- package/src/services/ai/providers/index.js +0 -526
- package/src/services/ai/proxy-install.js +0 -249
- package/src/services/ai/proxy-manager.js +0 -494
- package/src/services/ai/proxy-remote.js +0 -161
- package/src/services/ai/strategy-supervisor.js +0 -1312
- package/src/services/ai/supervisor-data.js +0 -195
- package/src/services/ai/supervisor-optimize.js +0 -215
- package/src/services/ai/supervisor-sync.js +0 -178
- package/src/services/ai/supervisor-utils.js +0 -158
- package/src/services/ai/supervisor.js +0 -484
- package/src/services/ai/validation.js +0 -250
- package/src/services/hqx-server-events.js +0 -110
- package/src/services/hqx-server-handlers.js +0 -217
- package/src/services/hqx-server-latency.js +0 -136
- package/src/services/hqx-server.js +0 -403
- package/src/services/position-constants.js +0 -28
- package/src/services/position-manager.js +0 -528
- package/src/services/position-momentum.js +0 -206
- package/src/services/projectx/accounts.js +0 -142
- package/src/services/projectx/index.js +0 -443
- package/src/services/projectx/market.js +0 -172
- package/src/services/projectx/stats.js +0 -110
- package/src/services/projectx/trading.js +0 -180
- package/src/services/rithmic/latency-tracker.js +0 -182
- package/src/services/rithmic/market-data.js +0 -549
- package/src/services/rithmic/specs.js +0 -146
- package/src/services/rithmic/trade-history.js +0 -254
- package/src/services/session-history.js +0 -475
- package/src/services/strategy/hft-tick.js +0 -507
- package/src/services/strategy/recovery-math.js +0 -402
- package/src/services/tradovate/constants.js +0 -109
- package/src/services/tradovate/index.js +0 -505
- package/src/services/tradovate/market.js +0 -47
- package/src/services/tradovate/websocket.js +0 -97
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Qwen OAuth Authentication (Device Flow)
|
|
3
|
-
*
|
|
4
|
-
* Implements OAuth 2.0 Device Authorization Grant for Qwen Chat subscription.
|
|
5
|
-
* Based on the public OAuth flow used by Qwen Code CLI.
|
|
6
|
-
*
|
|
7
|
-
* Data source: Qwen OAuth API (https://chat.qwen.ai/api/v1/oauth2)
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const crypto = require('crypto');
|
|
11
|
-
const https = require('https');
|
|
12
|
-
|
|
13
|
-
// Public OAuth Client ID (from Qwen CLI)
|
|
14
|
-
const CLIENT_ID = 'f0304373b74a44d2b584a3fb70ca9e56';
|
|
15
|
-
const DEVICE_CODE_URL = 'https://chat.qwen.ai/api/v1/oauth2/device/code';
|
|
16
|
-
const TOKEN_URL = 'https://chat.qwen.ai/api/v1/oauth2/token';
|
|
17
|
-
const SCOPES = 'openid profile email model.completion';
|
|
18
|
-
const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Generate PKCE code verifier and challenge
|
|
22
|
-
* @returns {Object} { verifier: string, challenge: string }
|
|
23
|
-
*/
|
|
24
|
-
const generatePKCE = () => {
|
|
25
|
-
const verifier = crypto.randomBytes(32)
|
|
26
|
-
.toString('base64')
|
|
27
|
-
.replace(/\+/g, '-')
|
|
28
|
-
.replace(/\//g, '_')
|
|
29
|
-
.replace(/=/g, '');
|
|
30
|
-
|
|
31
|
-
const challenge = crypto.createHash('sha256')
|
|
32
|
-
.update(verifier)
|
|
33
|
-
.digest('base64')
|
|
34
|
-
.replace(/\+/g, '-')
|
|
35
|
-
.replace(/\//g, '_')
|
|
36
|
-
.replace(/=/g, '');
|
|
37
|
-
|
|
38
|
-
return { verifier, challenge };
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Make HTTPS request
|
|
43
|
-
*/
|
|
44
|
-
const makeRequest = (urlStr, options) => {
|
|
45
|
-
return new Promise((resolve, reject) => {
|
|
46
|
-
const url = new URL(urlStr);
|
|
47
|
-
const req = https.request({
|
|
48
|
-
hostname: url.hostname,
|
|
49
|
-
port: url.port || 443,
|
|
50
|
-
path: url.pathname + url.search,
|
|
51
|
-
method: options.method || 'POST',
|
|
52
|
-
headers: options.headers || {}
|
|
53
|
-
}, (res) => {
|
|
54
|
-
let data = '';
|
|
55
|
-
res.on('data', chunk => data += chunk);
|
|
56
|
-
res.on('end', () => {
|
|
57
|
-
try {
|
|
58
|
-
const json = JSON.parse(data);
|
|
59
|
-
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
60
|
-
resolve(json);
|
|
61
|
-
} else {
|
|
62
|
-
resolve({ ...json, statusCode: res.statusCode }); // Return error response for polling
|
|
63
|
-
}
|
|
64
|
-
} catch (e) {
|
|
65
|
-
reject(new Error(`Invalid JSON response: ${data.substring(0, 200)}`));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
req.on('error', reject);
|
|
71
|
-
|
|
72
|
-
if (options.body) {
|
|
73
|
-
req.write(options.body);
|
|
74
|
-
}
|
|
75
|
-
req.end();
|
|
76
|
-
});
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Initiate device authorization flow
|
|
81
|
-
* @returns {Promise<Object>} { deviceCode, userCode, verificationUri, verificationUriComplete, expiresIn, interval, verifier }
|
|
82
|
-
*/
|
|
83
|
-
const initiateDeviceFlow = async () => {
|
|
84
|
-
try {
|
|
85
|
-
const pkce = generatePKCE();
|
|
86
|
-
|
|
87
|
-
const body = new URLSearchParams({
|
|
88
|
-
client_id: CLIENT_ID,
|
|
89
|
-
scope: SCOPES,
|
|
90
|
-
code_challenge: pkce.challenge,
|
|
91
|
-
code_challenge_method: 'S256'
|
|
92
|
-
}).toString();
|
|
93
|
-
|
|
94
|
-
const response = await makeRequest(DEVICE_CODE_URL, {
|
|
95
|
-
method: 'POST',
|
|
96
|
-
headers: {
|
|
97
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
98
|
-
'Accept': 'application/json'
|
|
99
|
-
},
|
|
100
|
-
body
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
if (!response.device_code) {
|
|
104
|
-
return {
|
|
105
|
-
type: 'failed',
|
|
106
|
-
error: 'Device code not found in response'
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
type: 'success',
|
|
112
|
-
deviceCode: response.device_code,
|
|
113
|
-
userCode: response.user_code,
|
|
114
|
-
verificationUri: response.verification_uri,
|
|
115
|
-
verificationUriComplete: response.verification_uri_complete,
|
|
116
|
-
expiresIn: response.expires_in,
|
|
117
|
-
interval: response.interval || 5,
|
|
118
|
-
verifier: pkce.verifier
|
|
119
|
-
};
|
|
120
|
-
} catch (error) {
|
|
121
|
-
return {
|
|
122
|
-
type: 'failed',
|
|
123
|
-
error: error.message
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Poll for token (single attempt)
|
|
130
|
-
* @param {string} deviceCode - Device code from initiateDeviceFlow
|
|
131
|
-
* @param {string} verifier - PKCE code verifier
|
|
132
|
-
* @returns {Promise<Object>}
|
|
133
|
-
*/
|
|
134
|
-
const pollForToken = async (deviceCode, verifier) => {
|
|
135
|
-
try {
|
|
136
|
-
const body = new URLSearchParams({
|
|
137
|
-
grant_type: GRANT_TYPE,
|
|
138
|
-
client_id: CLIENT_ID,
|
|
139
|
-
device_code: deviceCode,
|
|
140
|
-
code_verifier: verifier
|
|
141
|
-
}).toString();
|
|
142
|
-
|
|
143
|
-
const response = await makeRequest(TOKEN_URL, {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: {
|
|
146
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
147
|
-
'Accept': 'application/json'
|
|
148
|
-
},
|
|
149
|
-
body
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Check for polling errors (RFC 8628)
|
|
153
|
-
if (response.error) {
|
|
154
|
-
switch (response.error) {
|
|
155
|
-
case 'authorization_pending':
|
|
156
|
-
return { type: 'pending' };
|
|
157
|
-
case 'slow_down':
|
|
158
|
-
return { type: 'slow_down' };
|
|
159
|
-
case 'expired_token':
|
|
160
|
-
return { type: 'failed', error: 'Device code expired. Please restart authentication.' };
|
|
161
|
-
case 'access_denied':
|
|
162
|
-
return { type: 'failed', error: 'Authorization denied by user.' };
|
|
163
|
-
default:
|
|
164
|
-
return { type: 'failed', error: response.error_description || response.error };
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Success
|
|
169
|
-
if (response.access_token) {
|
|
170
|
-
return {
|
|
171
|
-
type: 'success',
|
|
172
|
-
access: response.access_token,
|
|
173
|
-
refresh: response.refresh_token,
|
|
174
|
-
resourceUrl: response.resource_url,
|
|
175
|
-
expires: Date.now() + (response.expires_in * 1000)
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return { type: 'pending' };
|
|
180
|
-
} catch (error) {
|
|
181
|
-
return {
|
|
182
|
-
type: 'failed',
|
|
183
|
-
error: error.message
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Refresh access token using refresh token
|
|
190
|
-
* @param {string} refreshTokenValue - The refresh token
|
|
191
|
-
* @returns {Promise<Object>}
|
|
192
|
-
*/
|
|
193
|
-
const refreshToken = async (refreshTokenValue) => {
|
|
194
|
-
try {
|
|
195
|
-
const body = new URLSearchParams({
|
|
196
|
-
grant_type: 'refresh_token',
|
|
197
|
-
refresh_token: refreshTokenValue,
|
|
198
|
-
client_id: CLIENT_ID
|
|
199
|
-
}).toString();
|
|
200
|
-
|
|
201
|
-
const response = await makeRequest(TOKEN_URL, {
|
|
202
|
-
method: 'POST',
|
|
203
|
-
headers: {
|
|
204
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
205
|
-
'Accept': 'application/json'
|
|
206
|
-
},
|
|
207
|
-
body
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
if (response.error) {
|
|
211
|
-
return {
|
|
212
|
-
type: 'failed',
|
|
213
|
-
error: response.error_description || response.error
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
type: 'success',
|
|
219
|
-
access: response.access_token,
|
|
220
|
-
refresh: response.refresh_token,
|
|
221
|
-
resourceUrl: response.resource_url,
|
|
222
|
-
expires: Date.now() + (response.expires_in * 1000)
|
|
223
|
-
};
|
|
224
|
-
} catch (error) {
|
|
225
|
-
return {
|
|
226
|
-
type: 'failed',
|
|
227
|
-
error: error.message
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Get valid access token (refresh if expired)
|
|
234
|
-
* @param {Object} oauthData - OAuth data { access, refresh, expires }
|
|
235
|
-
* @returns {Promise<Object>}
|
|
236
|
-
*/
|
|
237
|
-
const getValidToken = async (oauthData) => {
|
|
238
|
-
if (!oauthData || !oauthData.refresh) {
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const expirationBuffer = 5 * 60 * 1000; // 5 minutes
|
|
243
|
-
if (oauthData.expires && oauthData.expires > Date.now() + expirationBuffer) {
|
|
244
|
-
return {
|
|
245
|
-
...oauthData,
|
|
246
|
-
refreshed: false
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const result = await refreshToken(oauthData.refresh);
|
|
251
|
-
if (result.type === 'success') {
|
|
252
|
-
return {
|
|
253
|
-
access: result.access,
|
|
254
|
-
refresh: result.refresh,
|
|
255
|
-
expires: result.expires,
|
|
256
|
-
refreshed: true
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return null;
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Check if credentials are OAuth tokens
|
|
265
|
-
*/
|
|
266
|
-
const isOAuthCredentials = (credentials) => {
|
|
267
|
-
return credentials && credentials.oauth && credentials.oauth.refresh;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
module.exports = {
|
|
271
|
-
CLIENT_ID,
|
|
272
|
-
SCOPES,
|
|
273
|
-
generatePKCE,
|
|
274
|
-
initiateDeviceFlow,
|
|
275
|
-
pollForToken,
|
|
276
|
-
refreshToken,
|
|
277
|
-
getValidToken,
|
|
278
|
-
isOAuthCredentials
|
|
279
|
-
};
|