hedgequantx 2.4.6 → 2.4.7
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/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.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 +1 -2
- package/src/pages/algo/one-account.js +3 -3
- package/src/lib/api.js +0 -198
- package/src/lib/api2.js +0 -353
- package/src/lib/core.js +0 -539
- package/src/lib/core2.js +0 -341
- package/src/lib/data.js +0 -555
- package/src/lib/data2.js +0 -492
- package/src/lib/decoder.js +0 -599
- package/src/lib/m/s1.js +0 -372
- package/src/lib/m/s2.js +0 -34
- package/src/lib/n/r1.js +0 -454
- package/src/lib/n/r2.js +0 -514
- package/src/lib/n/r3.js +0 -631
- package/src/lib/n/r4.js +0 -401
- package/src/lib/n/r5.js +0 -335
- package/src/lib/n/r6.js +0 -425
- package/src/lib/n/r7.js +0 -530
- package/src/lib/o/l1.js +0 -44
- package/src/lib/o/l2.js +0 -427
- package/src/lib/python-bridge.js +0 -206
package/src/lib/m/s1.js
DELETED
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HQX Ultra Scalping Strategy
|
|
3
|
-
* Tick-based real-time scalping
|
|
4
|
-
*/
|
|
5
|
-
const EventEmitter = require('events');
|
|
6
|
-
const { v4: uuidv4 } = require('uuid');
|
|
7
|
-
|
|
8
|
-
const OS = { B: 0, A: 1 }; // Order Side: Buy, Ask(Sell)
|
|
9
|
-
const SS = { W: 1, M: 2, S: 3, VS: 4, E: 5 }; // Signal Strength
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* VWAP Calculator - Real-time tick-based
|
|
13
|
-
*/
|
|
14
|
-
class VC {
|
|
15
|
-
constructor() {
|
|
16
|
-
this.data = new Map();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
getKey(c) {
|
|
20
|
-
return `${c}_${new Date().toISOString().split('T')[0]}`;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
init(c) {
|
|
24
|
-
const k = this.getKey(c);
|
|
25
|
-
if (!this.data.has(k)) {
|
|
26
|
-
this.data.set(k, {
|
|
27
|
-
vwap: 0,
|
|
28
|
-
cumVolume: 0,
|
|
29
|
-
cumTPV: 0, // cumulative typical price * volume
|
|
30
|
-
stdDev: 0,
|
|
31
|
-
prices: [],
|
|
32
|
-
high: -Infinity,
|
|
33
|
-
low: Infinity,
|
|
34
|
-
tickCount: 0
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Process each tick
|
|
40
|
-
addTick(c, price, volume = 1) {
|
|
41
|
-
const k = this.getKey(c);
|
|
42
|
-
let d = this.data.get(k);
|
|
43
|
-
if (!d) {
|
|
44
|
-
this.init(c);
|
|
45
|
-
d = this.data.get(k);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Update VWAP
|
|
49
|
-
d.cumVolume += volume;
|
|
50
|
-
d.cumTPV += price * volume;
|
|
51
|
-
if (d.cumVolume > 0) {
|
|
52
|
-
d.vwap = d.cumTPV / d.cumVolume;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Track prices for std dev (last 100)
|
|
56
|
-
d.prices.push(price);
|
|
57
|
-
if (d.prices.length > 100) d.prices.shift();
|
|
58
|
-
|
|
59
|
-
// Calculate standard deviation
|
|
60
|
-
if (d.prices.length >= 10) {
|
|
61
|
-
const mean = d.prices.reduce((a, b) => a + b, 0) / d.prices.length;
|
|
62
|
-
const variance = d.prices.reduce((s, p) => s + Math.pow(p - mean, 2), 0) / d.prices.length;
|
|
63
|
-
d.stdDev = Math.sqrt(variance);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Update high/low
|
|
67
|
-
if (price > d.high) d.high = price;
|
|
68
|
-
if (price < d.low) d.low = price;
|
|
69
|
-
d.tickCount++;
|
|
70
|
-
|
|
71
|
-
return d;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Analyze current price vs VWAP
|
|
75
|
-
analyze(c, currentPrice, tickSize = 0.25) {
|
|
76
|
-
const k = this.getKey(c);
|
|
77
|
-
const d = this.data.get(k);
|
|
78
|
-
if (!d || d.vwap === 0) return null;
|
|
79
|
-
|
|
80
|
-
const deviation = currentPrice - d.vwap;
|
|
81
|
-
const zScore = d.stdDev > 0 ? deviation / d.stdDev : 0;
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
vwap: d.vwap,
|
|
85
|
-
price: currentPrice,
|
|
86
|
-
deviation,
|
|
87
|
-
zScore,
|
|
88
|
-
stdDev: d.stdDev,
|
|
89
|
-
high: d.high,
|
|
90
|
-
low: d.low,
|
|
91
|
-
tickCount: d.tickCount
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get(c) {
|
|
96
|
-
return this.data.get(this.getKey(c)) || null;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
reset(c) {
|
|
100
|
-
this.data.delete(this.getKey(c));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* S1 - HQX Ultra Scalping Strategy
|
|
106
|
-
* Pure tick-based, no bar conversion
|
|
107
|
-
*/
|
|
108
|
-
class S1 extends EventEmitter {
|
|
109
|
-
constructor(cfg = {}) {
|
|
110
|
-
super();
|
|
111
|
-
|
|
112
|
-
// Config
|
|
113
|
-
this.tickSize = cfg.tickSize || 0.25;
|
|
114
|
-
this.minRR = cfg.minRR || 1.2; // Minimum risk/reward
|
|
115
|
-
this.cooldown = cfg.cooldown || 15000; // 15s between signals
|
|
116
|
-
this.minTicks = cfg.minTicks || 20; // Min ticks before first signal
|
|
117
|
-
|
|
118
|
-
// State
|
|
119
|
-
this.vc = new VC();
|
|
120
|
-
this.ticks = new Map(); // contractId -> tick history
|
|
121
|
-
this.lastSignalTime = 0;
|
|
122
|
-
this.inPosition = false;
|
|
123
|
-
|
|
124
|
-
// Order flow tracking
|
|
125
|
-
this.buyVolume = 0;
|
|
126
|
-
this.sellVolume = 0;
|
|
127
|
-
this.lastPrice = 0;
|
|
128
|
-
|
|
129
|
-
// Stats
|
|
130
|
-
this.stats = { signals: 0, trades: 0, wins: 0, losses: 0, pnl: 0 };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
initialize(contractId, tickSize = 0.25) {
|
|
134
|
-
this.tickSize = tickSize;
|
|
135
|
-
this.ticks.set(contractId, []);
|
|
136
|
-
this.vc.init(contractId);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Process incoming tick - MAIN ENTRY POINT
|
|
141
|
-
*/
|
|
142
|
-
processTick(tick) {
|
|
143
|
-
const { contractId, price, bid, ask, volume = 1, side, timestamp } = tick;
|
|
144
|
-
|
|
145
|
-
if (!price || price <= 0) return null;
|
|
146
|
-
|
|
147
|
-
// Store tick
|
|
148
|
-
let tickHistory = this.ticks.get(contractId);
|
|
149
|
-
if (!tickHistory) {
|
|
150
|
-
tickHistory = [];
|
|
151
|
-
this.ticks.set(contractId, tickHistory);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const tickData = {
|
|
155
|
-
price,
|
|
156
|
-
bid: bid || price,
|
|
157
|
-
ask: ask || price,
|
|
158
|
-
volume,
|
|
159
|
-
side: side || (price >= this.lastPrice ? 'buy' : 'sell'),
|
|
160
|
-
timestamp: timestamp || Date.now()
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
tickHistory.push(tickData);
|
|
164
|
-
if (tickHistory.length > 500) tickHistory.shift();
|
|
165
|
-
|
|
166
|
-
// Update VWAP
|
|
167
|
-
this.vc.addTick(contractId, price, volume);
|
|
168
|
-
|
|
169
|
-
// Update order flow
|
|
170
|
-
if (tickData.side === 'buy') {
|
|
171
|
-
this.buyVolume += volume;
|
|
172
|
-
} else {
|
|
173
|
-
this.sellVolume += volume;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
this.lastPrice = price;
|
|
177
|
-
|
|
178
|
-
// Check for signal
|
|
179
|
-
return this.checkSignal(contractId, price, tickHistory);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Check if conditions are met for a signal
|
|
184
|
-
*/
|
|
185
|
-
checkSignal(contractId, price, ticks) {
|
|
186
|
-
// Need minimum ticks
|
|
187
|
-
if (ticks.length < this.minTicks) return null;
|
|
188
|
-
|
|
189
|
-
// Cooldown check
|
|
190
|
-
if (Date.now() - this.lastSignalTime < this.cooldown) return null;
|
|
191
|
-
|
|
192
|
-
// Don't signal if already in position
|
|
193
|
-
if (this.inPosition) return null;
|
|
194
|
-
|
|
195
|
-
// Get VWAP analysis
|
|
196
|
-
const vwap = this.vc.analyze(contractId, price, this.tickSize);
|
|
197
|
-
if (!vwap || vwap.tickCount < this.minTicks) return null;
|
|
198
|
-
|
|
199
|
-
// Calculate order flow imbalance
|
|
200
|
-
const totalVolume = this.buyVolume + this.sellVolume;
|
|
201
|
-
const imbalance = totalVolume > 0 ? (this.buyVolume - this.sellVolume) / totalVolume : 0;
|
|
202
|
-
|
|
203
|
-
// Calculate momentum (last 10 ticks)
|
|
204
|
-
const recentTicks = ticks.slice(-10);
|
|
205
|
-
const momentum = recentTicks.length >= 2
|
|
206
|
-
? recentTicks[recentTicks.length - 1].price - recentTicks[0].price
|
|
207
|
-
: 0;
|
|
208
|
-
|
|
209
|
-
// Signal logic
|
|
210
|
-
let direction = null;
|
|
211
|
-
let confidence = 0;
|
|
212
|
-
|
|
213
|
-
// LONG conditions: Price below VWAP + buying pressure
|
|
214
|
-
if (vwap.zScore < -1.0 && imbalance > 0.1) {
|
|
215
|
-
direction = 'long';
|
|
216
|
-
confidence = Math.min(0.9, 0.5 + Math.abs(vwap.zScore) * 0.15 + imbalance * 0.3);
|
|
217
|
-
}
|
|
218
|
-
// SHORT conditions: Price above VWAP + selling pressure
|
|
219
|
-
else if (vwap.zScore > 1.0 && imbalance < -0.1) {
|
|
220
|
-
direction = 'short';
|
|
221
|
-
confidence = Math.min(0.9, 0.5 + Math.abs(vwap.zScore) * 0.15 + Math.abs(imbalance) * 0.3);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (!direction || confidence < 0.55) return null;
|
|
225
|
-
|
|
226
|
-
// Calculate SL/TP
|
|
227
|
-
const stopTicks = 6;
|
|
228
|
-
const targetTicks = 8;
|
|
229
|
-
|
|
230
|
-
let stopLoss, takeProfit;
|
|
231
|
-
if (direction === 'long') {
|
|
232
|
-
stopLoss = price - stopTicks * this.tickSize;
|
|
233
|
-
takeProfit = price + targetTicks * this.tickSize;
|
|
234
|
-
} else {
|
|
235
|
-
stopLoss = price + stopTicks * this.tickSize;
|
|
236
|
-
takeProfit = price - targetTicks * this.tickSize;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Check R:R
|
|
240
|
-
const risk = Math.abs(price - stopLoss);
|
|
241
|
-
const reward = Math.abs(takeProfit - price);
|
|
242
|
-
if (reward / risk < this.minRR) return null;
|
|
243
|
-
|
|
244
|
-
// Generate signal
|
|
245
|
-
this.lastSignalTime = Date.now();
|
|
246
|
-
this.stats.signals++;
|
|
247
|
-
|
|
248
|
-
const signal = {
|
|
249
|
-
id: uuidv4(),
|
|
250
|
-
timestamp: Date.now(),
|
|
251
|
-
contractId,
|
|
252
|
-
direction,
|
|
253
|
-
side: direction === 'long' ? OS.B : OS.A,
|
|
254
|
-
entry: price,
|
|
255
|
-
entryPrice: price,
|
|
256
|
-
stopLoss,
|
|
257
|
-
takeProfit,
|
|
258
|
-
stopTicks,
|
|
259
|
-
targetTicks,
|
|
260
|
-
confidence,
|
|
261
|
-
zScore: vwap.zScore,
|
|
262
|
-
vwap: vwap.vwap,
|
|
263
|
-
imbalance,
|
|
264
|
-
momentum,
|
|
265
|
-
riskReward: reward / risk
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
this.emit('signal', signal);
|
|
269
|
-
return signal;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Called when entering a position
|
|
274
|
-
*/
|
|
275
|
-
onPositionOpened() {
|
|
276
|
-
this.inPosition = true;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Called when position is closed
|
|
281
|
-
*/
|
|
282
|
-
onPositionClosed(pnl) {
|
|
283
|
-
this.inPosition = false;
|
|
284
|
-
this.recordTradeResult(pnl);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Record trade result
|
|
289
|
-
*/
|
|
290
|
-
recordTradeResult(pnl) {
|
|
291
|
-
this.stats.trades++;
|
|
292
|
-
this.stats.pnl += pnl;
|
|
293
|
-
if (pnl > 0) {
|
|
294
|
-
this.stats.wins++;
|
|
295
|
-
} else {
|
|
296
|
-
this.stats.losses++;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Reset order flow after trade
|
|
300
|
-
this.buyVolume = 0;
|
|
301
|
-
this.sellVolume = 0;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
getStats() {
|
|
305
|
-
return this.stats;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
reset(contractId) {
|
|
309
|
-
this.ticks.set(contractId, []);
|
|
310
|
-
this.vc.reset(contractId);
|
|
311
|
-
this.buyVolume = 0;
|
|
312
|
-
this.sellVolume = 0;
|
|
313
|
-
this.lastSignalTime = 0;
|
|
314
|
-
this.inPosition = false;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* M1 - Main Strategy Interface
|
|
320
|
-
*/
|
|
321
|
-
class M1 extends EventEmitter {
|
|
322
|
-
constructor(cfg = {}) {
|
|
323
|
-
super();
|
|
324
|
-
this.cfg = cfg;
|
|
325
|
-
this.s = new S1(cfg);
|
|
326
|
-
|
|
327
|
-
// Forward signals
|
|
328
|
-
this.s.on('signal', (sig) => {
|
|
329
|
-
this.emit('signal', {
|
|
330
|
-
...sig,
|
|
331
|
-
side: sig.direction === 'long' ? 'buy' : 'sell',
|
|
332
|
-
action: 'open',
|
|
333
|
-
reason: `Z=${sig.zScore.toFixed(2)}, conf=${(sig.confidence * 100).toFixed(0)}%`
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
processTick(t) {
|
|
339
|
-
return this.s.processTick(t);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
onTick(t) {
|
|
343
|
-
return this.processTick(t);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
initialize(contractId, tickSize) {
|
|
347
|
-
this.s.initialize(contractId, tickSize);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
onPositionOpened() {
|
|
351
|
-
this.s.onPositionOpened();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
onPositionClosed(pnl) {
|
|
355
|
-
this.s.onPositionClosed(pnl);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
recordTradeResult(pnl) {
|
|
359
|
-
this.s.recordTradeResult(pnl);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
getStats() {
|
|
363
|
-
return this.s.getStats();
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
reset(contractId) {
|
|
367
|
-
this.s.reset(contractId);
|
|
368
|
-
this.emit('log', { type: 'info', message: 'Strategy reset' });
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
module.exports = { S1, M1, VC, OS, SS };
|
package/src/lib/m/s2.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* M2 Module
|
|
3
|
-
*/
|
|
4
|
-
const EventEmitter = require('events');
|
|
5
|
-
const DP = { et: 0.6, vrng: [0.8, 2.5], cth: 0.45, mxl: 3, stk: 6, tgt: 8, ctr: 1, roc: true, mht: 10000, cd: 30000 };
|
|
6
|
-
|
|
7
|
-
class S2 extends EventEmitter {
|
|
8
|
-
constructor(cfg = {}) { super(); this.p = { ...DP, ...cfg }; this.ts = cfg.tickSize || 0.25; this.cid = null; this.bh = []; this.cd = { v: 0, cv: 0, tpv: 0, sd: 0 }; this.of = { bd: 0, ad: 0, lt: null }; this.st = { s: 0, t: 0, w: 0, l: 0, pnl: 0 }; this.lst = 0; this.lss = 0; }
|
|
9
|
-
// tickSize for tick calculations, P&L comes from API
|
|
10
|
-
initialize(c, ts = 0.25) { this.cid = c; this.ts = ts; this.bh = []; this.cd = { v: 0, cv: 0, tpv: 0, sd: 0 }; this.of = { bd: 0, ad: 0, lt: null }; }
|
|
11
|
-
processTick(t) { const { price, volume, side, timestamp } = t; this.bh.push({ p: price, v: volume || 1, s: side, t: timestamp || Date.now() }); if (this.bh.length > 500) this.bh.shift(); const tp = price; this.cd.cv += volume || 1; this.cd.tpv += tp * (volume || 1); if (this.cd.cv > 0) this.cd.v = this.cd.tpv / this.cd.cv; if (side === 'buy') this.of.bd += volume || 1; else if (side === 'sell') this.of.ad += volume || 1; this.of.lt = side; }
|
|
12
|
-
onTick(t) { return this.processTick(t); }
|
|
13
|
-
onTrade(t) { this.processTick({ price: t.price, volume: t.size || t.volume || 1, side: t.side, timestamp: t.timestamp }); }
|
|
14
|
-
generateSignal(cp) { if (this.bh.length < 50) return null; if (Date.now() - this.lst < this.p.cd) return null; if (this.lss >= this.p.mxl) return null; const v = this.cd.v; if (v <= 0) return null; const sd = this.csd(); if (sd <= 0) return null; const dv = (cp - v) / sd; const ad = Math.abs(dv); if (ad < this.p.vrng[0] || ad > this.p.vrng[1]) return null; let dir = null; if (dv < -this.p.et) dir = 'long'; else if (dv > this.p.et) dir = 'short'; if (!dir) return null; if (this.p.roc) { const ofc = this.cof(dir); if (!ofc) return null; } const cf = Math.min(1.0, 0.5 + ad * 0.15); if (cf < this.p.cth) return null; this.lst = Date.now(); this.st.s++; return { direction: dir, confidence: cf, zScore: dv, stopTicks: this.p.stk, targetTicks: this.p.tgt }; }
|
|
15
|
-
csd() { if (this.bh.length < 20) return 0; const ps = this.bh.slice(-100).map(b => b.p); const m = ps.reduce((a, b) => a + b, 0) / ps.length; const va = ps.reduce((s, p) => s + Math.pow(p - m, 2), 0) / ps.length; return Math.sqrt(va); }
|
|
16
|
-
cof(dir) { const tb = this.of.bd + this.of.ad; if (tb < 10) return true; const br = this.of.bd / tb; if (dir === 'long' && br > 0.45) return true; if (dir === 'short' && br < 0.55) return true; if (this.of.lt === 'buy' && dir === 'long') return true; if (this.of.lt === 'sell' && dir === 'short') return true; return false; }
|
|
17
|
-
recordTradeResult(pnl) { this.st.t++; this.st.pnl += pnl; if (pnl > 0) { this.st.w++; this.lss = 0; } else { this.st.l++; this.lss++; } }
|
|
18
|
-
getStats() { return this.st; }
|
|
19
|
-
reset() { this.bh = []; this.cd = { v: 0, cv: 0, tpv: 0, sd: 0 }; this.of = { bd: 0, ad: 0, lt: null }; this.lss = 0; }
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class M2 extends EventEmitter {
|
|
23
|
-
constructor(cfg = {}) { super(); this.s = new S2(cfg); }
|
|
24
|
-
initialize(c, ts, tv) { this.s.initialize(c, ts, tv); }
|
|
25
|
-
processTick(t) { this.s.processTick(t); }
|
|
26
|
-
onTick(t) { this.s.onTick(t); const sig = this.s.generateSignal(t.price); if (sig) this.emit('signal', { side: sig.direction === 'long' ? 'buy' : 'sell', action: 'open', ...sig }); }
|
|
27
|
-
onTrade(t) { this.s.onTrade(t); }
|
|
28
|
-
generateSignal(p) { return this.s.generateSignal(p); }
|
|
29
|
-
recordTradeResult(p) { this.s.recordTradeResult(p); }
|
|
30
|
-
getStats() { return this.s.getStats(); }
|
|
31
|
-
reset() { this.s.reset(); this.emit('log', { type: 'info', message: 'Reset' }); }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
module.exports = { S2, M2, DP };
|