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,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Rithmic Trade History
|
|
3
|
-
* Handles trade history fetching and P&L calculation
|
|
4
|
-
*
|
|
5
|
-
* NO FAKE DATA - Only real values from Rithmic API
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { logger } = require('../../utils/logger');
|
|
9
|
-
const { getTickMultiplier } = require('./specs');
|
|
10
|
-
|
|
11
|
-
const log = logger.scope('RithmicTradeHistory');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get trade history from Rithmic API
|
|
15
|
-
* Uses RequestShowOrderHistory to fetch historical fills
|
|
16
|
-
* @param {Object} service - RithmicService instance
|
|
17
|
-
* @param {string} accountId - Optional account filter
|
|
18
|
-
* @param {number} days - Number of days to fetch (default: 30)
|
|
19
|
-
* @returns {Promise<{success: boolean, trades: Array}>}
|
|
20
|
-
*/
|
|
21
|
-
const getTradeHistory = async (service, accountId, days = 30) => {
|
|
22
|
-
if (!service.orderConn || !service.loginInfo) {
|
|
23
|
-
return { success: true, trades: service.completedTrades || [] };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return new Promise((resolve) => {
|
|
27
|
-
const historyOrders = [];
|
|
28
|
-
let resolved = false;
|
|
29
|
-
|
|
30
|
-
// Timeout after 5 seconds
|
|
31
|
-
const timeout = setTimeout(() => {
|
|
32
|
-
if (!resolved) {
|
|
33
|
-
resolved = true;
|
|
34
|
-
cleanup();
|
|
35
|
-
// Combine API history with session trades
|
|
36
|
-
const allTrades = [...processHistoryToTrades(historyOrders, service), ...service.completedTrades];
|
|
37
|
-
resolve({ success: true, trades: allTrades });
|
|
38
|
-
}
|
|
39
|
-
}, 5000);
|
|
40
|
-
|
|
41
|
-
// Listen for order history snapshots
|
|
42
|
-
const onOrderNotification = (data) => {
|
|
43
|
-
try {
|
|
44
|
-
if (data.isSnapshot || data.status === 'complete' || data.status === 'Complete') {
|
|
45
|
-
const order = {
|
|
46
|
-
orderId: data.orderId || data.orderTag,
|
|
47
|
-
accountId: data.accountId,
|
|
48
|
-
symbol: data.symbol,
|
|
49
|
-
exchange: data.exchange,
|
|
50
|
-
side: data.transactionType === 1 ? 0 : 1,
|
|
51
|
-
quantity: data.quantity || data.totalFillQuantity || 0,
|
|
52
|
-
fillPrice: data.avgFillPrice || data.lastFillPrice || 0,
|
|
53
|
-
timestamp: data.ssboe ? data.ssboe * 1000 : Date.now(),
|
|
54
|
-
status: data.status,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
if (order.quantity > 0 && order.fillPrice > 0) {
|
|
58
|
-
historyOrders.push(order);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
} catch (e) {
|
|
62
|
-
// Ignore parse errors
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const onHistoryComplete = () => {
|
|
67
|
-
if (!resolved) {
|
|
68
|
-
resolved = true;
|
|
69
|
-
cleanup();
|
|
70
|
-
const allTrades = [...processHistoryToTrades(historyOrders, service), ...service.completedTrades];
|
|
71
|
-
resolve({ success: true, trades: allTrades });
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const cleanup = () => {
|
|
76
|
-
clearTimeout(timeout);
|
|
77
|
-
service.removeListener('orderNotification', onOrderNotification);
|
|
78
|
-
service.removeListener('orderHistoryComplete', onHistoryComplete);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
service.on('orderNotification', onOrderNotification);
|
|
82
|
-
service.on('orderHistoryComplete', onHistoryComplete);
|
|
83
|
-
|
|
84
|
-
// Request order history for each account
|
|
85
|
-
try {
|
|
86
|
-
const accounts = accountId
|
|
87
|
-
? service.accounts.filter(a => a.accountId === accountId)
|
|
88
|
-
: service.accounts;
|
|
89
|
-
|
|
90
|
-
for (const acc of accounts) {
|
|
91
|
-
service.orderConn.send('RequestShowOrderHistory', {
|
|
92
|
-
templateId: 324,
|
|
93
|
-
userMsg: ['HQX-HISTORY'],
|
|
94
|
-
fcmId: acc.fcmId || service.loginInfo.fcmId,
|
|
95
|
-
ibId: acc.ibId || service.loginInfo.ibId,
|
|
96
|
-
accountId: acc.accountId,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
} catch (e) {
|
|
100
|
-
if (!resolved) {
|
|
101
|
-
resolved = true;
|
|
102
|
-
cleanup();
|
|
103
|
-
resolve({ success: false, error: e.message, trades: service.completedTrades || [] });
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Process historical orders into trades with P&L
|
|
111
|
-
* Matches entries and exits to calculate P&L
|
|
112
|
-
* @param {Array} orders - Historical orders
|
|
113
|
-
* @param {Object} service - RithmicService instance (for _getTickMultiplier)
|
|
114
|
-
* @returns {Array} Processed trades
|
|
115
|
-
*/
|
|
116
|
-
const processHistoryToTrades = (orders, service) => {
|
|
117
|
-
const trades = [];
|
|
118
|
-
const openPositions = new Map();
|
|
119
|
-
|
|
120
|
-
// Sort by timestamp (oldest first)
|
|
121
|
-
const sorted = [...orders].sort((a, b) => a.timestamp - b.timestamp);
|
|
122
|
-
|
|
123
|
-
for (const order of sorted) {
|
|
124
|
-
const key = `${order.accountId}:${order.symbol}`;
|
|
125
|
-
const open = openPositions.get(key);
|
|
126
|
-
|
|
127
|
-
if (open && open.side !== order.side) {
|
|
128
|
-
// Closing trade - calculate P&L
|
|
129
|
-
const closeQty = Math.min(order.quantity, open.quantity);
|
|
130
|
-
let pnl;
|
|
131
|
-
|
|
132
|
-
if (open.side === 0) {
|
|
133
|
-
pnl = (order.fillPrice - open.price) * closeQty;
|
|
134
|
-
} else {
|
|
135
|
-
pnl = (open.price - order.fillPrice) * closeQty;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const tickMultiplier = getTickMultiplier(order.symbol);
|
|
139
|
-
pnl = pnl * tickMultiplier;
|
|
140
|
-
|
|
141
|
-
trades.push({
|
|
142
|
-
id: order.orderId,
|
|
143
|
-
accountId: order.accountId,
|
|
144
|
-
symbol: order.symbol,
|
|
145
|
-
exchange: order.exchange,
|
|
146
|
-
side: open.side,
|
|
147
|
-
size: closeQty,
|
|
148
|
-
entryPrice: open.price,
|
|
149
|
-
exitPrice: order.fillPrice,
|
|
150
|
-
price: order.fillPrice,
|
|
151
|
-
timestamp: order.timestamp,
|
|
152
|
-
creationTimestamp: new Date(order.timestamp).toISOString(),
|
|
153
|
-
status: 'CLOSED',
|
|
154
|
-
profitAndLoss: pnl,
|
|
155
|
-
pnl: pnl,
|
|
156
|
-
fees: 0,
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const remaining = open.quantity - closeQty;
|
|
160
|
-
if (remaining <= 0) {
|
|
161
|
-
openPositions.delete(key);
|
|
162
|
-
} else {
|
|
163
|
-
open.quantity = remaining;
|
|
164
|
-
}
|
|
165
|
-
} else if (open && open.side === order.side) {
|
|
166
|
-
// Adding to position
|
|
167
|
-
const totalQty = open.quantity + order.quantity;
|
|
168
|
-
open.price = ((open.price * open.quantity) + (order.fillPrice * order.quantity)) / totalQty;
|
|
169
|
-
open.quantity = totalQty;
|
|
170
|
-
} else {
|
|
171
|
-
// Opening new position
|
|
172
|
-
openPositions.set(key, {
|
|
173
|
-
side: order.side,
|
|
174
|
-
quantity: order.quantity,
|
|
175
|
-
price: order.fillPrice,
|
|
176
|
-
timestamp: order.timestamp,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return trades;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Setup order fill listener for real-time P&L tracking
|
|
186
|
-
* @param {Object} service - RithmicService instance
|
|
187
|
-
*/
|
|
188
|
-
const setupOrderFillListener = (service) => {
|
|
189
|
-
service._openEntries = new Map();
|
|
190
|
-
|
|
191
|
-
service.on('orderFilled', (fillInfo) => {
|
|
192
|
-
const key = `${fillInfo.accountId}:${fillInfo.symbol}`;
|
|
193
|
-
const side = fillInfo.transactionType === 1 ? 0 : 1;
|
|
194
|
-
const qty = fillInfo.fillQuantity || fillInfo.totalFillQuantity || 0;
|
|
195
|
-
const price = fillInfo.avgFillPrice || fillInfo.lastFillPrice || 0;
|
|
196
|
-
|
|
197
|
-
const openEntry = service._openEntries.get(key);
|
|
198
|
-
let pnl = null;
|
|
199
|
-
|
|
200
|
-
if (openEntry && openEntry.side !== side) {
|
|
201
|
-
// Closing trade
|
|
202
|
-
const closeQty = Math.min(qty, openEntry.qty);
|
|
203
|
-
|
|
204
|
-
if (openEntry.side === 0) {
|
|
205
|
-
pnl = (price - openEntry.price) * closeQty;
|
|
206
|
-
} else {
|
|
207
|
-
pnl = (openEntry.price - price) * closeQty;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const remainingQty = openEntry.qty - closeQty;
|
|
211
|
-
if (remainingQty <= 0) {
|
|
212
|
-
service._openEntries.delete(key);
|
|
213
|
-
} else {
|
|
214
|
-
openEntry.qty = remainingQty;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
service.completedTrades.push({
|
|
218
|
-
id: fillInfo.orderId || fillInfo.orderTag,
|
|
219
|
-
orderTag: fillInfo.orderTag,
|
|
220
|
-
accountId: fillInfo.accountId,
|
|
221
|
-
symbol: fillInfo.symbol,
|
|
222
|
-
exchange: fillInfo.exchange,
|
|
223
|
-
side: openEntry.side,
|
|
224
|
-
size: closeQty,
|
|
225
|
-
entryPrice: openEntry.price,
|
|
226
|
-
exitPrice: price,
|
|
227
|
-
price: price,
|
|
228
|
-
timestamp: fillInfo.localTimestamp || Date.now(),
|
|
229
|
-
creationTimestamp: new Date().toISOString(),
|
|
230
|
-
status: 'CLOSED',
|
|
231
|
-
profitAndLoss: pnl,
|
|
232
|
-
pnl: pnl,
|
|
233
|
-
fees: 0,
|
|
234
|
-
});
|
|
235
|
-
log.debug('Trade closed', { symbol: fillInfo.symbol, pnl, trades: service.completedTrades.length });
|
|
236
|
-
} else {
|
|
237
|
-
// Opening or adding to position
|
|
238
|
-
if (openEntry && openEntry.side === side) {
|
|
239
|
-
const totalQty = openEntry.qty + qty;
|
|
240
|
-
openEntry.price = ((openEntry.price * openEntry.qty) + (price * qty)) / totalQty;
|
|
241
|
-
openEntry.qty = totalQty;
|
|
242
|
-
} else {
|
|
243
|
-
service._openEntries.set(key, { side, qty, price, timestamp: Date.now() });
|
|
244
|
-
}
|
|
245
|
-
log.debug('Position opened/added', { symbol: fillInfo.symbol, side, qty, price });
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
module.exports = {
|
|
251
|
-
getTradeHistory,
|
|
252
|
-
processHistoryToTrades,
|
|
253
|
-
setupOrderFillListener,
|
|
254
|
-
};
|