@alango/dr-manhattan 0.1.3 → 0.1.4
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/index.d.ts +331 -331
- package/dist/index.js +259 -256
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -7,39 +7,70 @@ import { io } from 'socket.io-client';
|
|
|
7
7
|
import { ClobClient, Side, AssetType } from '@polymarket/clob-client';
|
|
8
8
|
import pino from 'pino';
|
|
9
9
|
|
|
10
|
-
// src/
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
// src/errors/index.ts
|
|
11
|
+
var DrManhattanError = class extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "DrManhattanError";
|
|
15
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
16
|
+
}
|
|
14
17
|
};
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
CANCELLED: "cancelled",
|
|
21
|
-
REJECTED: "rejected"
|
|
18
|
+
var ExchangeError = class extends DrManhattanError {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "ExchangeError";
|
|
22
|
+
}
|
|
22
23
|
};
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
var NetworkError = class extends DrManhattanError {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "NetworkError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var RateLimitError = class extends DrManhattanError {
|
|
31
|
+
retryAfter;
|
|
32
|
+
constructor(message, retryAfter) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = "RateLimitError";
|
|
35
|
+
this.retryAfter = retryAfter;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var AuthenticationError = class extends DrManhattanError {
|
|
39
|
+
constructor(message) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.name = "AuthenticationError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var InsufficientFunds = class extends DrManhattanError {
|
|
45
|
+
constructor(message) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "InsufficientFunds";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var InvalidOrder = class extends DrManhattanError {
|
|
51
|
+
constructor(message) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "InvalidOrder";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var MarketNotFound = class extends DrManhattanError {
|
|
57
|
+
constructor(message) {
|
|
58
|
+
super(message);
|
|
59
|
+
this.name = "MarketNotFound";
|
|
40
60
|
}
|
|
41
61
|
};
|
|
42
62
|
|
|
63
|
+
// src/types/crypto-hourly.ts
|
|
64
|
+
var TOKEN_ALIASES = {
|
|
65
|
+
BITCOIN: "BTC",
|
|
66
|
+
ETHEREUM: "ETH",
|
|
67
|
+
SOLANA: "SOL"
|
|
68
|
+
};
|
|
69
|
+
function normalizeTokenSymbol(token) {
|
|
70
|
+
const upper = token.toUpperCase();
|
|
71
|
+
return TOKEN_ALIASES[upper] ?? upper;
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
// src/types/market.ts
|
|
44
75
|
var MarketUtils = {
|
|
45
76
|
/** Check if market is binary (Yes/No) */
|
|
@@ -89,49 +120,38 @@ var MarketUtils = {
|
|
|
89
120
|
}
|
|
90
121
|
};
|
|
91
122
|
|
|
92
|
-
// src/types/
|
|
93
|
-
var
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
123
|
+
// src/types/order.ts
|
|
124
|
+
var OrderSide = {
|
|
125
|
+
BUY: "buy",
|
|
126
|
+
SELL: "sell"
|
|
127
|
+
};
|
|
128
|
+
var OrderStatus = {
|
|
129
|
+
PENDING: "pending",
|
|
130
|
+
OPEN: "open",
|
|
131
|
+
FILLED: "filled",
|
|
132
|
+
PARTIALLY_FILLED: "partially_filled",
|
|
133
|
+
CANCELLED: "cancelled",
|
|
134
|
+
REJECTED: "rejected"
|
|
135
|
+
};
|
|
136
|
+
var OrderUtils = {
|
|
137
|
+
/** Get remaining unfilled amount */
|
|
138
|
+
remaining(order) {
|
|
139
|
+
return order.size - order.filled;
|
|
97
140
|
},
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
-
return
|
|
141
|
+
/** Check if order is still active */
|
|
142
|
+
isActive(order) {
|
|
143
|
+
return order.status === OrderStatus.OPEN || order.status === OrderStatus.PARTIALLY_FILLED;
|
|
101
144
|
},
|
|
102
|
-
/**
|
|
103
|
-
|
|
104
|
-
return
|
|
145
|
+
/** Check if order is completely filled */
|
|
146
|
+
isFilled(order) {
|
|
147
|
+
return order.status === OrderStatus.FILLED || order.filled >= order.size;
|
|
105
148
|
},
|
|
106
|
-
/** Get
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return PositionUtils.unrealizedPnl(position) / costBasis * 100;
|
|
149
|
+
/** Get fill percentage (0-1) */
|
|
150
|
+
fillPercentage(order) {
|
|
151
|
+
if (order.size === 0) return 0;
|
|
152
|
+
return order.filled / order.size;
|
|
111
153
|
}
|
|
112
154
|
};
|
|
113
|
-
function calculateDelta(positions) {
|
|
114
|
-
const entries = Object.entries(positions);
|
|
115
|
-
if (entries.length === 0) {
|
|
116
|
-
return { delta: 0, maxOutcome: null, maxPosition: 0 };
|
|
117
|
-
}
|
|
118
|
-
let maxOutcome = null;
|
|
119
|
-
let maxPosition = 0;
|
|
120
|
-
for (const [outcome, size] of entries) {
|
|
121
|
-
if (size > maxPosition) {
|
|
122
|
-
maxPosition = size;
|
|
123
|
-
maxOutcome = outcome;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (entries.length === 2) {
|
|
127
|
-
const [first, second] = entries;
|
|
128
|
-
if (first && second) {
|
|
129
|
-
const delta = Math.abs(first[1] - second[1]);
|
|
130
|
-
return { delta, maxOutcome, maxPosition };
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return { delta: maxPosition, maxOutcome, maxPosition };
|
|
134
|
-
}
|
|
135
155
|
|
|
136
156
|
// src/types/orderbook.ts
|
|
137
157
|
var OrderbookUtils = {
|
|
@@ -218,69 +238,49 @@ var OrderbookManager = class {
|
|
|
218
238
|
}
|
|
219
239
|
};
|
|
220
240
|
|
|
221
|
-
// src/types/
|
|
222
|
-
var
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
var ExchangeError = class extends DrManhattanError {
|
|
241
|
-
constructor(message) {
|
|
242
|
-
super(message);
|
|
243
|
-
this.name = "ExchangeError";
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
var NetworkError = class extends DrManhattanError {
|
|
247
|
-
constructor(message) {
|
|
248
|
-
super(message);
|
|
249
|
-
this.name = "NetworkError";
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
var RateLimitError = class extends DrManhattanError {
|
|
253
|
-
retryAfter;
|
|
254
|
-
constructor(message, retryAfter) {
|
|
255
|
-
super(message);
|
|
256
|
-
this.name = "RateLimitError";
|
|
257
|
-
this.retryAfter = retryAfter;
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
var AuthenticationError = class extends DrManhattanError {
|
|
261
|
-
constructor(message) {
|
|
262
|
-
super(message);
|
|
263
|
-
this.name = "AuthenticationError";
|
|
241
|
+
// src/types/position.ts
|
|
242
|
+
var PositionUtils = {
|
|
243
|
+
/** Get total cost basis */
|
|
244
|
+
costBasis(position) {
|
|
245
|
+
return position.size * position.averagePrice;
|
|
246
|
+
},
|
|
247
|
+
/** Get current market value */
|
|
248
|
+
currentValue(position) {
|
|
249
|
+
return position.size * position.currentPrice;
|
|
250
|
+
},
|
|
251
|
+
/** Get unrealized profit/loss */
|
|
252
|
+
unrealizedPnl(position) {
|
|
253
|
+
return PositionUtils.currentValue(position) - PositionUtils.costBasis(position);
|
|
254
|
+
},
|
|
255
|
+
/** Get unrealized P&L as percentage */
|
|
256
|
+
unrealizedPnlPercent(position) {
|
|
257
|
+
const costBasis = PositionUtils.costBasis(position);
|
|
258
|
+
if (costBasis === 0) return 0;
|
|
259
|
+
return PositionUtils.unrealizedPnl(position) / costBasis * 100;
|
|
264
260
|
}
|
|
265
261
|
};
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
262
|
+
function calculateDelta(positions) {
|
|
263
|
+
const entries = Object.entries(positions);
|
|
264
|
+
if (entries.length === 0) {
|
|
265
|
+
return { delta: 0, maxOutcome: null, maxPosition: 0 };
|
|
270
266
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
267
|
+
let maxOutcome = null;
|
|
268
|
+
let maxPosition = 0;
|
|
269
|
+
for (const [outcome, size] of entries) {
|
|
270
|
+
if (size > maxPosition) {
|
|
271
|
+
maxPosition = size;
|
|
272
|
+
maxOutcome = outcome;
|
|
273
|
+
}
|
|
276
274
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
275
|
+
if (entries.length === 2) {
|
|
276
|
+
const [first, second] = entries;
|
|
277
|
+
if (first && second) {
|
|
278
|
+
const delta = Math.abs(first[1] - second[1]);
|
|
279
|
+
return { delta, maxOutcome, maxPosition };
|
|
280
|
+
}
|
|
282
281
|
}
|
|
283
|
-
};
|
|
282
|
+
return { delta: maxPosition, maxOutcome, maxPosition };
|
|
283
|
+
}
|
|
284
284
|
|
|
285
285
|
// src/core/exchange.ts
|
|
286
286
|
var Exchange = class {
|
|
@@ -411,6 +411,131 @@ var Exchange = class {
|
|
|
411
411
|
return Math.min(maxPositionSize, liquidityBasedSize);
|
|
412
412
|
}
|
|
413
413
|
};
|
|
414
|
+
var StrategyState = {
|
|
415
|
+
STOPPED: "stopped",
|
|
416
|
+
RUNNING: "running",
|
|
417
|
+
PAUSED: "paused"
|
|
418
|
+
};
|
|
419
|
+
var Strategy = class extends EventEmitter {
|
|
420
|
+
exchange;
|
|
421
|
+
marketId;
|
|
422
|
+
market = null;
|
|
423
|
+
state = StrategyState.STOPPED;
|
|
424
|
+
config;
|
|
425
|
+
tickTimer = null;
|
|
426
|
+
positions = [];
|
|
427
|
+
openOrders = [];
|
|
428
|
+
constructor(exchange, marketId, config = {}) {
|
|
429
|
+
super();
|
|
430
|
+
this.exchange = exchange;
|
|
431
|
+
this.marketId = marketId;
|
|
432
|
+
this.config = {
|
|
433
|
+
tickInterval: 1e3,
|
|
434
|
+
maxPositionSize: 100,
|
|
435
|
+
spreadBps: 100,
|
|
436
|
+
verbose: false,
|
|
437
|
+
...config
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
async start() {
|
|
441
|
+
if (this.state === StrategyState.RUNNING) return;
|
|
442
|
+
this.market = await this.exchange.fetchMarket(this.marketId);
|
|
443
|
+
this.state = StrategyState.RUNNING;
|
|
444
|
+
this.tickTimer = setInterval(async () => {
|
|
445
|
+
if (this.state !== StrategyState.RUNNING) return;
|
|
446
|
+
try {
|
|
447
|
+
await this.refreshState();
|
|
448
|
+
await this.onTick();
|
|
449
|
+
} catch (error) {
|
|
450
|
+
this.emit("error", error);
|
|
451
|
+
if (this.config.verbose) {
|
|
452
|
+
console.error("Strategy tick error:", error);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}, this.config.tickInterval);
|
|
456
|
+
this.emit("started");
|
|
457
|
+
}
|
|
458
|
+
async stop() {
|
|
459
|
+
if (this.state === StrategyState.STOPPED) return;
|
|
460
|
+
this.state = StrategyState.STOPPED;
|
|
461
|
+
if (this.tickTimer) {
|
|
462
|
+
clearInterval(this.tickTimer);
|
|
463
|
+
this.tickTimer = null;
|
|
464
|
+
}
|
|
465
|
+
await this.cancelAllOrders();
|
|
466
|
+
this.emit("stopped");
|
|
467
|
+
}
|
|
468
|
+
pause() {
|
|
469
|
+
if (this.state === StrategyState.RUNNING) {
|
|
470
|
+
this.state = StrategyState.PAUSED;
|
|
471
|
+
this.emit("paused");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
resume() {
|
|
475
|
+
if (this.state === StrategyState.PAUSED) {
|
|
476
|
+
this.state = StrategyState.RUNNING;
|
|
477
|
+
this.emit("resumed");
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
async refreshState() {
|
|
481
|
+
const [positions, orders] = await Promise.all([
|
|
482
|
+
this.exchange.fetchPositions(this.marketId),
|
|
483
|
+
this.exchange.fetchOpenOrders(this.marketId)
|
|
484
|
+
]);
|
|
485
|
+
this.positions = positions;
|
|
486
|
+
this.openOrders = orders;
|
|
487
|
+
}
|
|
488
|
+
async cancelAllOrders() {
|
|
489
|
+
for (const order of this.openOrders) {
|
|
490
|
+
try {
|
|
491
|
+
await this.exchange.cancelOrder(order.id, this.marketId);
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
this.openOrders = [];
|
|
496
|
+
}
|
|
497
|
+
getPosition(outcome) {
|
|
498
|
+
return this.positions.find((p) => p.outcome === outcome);
|
|
499
|
+
}
|
|
500
|
+
getNetPosition() {
|
|
501
|
+
if (!this.market || this.market.outcomes.length !== 2) return 0;
|
|
502
|
+
const outcome1 = this.market.outcomes[0];
|
|
503
|
+
const outcome2 = this.market.outcomes[1];
|
|
504
|
+
if (!outcome1 || !outcome2) return 0;
|
|
505
|
+
const pos1 = this.getPosition(outcome1)?.size ?? 0;
|
|
506
|
+
const pos2 = this.getPosition(outcome2)?.size ?? 0;
|
|
507
|
+
return pos1 - pos2;
|
|
508
|
+
}
|
|
509
|
+
async placeOrder(outcome, side, price, size, tokenId) {
|
|
510
|
+
try {
|
|
511
|
+
const order = await this.exchange.createOrder({
|
|
512
|
+
marketId: this.marketId,
|
|
513
|
+
outcome,
|
|
514
|
+
side,
|
|
515
|
+
price,
|
|
516
|
+
size,
|
|
517
|
+
tokenId
|
|
518
|
+
});
|
|
519
|
+
this.openOrders.push(order);
|
|
520
|
+
this.emit("order", order);
|
|
521
|
+
return order;
|
|
522
|
+
} catch (error) {
|
|
523
|
+
this.emit("error", error);
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
log(message) {
|
|
528
|
+
if (this.config.verbose) {
|
|
529
|
+
console.log(`[${this.exchange.id}:${this.marketId}] ${message}`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
get isRunning() {
|
|
533
|
+
return this.state === StrategyState.RUNNING;
|
|
534
|
+
}
|
|
535
|
+
get currentState() {
|
|
536
|
+
return this.state;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
414
539
|
var WebSocketState = {
|
|
415
540
|
DISCONNECTED: "disconnected",
|
|
416
541
|
CONNECTING: "connecting",
|
|
@@ -579,142 +704,20 @@ var OrderBookWebSocket = class extends EventEmitter {
|
|
|
579
704
|
}
|
|
580
705
|
}
|
|
581
706
|
};
|
|
582
|
-
var StrategyState = {
|
|
583
|
-
STOPPED: "stopped",
|
|
584
|
-
RUNNING: "running",
|
|
585
|
-
PAUSED: "paused"
|
|
586
|
-
};
|
|
587
|
-
var Strategy = class extends EventEmitter {
|
|
588
|
-
exchange;
|
|
589
|
-
marketId;
|
|
590
|
-
market = null;
|
|
591
|
-
state = StrategyState.STOPPED;
|
|
592
|
-
config;
|
|
593
|
-
tickTimer = null;
|
|
594
|
-
positions = [];
|
|
595
|
-
openOrders = [];
|
|
596
|
-
constructor(exchange, marketId, config = {}) {
|
|
597
|
-
super();
|
|
598
|
-
this.exchange = exchange;
|
|
599
|
-
this.marketId = marketId;
|
|
600
|
-
this.config = {
|
|
601
|
-
tickInterval: 1e3,
|
|
602
|
-
maxPositionSize: 100,
|
|
603
|
-
spreadBps: 100,
|
|
604
|
-
verbose: false,
|
|
605
|
-
...config
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
async start() {
|
|
609
|
-
if (this.state === StrategyState.RUNNING) return;
|
|
610
|
-
this.market = await this.exchange.fetchMarket(this.marketId);
|
|
611
|
-
this.state = StrategyState.RUNNING;
|
|
612
|
-
this.tickTimer = setInterval(async () => {
|
|
613
|
-
if (this.state !== StrategyState.RUNNING) return;
|
|
614
|
-
try {
|
|
615
|
-
await this.refreshState();
|
|
616
|
-
await this.onTick();
|
|
617
|
-
} catch (error) {
|
|
618
|
-
this.emit("error", error);
|
|
619
|
-
if (this.config.verbose) {
|
|
620
|
-
console.error("Strategy tick error:", error);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}, this.config.tickInterval);
|
|
624
|
-
this.emit("started");
|
|
625
|
-
}
|
|
626
|
-
async stop() {
|
|
627
|
-
if (this.state === StrategyState.STOPPED) return;
|
|
628
|
-
this.state = StrategyState.STOPPED;
|
|
629
|
-
if (this.tickTimer) {
|
|
630
|
-
clearInterval(this.tickTimer);
|
|
631
|
-
this.tickTimer = null;
|
|
632
|
-
}
|
|
633
|
-
await this.cancelAllOrders();
|
|
634
|
-
this.emit("stopped");
|
|
635
|
-
}
|
|
636
|
-
pause() {
|
|
637
|
-
if (this.state === StrategyState.RUNNING) {
|
|
638
|
-
this.state = StrategyState.PAUSED;
|
|
639
|
-
this.emit("paused");
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
resume() {
|
|
643
|
-
if (this.state === StrategyState.PAUSED) {
|
|
644
|
-
this.state = StrategyState.RUNNING;
|
|
645
|
-
this.emit("resumed");
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
async refreshState() {
|
|
649
|
-
const [positions, orders] = await Promise.all([
|
|
650
|
-
this.exchange.fetchPositions(this.marketId),
|
|
651
|
-
this.exchange.fetchOpenOrders(this.marketId)
|
|
652
|
-
]);
|
|
653
|
-
this.positions = positions;
|
|
654
|
-
this.openOrders = orders;
|
|
655
|
-
}
|
|
656
|
-
async cancelAllOrders() {
|
|
657
|
-
for (const order of this.openOrders) {
|
|
658
|
-
try {
|
|
659
|
-
await this.exchange.cancelOrder(order.id, this.marketId);
|
|
660
|
-
} catch {
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
this.openOrders = [];
|
|
664
|
-
}
|
|
665
|
-
getPosition(outcome) {
|
|
666
|
-
return this.positions.find((p) => p.outcome === outcome);
|
|
667
|
-
}
|
|
668
|
-
getNetPosition() {
|
|
669
|
-
if (!this.market || this.market.outcomes.length !== 2) return 0;
|
|
670
|
-
const outcome1 = this.market.outcomes[0];
|
|
671
|
-
const outcome2 = this.market.outcomes[1];
|
|
672
|
-
if (!outcome1 || !outcome2) return 0;
|
|
673
|
-
const pos1 = this.getPosition(outcome1)?.size ?? 0;
|
|
674
|
-
const pos2 = this.getPosition(outcome2)?.size ?? 0;
|
|
675
|
-
return pos1 - pos2;
|
|
676
|
-
}
|
|
677
|
-
async placeOrder(outcome, side, price, size, tokenId) {
|
|
678
|
-
try {
|
|
679
|
-
const order = await this.exchange.createOrder({
|
|
680
|
-
marketId: this.marketId,
|
|
681
|
-
outcome,
|
|
682
|
-
side,
|
|
683
|
-
price,
|
|
684
|
-
size,
|
|
685
|
-
tokenId
|
|
686
|
-
});
|
|
687
|
-
this.openOrders.push(order);
|
|
688
|
-
this.emit("order", order);
|
|
689
|
-
return order;
|
|
690
|
-
} catch (error) {
|
|
691
|
-
this.emit("error", error);
|
|
692
|
-
return null;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
log(message) {
|
|
696
|
-
if (this.config.verbose) {
|
|
697
|
-
console.log(`[${this.exchange.id}:${this.marketId}] ${message}`);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
get isRunning() {
|
|
701
|
-
return this.state === StrategyState.RUNNING;
|
|
702
|
-
}
|
|
703
|
-
get currentState() {
|
|
704
|
-
return this.state;
|
|
705
|
-
}
|
|
706
|
-
};
|
|
707
707
|
var BASE_URL = "https://api.elections.kalshi.com/trade-api/v2";
|
|
708
708
|
var DEMO_URL = "https://demo-api.kalshi.co/trade-api/v2";
|
|
709
709
|
function createAuth(privateKeyPem) {
|
|
710
|
+
const privateKey = crypto.createPrivateKey(privateKeyPem);
|
|
710
711
|
return {
|
|
711
712
|
sign(timestampMs, method, path) {
|
|
712
|
-
const
|
|
713
|
-
const
|
|
714
|
-
sign.
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
713
|
+
const pathWithoutQuery = path.split("?")[0];
|
|
714
|
+
const message = `${timestampMs}${method.toUpperCase()}${pathWithoutQuery}`;
|
|
715
|
+
const signature = crypto.sign("sha256", Buffer.from(message), {
|
|
716
|
+
key: privateKey,
|
|
717
|
+
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
|
718
|
+
saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
|
|
719
|
+
});
|
|
720
|
+
return signature.toString("base64");
|
|
718
721
|
}
|
|
719
722
|
};
|
|
720
723
|
}
|
|
@@ -3034,7 +3037,7 @@ var Polymarket = class extends Exchange {
|
|
|
3034
3037
|
minLiquidity
|
|
3035
3038
|
});
|
|
3036
3039
|
const upDownPattern = /(?<token>Bitcoin|Ethereum|Solana|BTC|ETH|SOL)\s+Up or Down/i;
|
|
3037
|
-
const strikePattern = /(?:(?<token1>BTC|ETH|SOL|BITCOIN|ETHEREUM|SOLANA)\s+.*?(?<direction>above|below|over|under|reach)\s+[
|
|
3040
|
+
const strikePattern = /(?:(?<token1>BTC|ETH|SOL|BITCOIN|ETHEREUM|SOLANA)\s+.*?(?<direction>above|below|over|under|reach)\s+[$]?(?<price1>[\d,]+(?:\.\d+)?))|(?:[$]?(?<price2>[\d,]+(?:\.\d+)?)\s+.*?(?<token2>BTC|ETH|SOL|BITCOIN|ETHEREUM|SOLANA))/i;
|
|
3038
3041
|
for (const market of markets) {
|
|
3039
3042
|
if (!MarketUtils.isBinary(market) || !MarketUtils.isOpen(market)) continue;
|
|
3040
3043
|
if (market.closeTime) {
|