hedgequantx 2.6.163 → 2.7.1
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 +8 -5
- 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 +116 -99
- package/src/services/rithmic/handlers.js +21 -196
- package/src/services/rithmic/index.js +63 -120
- package/src/services/rithmic/market.js +31 -0
- package/src/services/rithmic/orders.js +5 -111
- package/src/services/rithmic/protobuf.js +384 -138
- 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/direct-providers.js +0 -323
- package/src/services/ai/providers/index.js +0 -62
- package/src/services/ai/providers/other-providers.js +0 -104
- 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-exit-logic.js +0 -174
- package/src/services/position-manager.js +0 -438
- 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-decoders.js +0 -229
- package/src/services/rithmic/market-data.js +0 -272
- package/src/services/rithmic/orders-fast.js +0 -246
- package/src/services/rithmic/proto-decoders.js +0 -403
- 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-signal-calc.js +0 -147
- package/src/services/strategy/hft-tick.js +0 -407
- package/src/services/strategy/recovery-math.js +0 -402
- package/src/services/tradovate/constants.js +0 -109
- package/src/services/tradovate/index.js +0 -392
- package/src/services/tradovate/market.js +0 -47
- package/src/services/tradovate/orders.js +0 -145
- package/src/services/tradovate/websocket.js +0 -97
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* =============================================================================
|
|
3
|
-
* HFT TICK-BY-TICK STRATEGY
|
|
4
|
-
* =============================================================================
|
|
5
|
-
* Pure tick-based strategy for high-frequency trading
|
|
6
|
-
* No bars, no candles - every tick counts
|
|
7
|
-
*
|
|
8
|
-
* MODELS:
|
|
9
|
-
* 1. Order Flow Imbalance (OFI) - Real-time buy/sell pressure
|
|
10
|
-
* 2. Cumulative Delta - Net volume direction
|
|
11
|
-
* 3. Bid/Ask Pressure - Spread and size analysis
|
|
12
|
-
* 4. Momentum - Price velocity and acceleration
|
|
13
|
-
* 5. Mean Reversion - Z-score on tick prices
|
|
14
|
-
*
|
|
15
|
-
* SIGNALS:
|
|
16
|
-
* - Generated on each tick when conditions align
|
|
17
|
-
* - Sub-second decision making
|
|
18
|
-
* - Designed for <50ms execution
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const EventEmitter = require('events');
|
|
22
|
-
const { logger } = require('../../utils/logger');
|
|
23
|
-
const { calculateSignal, buildSignal } = require('./hft-signal-calc');
|
|
24
|
-
|
|
25
|
-
const log = logger.scope('HFT');
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Circular buffer for efficient tick storage
|
|
29
|
-
*/
|
|
30
|
-
class CircularBuffer {
|
|
31
|
-
constructor(size) {
|
|
32
|
-
this.size = size;
|
|
33
|
-
this.buffer = new Array(size);
|
|
34
|
-
this.head = 0;
|
|
35
|
-
this.count = 0;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
push(item) {
|
|
39
|
-
this.buffer[this.head] = item;
|
|
40
|
-
this.head = (this.head + 1) % this.size;
|
|
41
|
-
if (this.count < this.size) this.count++;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get(index) {
|
|
45
|
-
if (index >= this.count) return null;
|
|
46
|
-
const actualIndex = (this.head - this.count + index + this.size) % this.size;
|
|
47
|
-
return this.buffer[actualIndex];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
getLast(n = 1) {
|
|
51
|
-
const result = [];
|
|
52
|
-
const count = Math.min(n, this.count);
|
|
53
|
-
for (let i = this.count - count; i < this.count; i++) {
|
|
54
|
-
result.push(this.get(i));
|
|
55
|
-
}
|
|
56
|
-
return result;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
getAll() {
|
|
60
|
-
return this.getLast(this.count);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get length() {
|
|
64
|
-
return this.count;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
clear() {
|
|
68
|
-
this.head = 0;
|
|
69
|
-
this.count = 0;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* HFT Tick Strategy
|
|
75
|
-
*/
|
|
76
|
-
class HFTTickStrategy extends EventEmitter {
|
|
77
|
-
constructor() {
|
|
78
|
-
super();
|
|
79
|
-
|
|
80
|
-
// Configuration - MUST be set via initialize() with API data
|
|
81
|
-
this.tickSize = null;
|
|
82
|
-
this.tickValue = null;
|
|
83
|
-
this.contractId = null;
|
|
84
|
-
this.initialized = false;
|
|
85
|
-
|
|
86
|
-
// Tick buffers (circular for memory efficiency)
|
|
87
|
-
this.tickBuffer = new CircularBuffer(1000); // Last 1000 ticks
|
|
88
|
-
this.priceBuffer = new CircularBuffer(500); // Last 500 prices
|
|
89
|
-
|
|
90
|
-
// Real-time metrics
|
|
91
|
-
this.cumulativeDelta = 0;
|
|
92
|
-
this.buyVolume = 0;
|
|
93
|
-
this.sellVolume = 0;
|
|
94
|
-
this.lastPrice = 0;
|
|
95
|
-
this.lastBid = 0;
|
|
96
|
-
this.lastAsk = 0;
|
|
97
|
-
|
|
98
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
99
|
-
// STRATEGY CONFIGURATION PARAMETERS
|
|
100
|
-
// These are algorithm tuning parameters, NOT trading data
|
|
101
|
-
// They define HOW the strategy calculates signals from real tick data
|
|
102
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
103
|
-
|
|
104
|
-
// OFI calculation windows (algorithm config)
|
|
105
|
-
this.ofiWindow = 50; // Number of ticks for OFI calculation
|
|
106
|
-
this.ofiValue = 0; // Calculated from real ticks
|
|
107
|
-
|
|
108
|
-
// Momentum windows (algorithm config)
|
|
109
|
-
this.momentumWindow = 20; // Number of ticks for momentum
|
|
110
|
-
this.momentum = 0; // Calculated from real tick prices
|
|
111
|
-
this.acceleration = 0; // Calculated from real tick prices
|
|
112
|
-
|
|
113
|
-
// Mean reversion windows (algorithm config)
|
|
114
|
-
this.zscoreWindow = 100; // Number of ticks for z-score
|
|
115
|
-
this.zscore = 0; // Calculated from real tick prices
|
|
116
|
-
this.mean = 0; // Calculated from real tick prices
|
|
117
|
-
this.std = 0; // Calculated from real tick prices
|
|
118
|
-
|
|
119
|
-
// Signal thresholds (algorithm tuning - from backtests)
|
|
120
|
-
this.ofiThreshold = 0.3; // |OFI| threshold for signal generation
|
|
121
|
-
this.zscoreThreshold = 1.5; // |Z| threshold for mean reversion
|
|
122
|
-
this.momentumThreshold = 0.5; // Momentum threshold for confirmation
|
|
123
|
-
this.minConfidence = 0.6; // Minimum composite score for signal
|
|
124
|
-
|
|
125
|
-
// Risk parameters in ticks (algorithm config)
|
|
126
|
-
this.baseStopTicks = 8; // Base stop distance in ticks
|
|
127
|
-
this.baseTargetTicks = 12; // Base target distance in ticks
|
|
128
|
-
|
|
129
|
-
// State tracking
|
|
130
|
-
this.tickCount = 0; // Counter from real ticks received
|
|
131
|
-
this.signalCount = 0; // Counter of signals generated
|
|
132
|
-
this.lastSignalTime = 0; // Timestamp of last signal
|
|
133
|
-
this.cooldownMs = 5000; // Cooldown between signals (ms)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Initialize strategy for a contract
|
|
138
|
-
* @param {string} contractId - Contract identifier from API
|
|
139
|
-
* @param {number} tickSize - Tick size from API (REQUIRED - no default)
|
|
140
|
-
* @param {number} tickValue - Tick value from API (REQUIRED - no default)
|
|
141
|
-
*/
|
|
142
|
-
initialize(contractId, tickSize, tickValue) {
|
|
143
|
-
if (!contractId || tickSize === undefined || tickValue === undefined) {
|
|
144
|
-
throw new Error('HFT Strategy requires contractId, tickSize, and tickValue from API');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
this.contractId = contractId;
|
|
148
|
-
this.tickSize = tickSize;
|
|
149
|
-
this.tickValue = tickValue;
|
|
150
|
-
this.initialized = true;
|
|
151
|
-
|
|
152
|
-
// Reset state
|
|
153
|
-
this.tickBuffer.clear();
|
|
154
|
-
this.priceBuffer.clear();
|
|
155
|
-
this.cumulativeDelta = 0;
|
|
156
|
-
this.buyVolume = 0;
|
|
157
|
-
this.sellVolume = 0;
|
|
158
|
-
this.tickCount = 0;
|
|
159
|
-
|
|
160
|
-
log.info(`Initialized for ${contractId}: tick=${tickSize}, value=${tickValue}`);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Process a single tick - CORE HFT FUNCTION
|
|
165
|
-
* Called on every market tick
|
|
166
|
-
*/
|
|
167
|
-
processTick(tick) {
|
|
168
|
-
if (!this.initialized) return;
|
|
169
|
-
|
|
170
|
-
const { price, bid, ask, volume, side, timestamp } = tick;
|
|
171
|
-
|
|
172
|
-
// Store tick
|
|
173
|
-
this.tickBuffer.push({
|
|
174
|
-
price,
|
|
175
|
-
bid: bid || this.lastBid,
|
|
176
|
-
ask: ask || this.lastAsk,
|
|
177
|
-
volume: volume || 1,
|
|
178
|
-
side: side || this.inferSide(price, bid, ask),
|
|
179
|
-
timestamp: timestamp || Date.now(),
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
this.priceBuffer.push(price);
|
|
183
|
-
this.tickCount++;
|
|
184
|
-
|
|
185
|
-
// Update last values
|
|
186
|
-
this.lastPrice = price;
|
|
187
|
-
if (bid) this.lastBid = bid;
|
|
188
|
-
if (ask) this.lastAsk = ask;
|
|
189
|
-
|
|
190
|
-
// Update real-time metrics
|
|
191
|
-
this._updateDelta(tick);
|
|
192
|
-
this._updateOFI();
|
|
193
|
-
this._updateMomentum();
|
|
194
|
-
this._updateZScore();
|
|
195
|
-
|
|
196
|
-
// Check for signal (every tick!)
|
|
197
|
-
this._checkSignal(tick);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Infer trade side from price position
|
|
202
|
-
*/
|
|
203
|
-
inferSide(price, bid, ask) {
|
|
204
|
-
if (!bid || !ask) return 'unknown';
|
|
205
|
-
const mid = (bid + ask) / 2;
|
|
206
|
-
return price >= mid ? 'BUY' : 'SELL';
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Update cumulative delta
|
|
211
|
-
*/
|
|
212
|
-
_updateDelta(tick) {
|
|
213
|
-
const vol = tick.volume || 1;
|
|
214
|
-
const side = tick.side?.toUpperCase() || this.inferSide(tick.price, tick.bid, tick.ask);
|
|
215
|
-
|
|
216
|
-
if (side === 'BUY') {
|
|
217
|
-
this.buyVolume += vol;
|
|
218
|
-
this.cumulativeDelta += vol;
|
|
219
|
-
} else if (side === 'SELL') {
|
|
220
|
-
this.sellVolume += vol;
|
|
221
|
-
this.cumulativeDelta -= vol;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Calculate Order Flow Imbalance on recent ticks
|
|
227
|
-
*/
|
|
228
|
-
_updateOFI() {
|
|
229
|
-
const ticks = this.tickBuffer.getLast(this.ofiWindow);
|
|
230
|
-
if (ticks.length < 10) {
|
|
231
|
-
this.ofiValue = 0;
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
let buyPressure = 0;
|
|
236
|
-
let sellPressure = 0;
|
|
237
|
-
|
|
238
|
-
for (const tick of ticks) {
|
|
239
|
-
const vol = tick.volume || 1;
|
|
240
|
-
const side = (tick.side || '').toUpperCase();
|
|
241
|
-
|
|
242
|
-
if (side === 'BUY') {
|
|
243
|
-
buyPressure += vol;
|
|
244
|
-
} else if (side === 'SELL') {
|
|
245
|
-
sellPressure += vol;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const total = buyPressure + sellPressure;
|
|
250
|
-
if (total > 0) {
|
|
251
|
-
// OFI range: -1 (all sells) to +1 (all buys)
|
|
252
|
-
this.ofiValue = (buyPressure - sellPressure) / total;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Calculate price momentum
|
|
258
|
-
*/
|
|
259
|
-
_updateMomentum() {
|
|
260
|
-
const prices = this.priceBuffer.getLast(this.momentumWindow);
|
|
261
|
-
if (prices.length < 5) {
|
|
262
|
-
this.momentum = 0;
|
|
263
|
-
this.acceleration = 0;
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Momentum = price change over window
|
|
268
|
-
const first = prices[0];
|
|
269
|
-
const last = prices[prices.length - 1];
|
|
270
|
-
this.momentum = (last - first) / this.tickSize;
|
|
271
|
-
|
|
272
|
-
// Acceleration = change in momentum
|
|
273
|
-
if (prices.length >= 10) {
|
|
274
|
-
const mid = prices[Math.floor(prices.length / 2)];
|
|
275
|
-
const firstHalf = (mid - first) / this.tickSize;
|
|
276
|
-
const secondHalf = (last - mid) / this.tickSize;
|
|
277
|
-
this.acceleration = secondHalf - firstHalf;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Calculate Z-Score for mean reversion
|
|
283
|
-
*/
|
|
284
|
-
_updateZScore() {
|
|
285
|
-
const prices = this.priceBuffer.getLast(this.zscoreWindow);
|
|
286
|
-
if (prices.length < 20) {
|
|
287
|
-
this.zscore = 0;
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Calculate mean
|
|
292
|
-
this.mean = prices.reduce((a, b) => a + b, 0) / prices.length;
|
|
293
|
-
|
|
294
|
-
// Calculate standard deviation
|
|
295
|
-
const variance = prices.reduce((sum, p) => sum + Math.pow(p - this.mean, 2), 0) / prices.length;
|
|
296
|
-
this.std = Math.sqrt(variance);
|
|
297
|
-
|
|
298
|
-
// Z-Score
|
|
299
|
-
if (this.std > 0.0001) {
|
|
300
|
-
this.zscore = (this.lastPrice - this.mean) / this.std;
|
|
301
|
-
} else {
|
|
302
|
-
this.zscore = 0;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Check for trading signal
|
|
308
|
-
*/
|
|
309
|
-
_checkSignal(tick) {
|
|
310
|
-
if (this.tickCount < 50) return;
|
|
311
|
-
|
|
312
|
-
const now = Date.now();
|
|
313
|
-
if (now - this.lastSignalTime < this.cooldownMs) return;
|
|
314
|
-
|
|
315
|
-
const state = {
|
|
316
|
-
ofiValue: this.ofiValue,
|
|
317
|
-
zscore: this.zscore,
|
|
318
|
-
momentum: this.momentum,
|
|
319
|
-
buyVolume: this.buyVolume,
|
|
320
|
-
sellVolume: this.sellVolume,
|
|
321
|
-
cumulativeDelta: this.cumulativeDelta,
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
const config = {
|
|
325
|
-
ofiThreshold: this.ofiThreshold,
|
|
326
|
-
zscoreThreshold: this.zscoreThreshold,
|
|
327
|
-
momentumThreshold: this.momentumThreshold,
|
|
328
|
-
minConfidence: this.minConfidence,
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
const { direction, confidence, scores } = calculateSignal(state, config);
|
|
332
|
-
|
|
333
|
-
if (direction === 'none' || confidence < this.minConfidence) return;
|
|
334
|
-
|
|
335
|
-
this.signalCount++;
|
|
336
|
-
this.lastSignalTime = now;
|
|
337
|
-
|
|
338
|
-
const signalState = {
|
|
339
|
-
...state,
|
|
340
|
-
std: this.std,
|
|
341
|
-
tickCount: this.tickCount,
|
|
342
|
-
signalCount: this.signalCount,
|
|
343
|
-
contractId: this.contractId,
|
|
344
|
-
tickSize: this.tickSize,
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
const signalConfig = {
|
|
348
|
-
baseStopTicks: this.baseStopTicks,
|
|
349
|
-
baseTargetTicks: this.baseTargetTicks,
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
const signal = buildSignal(direction, confidence, scores, tick, signalState, signalConfig);
|
|
353
|
-
|
|
354
|
-
log.info(`SIGNAL #${this.signalCount}: ${direction.toUpperCase()} @ ${tick.price} | ` +
|
|
355
|
-
`OFI=${this.ofiValue.toFixed(2)} Z=${this.zscore.toFixed(2)} Mom=${this.momentum.toFixed(1)} | ` +
|
|
356
|
-
`Conf=${(confidence * 100).toFixed(0)}%`);
|
|
357
|
-
|
|
358
|
-
this.emit('signal', signal);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Get current model values for monitoring
|
|
363
|
-
*/
|
|
364
|
-
getModelValues() {
|
|
365
|
-
return {
|
|
366
|
-
ofi: this.ofiValue,
|
|
367
|
-
delta: this.cumulativeDelta,
|
|
368
|
-
zscore: this.zscore,
|
|
369
|
-
momentum: this.momentum,
|
|
370
|
-
mean: this.mean,
|
|
371
|
-
std: this.std,
|
|
372
|
-
buyVolume: this.buyVolume,
|
|
373
|
-
sellVolume: this.sellVolume,
|
|
374
|
-
tickCount: this.tickCount,
|
|
375
|
-
signalCount: this.signalCount,
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Get state for display
|
|
381
|
-
*/
|
|
382
|
-
getState() {
|
|
383
|
-
return this.getModelValues();
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Reset strategy state
|
|
388
|
-
*/
|
|
389
|
-
reset() {
|
|
390
|
-
this.tickBuffer.clear();
|
|
391
|
-
this.priceBuffer.clear();
|
|
392
|
-
this.cumulativeDelta = 0;
|
|
393
|
-
this.buyVolume = 0;
|
|
394
|
-
this.sellVolume = 0;
|
|
395
|
-
this.tickCount = 0;
|
|
396
|
-
this.signalCount = 0;
|
|
397
|
-
this.ofiValue = 0;
|
|
398
|
-
this.zscore = 0;
|
|
399
|
-
this.momentum = 0;
|
|
400
|
-
log.info('Strategy reset');
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Singleton instance
|
|
405
|
-
const hftStrategy = new HFTTickStrategy();
|
|
406
|
-
|
|
407
|
-
module.exports = { HFTTickStrategy, hftStrategy };
|