@newyorkcompute/kalshi-core 0.3.0 → 0.5.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.
Files changed (59) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/config.js +5 -1
  3. package/dist/config.js.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/mm/index.d.ts +11 -0
  9. package/dist/mm/index.d.ts.map +1 -0
  10. package/dist/mm/index.js +14 -0
  11. package/dist/mm/index.js.map +1 -0
  12. package/dist/mm/inventory.d.ts +70 -0
  13. package/dist/mm/inventory.d.ts.map +1 -0
  14. package/dist/mm/inventory.js +171 -0
  15. package/dist/mm/inventory.js.map +1 -0
  16. package/dist/mm/inventory.test.d.ts +2 -0
  17. package/dist/mm/inventory.test.d.ts.map +1 -0
  18. package/dist/mm/inventory.test.js +358 -0
  19. package/dist/mm/inventory.test.js.map +1 -0
  20. package/dist/mm/order-manager.d.ts +93 -0
  21. package/dist/mm/order-manager.d.ts.map +1 -0
  22. package/dist/mm/order-manager.js +262 -0
  23. package/dist/mm/order-manager.js.map +1 -0
  24. package/dist/mm/order-manager.test.d.ts +2 -0
  25. package/dist/mm/order-manager.test.d.ts.map +1 -0
  26. package/dist/mm/order-manager.test.js +333 -0
  27. package/dist/mm/order-manager.test.js.map +1 -0
  28. package/dist/mm/orderbook.d.ts +162 -0
  29. package/dist/mm/orderbook.d.ts.map +1 -0
  30. package/dist/mm/orderbook.js +271 -0
  31. package/dist/mm/orderbook.js.map +1 -0
  32. package/dist/mm/orderbook.test.d.ts +2 -0
  33. package/dist/mm/orderbook.test.d.ts.map +1 -0
  34. package/dist/mm/orderbook.test.js +264 -0
  35. package/dist/mm/orderbook.test.js.map +1 -0
  36. package/dist/mm/risk.d.ts +77 -0
  37. package/dist/mm/risk.d.ts.map +1 -0
  38. package/dist/mm/risk.js +179 -0
  39. package/dist/mm/risk.js.map +1 -0
  40. package/dist/mm/risk.test.d.ts +2 -0
  41. package/dist/mm/risk.test.d.ts.map +1 -0
  42. package/dist/mm/risk.test.js +297 -0
  43. package/dist/mm/risk.test.js.map +1 -0
  44. package/dist/mm/types.d.ts +128 -0
  45. package/dist/mm/types.d.ts.map +1 -0
  46. package/dist/mm/types.js +7 -0
  47. package/dist/mm/types.js.map +1 -0
  48. package/dist/websocket/auth.d.ts +9 -2
  49. package/dist/websocket/auth.d.ts.map +1 -1
  50. package/dist/websocket/auth.js +18 -13
  51. package/dist/websocket/auth.js.map +1 -1
  52. package/dist/websocket/auth.test.js +15 -6
  53. package/dist/websocket/auth.test.js.map +1 -1
  54. package/dist/websocket/client.d.ts.map +1 -1
  55. package/dist/websocket/client.js +6 -0
  56. package/dist/websocket/client.js.map +1 -1
  57. package/dist/websocket/types.d.ts +13 -1
  58. package/dist/websocket/types.d.ts.map +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Order Manager
3
+ *
4
+ * Manages the lifecycle of orders for market making.
5
+ * Handles placement, cancellation, and tracking of orders.
6
+ */
7
+ /**
8
+ * Generates a unique client order ID
9
+ */
10
+ function generateClientOrderId() {
11
+ return `mm-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
12
+ }
13
+ /**
14
+ * OrderManager handles order lifecycle for market making
15
+ */
16
+ export class OrderManager {
17
+ orders = new Map();
18
+ ordersApi;
19
+ constructor(ordersApi) {
20
+ this.ordersApi = ordersApi;
21
+ }
22
+ /**
23
+ * Place a new order
24
+ */
25
+ async place(input) {
26
+ const clientOrderId = generateClientOrderId();
27
+ // Create managed order (pending)
28
+ const managedOrder = {
29
+ clientOrderId,
30
+ ticker: input.ticker,
31
+ side: input.side,
32
+ action: input.action,
33
+ price: input.price,
34
+ count: input.count,
35
+ status: "pending",
36
+ createdAt: new Date(),
37
+ filledCount: 0,
38
+ };
39
+ this.orders.set(clientOrderId, managedOrder);
40
+ try {
41
+ // Place via Kalshi API
42
+ const response = await this.ordersApi.createOrder({
43
+ ticker: input.ticker,
44
+ type: "limit",
45
+ side: input.side,
46
+ action: input.action,
47
+ yes_price: input.side === "yes" ? input.price : undefined,
48
+ no_price: input.side === "no" ? input.price : undefined,
49
+ count: input.count,
50
+ client_order_id: clientOrderId,
51
+ });
52
+ // Update with Kalshi order ID
53
+ const kalshiOrder = response.data.order;
54
+ managedOrder.id = kalshiOrder?.order_id;
55
+ managedOrder.status = this.mapKalshiStatus(kalshiOrder?.status);
56
+ return { success: true, order: managedOrder };
57
+ }
58
+ catch (error) {
59
+ managedOrder.status = "failed";
60
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
61
+ return { success: false, order: managedOrder, error: errorMessage };
62
+ }
63
+ }
64
+ /**
65
+ * Place multiple orders (for two-sided quotes)
66
+ */
67
+ async placeBulk(inputs) {
68
+ // Place in parallel for speed
69
+ return Promise.all(inputs.map((input) => this.place(input)));
70
+ }
71
+ /**
72
+ * Cancel a specific order by client order ID
73
+ */
74
+ async cancel(clientOrderId) {
75
+ const order = this.orders.get(clientOrderId);
76
+ if (!order || !order.id) {
77
+ return false;
78
+ }
79
+ try {
80
+ await this.ordersApi.cancelOrder(order.id);
81
+ order.status = "cancelled";
82
+ return true;
83
+ }
84
+ catch {
85
+ // Order may already be filled or cancelled
86
+ return false;
87
+ }
88
+ }
89
+ /**
90
+ * Cancel all orders, optionally filtered by ticker
91
+ */
92
+ async cancelAll(ticker) {
93
+ const ordersToCancel = this.getActive(ticker);
94
+ let cancelledCount = 0;
95
+ // Cancel in parallel
96
+ const results = await Promise.allSettled(ordersToCancel.map((order) => this.cancel(order.clientOrderId)));
97
+ for (const result of results) {
98
+ if (result.status === "fulfilled" && result.value) {
99
+ cancelledCount++;
100
+ }
101
+ }
102
+ return cancelledCount;
103
+ }
104
+ /**
105
+ * Get all active (open/partial) orders
106
+ */
107
+ getActive(ticker) {
108
+ const activeStatuses = ["pending", "open", "partial"];
109
+ const result = [];
110
+ for (const order of this.orders.values()) {
111
+ if (!activeStatuses.includes(order.status))
112
+ continue;
113
+ if (ticker && order.ticker !== ticker)
114
+ continue;
115
+ result.push(order);
116
+ }
117
+ return result;
118
+ }
119
+ /**
120
+ * Get all orders (including filled/cancelled)
121
+ */
122
+ getAll() {
123
+ return Array.from(this.orders.values());
124
+ }
125
+ /**
126
+ * Get order by client order ID
127
+ */
128
+ get(clientOrderId) {
129
+ return this.orders.get(clientOrderId);
130
+ }
131
+ /**
132
+ * Update order status (called when we receive fill/cancel events)
133
+ */
134
+ updateStatus(clientOrderId, status, filledCount, avgFillPrice) {
135
+ const order = this.orders.get(clientOrderId);
136
+ if (!order)
137
+ return;
138
+ order.status = status;
139
+ if (filledCount !== undefined) {
140
+ order.filledCount = filledCount;
141
+ }
142
+ if (avgFillPrice !== undefined) {
143
+ order.avgFillPrice = avgFillPrice;
144
+ }
145
+ }
146
+ /**
147
+ * Update quotes for a market (ATOMIC: place new BEFORE canceling old)
148
+ *
149
+ * This is the main method for market making - it updates quotes with
150
+ * minimal exposure gap:
151
+ * 1. Place new orders first (briefly have double exposure)
152
+ * 2. Cancel old orders only after new ones confirmed
153
+ *
154
+ * This prevents the "naked" period where we have no quotes in market.
155
+ */
156
+ async updateQuote(quote) {
157
+ // Get existing orders for this ticker BEFORE placing new ones
158
+ const existingOrders = this.getActive(quote.ticker);
159
+ // Build new orders
160
+ const newOrders = [];
161
+ // Bid (buy YES at bid price)
162
+ if (quote.bidSize > 0 && quote.bidPrice >= 1 && quote.bidPrice <= 99) {
163
+ newOrders.push({
164
+ ticker: quote.ticker,
165
+ side: quote.side,
166
+ action: "buy",
167
+ price: quote.bidPrice,
168
+ count: quote.bidSize,
169
+ });
170
+ }
171
+ // Ask (sell YES at ask price, or buy NO)
172
+ if (quote.askSize > 0 && quote.askPrice >= 1 && quote.askPrice <= 99) {
173
+ newOrders.push({
174
+ ticker: quote.ticker,
175
+ side: quote.side,
176
+ action: "sell",
177
+ price: quote.askPrice,
178
+ count: quote.askSize,
179
+ });
180
+ }
181
+ // 1. Place new orders FIRST (we briefly have double exposure)
182
+ const placed = await this.placeBulk(newOrders);
183
+ // 2. Cancel old orders AFTER new ones are placed
184
+ // Even if new orders fail, we still cancel old stale quotes
185
+ let cancelled = 0;
186
+ if (existingOrders.length > 0) {
187
+ const cancelResults = await Promise.allSettled(existingOrders.map((order) => this.cancel(order.clientOrderId)));
188
+ for (const result of cancelResults) {
189
+ if (result.status === "fulfilled" && result.value) {
190
+ cancelled++;
191
+ }
192
+ }
193
+ }
194
+ return { cancelled, placed };
195
+ }
196
+ /**
197
+ * Update quotes (legacy mode: cancel first, then place)
198
+ * Use this if you're hitting rate limits from double orders
199
+ */
200
+ async updateQuoteLegacy(quote) {
201
+ // 1. Cancel existing orders for this ticker
202
+ const cancelled = await this.cancelAll(quote.ticker);
203
+ // 2. Place new bid and ask orders
204
+ const orders = [];
205
+ if (quote.bidSize > 0 && quote.bidPrice >= 1 && quote.bidPrice <= 99) {
206
+ orders.push({
207
+ ticker: quote.ticker,
208
+ side: quote.side,
209
+ action: "buy",
210
+ price: quote.bidPrice,
211
+ count: quote.bidSize,
212
+ });
213
+ }
214
+ if (quote.askSize > 0 && quote.askPrice >= 1 && quote.askPrice <= 99) {
215
+ orders.push({
216
+ ticker: quote.ticker,
217
+ side: quote.side,
218
+ action: "sell",
219
+ price: quote.askPrice,
220
+ count: quote.askSize,
221
+ });
222
+ }
223
+ const placed = await this.placeBulk(orders);
224
+ return { cancelled, placed };
225
+ }
226
+ /**
227
+ * Clean up old completed orders (keep memory bounded)
228
+ */
229
+ cleanup(maxAge = 24 * 60 * 60 * 1000) {
230
+ const now = Date.now();
231
+ const completedStatuses = ["filled", "cancelled", "failed"];
232
+ let removed = 0;
233
+ for (const [id, order] of this.orders) {
234
+ if (!completedStatuses.includes(order.status))
235
+ continue;
236
+ if (now - order.createdAt.getTime() > maxAge) {
237
+ this.orders.delete(id);
238
+ removed++;
239
+ }
240
+ }
241
+ return removed;
242
+ }
243
+ /**
244
+ * Map Kalshi order status to our internal status
245
+ */
246
+ mapKalshiStatus(status) {
247
+ switch (status?.toLowerCase()) {
248
+ case "resting":
249
+ return "open";
250
+ case "pending":
251
+ return "pending";
252
+ case "executed":
253
+ return "filled";
254
+ case "canceled":
255
+ case "cancelled":
256
+ return "cancelled";
257
+ default:
258
+ return "pending";
259
+ }
260
+ }
261
+ }
262
+ //# sourceMappingURL=order-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order-manager.js","sourceRoot":"","sources":["../../src/mm/order-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=order-manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order-manager.test.d.ts","sourceRoot":"","sources":["../../src/mm/order-manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,333 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import { OrderManager } from "./order-manager.js";
3
+ // Mock OrdersApi
4
+ function createMockOrdersApi() {
5
+ return {
6
+ createOrder: vi.fn().mockResolvedValue({
7
+ data: {
8
+ order: {
9
+ order_id: "kalshi-order-123",
10
+ status: "resting",
11
+ },
12
+ },
13
+ }),
14
+ cancelOrder: vi.fn().mockResolvedValue({}),
15
+ };
16
+ }
17
+ describe("OrderManager", () => {
18
+ let manager;
19
+ let mockApi;
20
+ beforeEach(() => {
21
+ mockApi = createMockOrdersApi();
22
+ manager = new OrderManager(mockApi);
23
+ });
24
+ describe("place", () => {
25
+ it("should place an order successfully", async () => {
26
+ const result = await manager.place({
27
+ ticker: "TEST-MARKET",
28
+ side: "yes",
29
+ action: "buy",
30
+ price: 50,
31
+ count: 10,
32
+ });
33
+ expect(result.success).toBe(true);
34
+ expect(result.order).toBeDefined();
35
+ expect(result.order.id).toBe("kalshi-order-123");
36
+ expect(result.order.status).toBe("open");
37
+ expect(result.order.ticker).toBe("TEST-MARKET");
38
+ expect(result.order.side).toBe("yes");
39
+ expect(result.order.action).toBe("buy");
40
+ expect(result.order.price).toBe(50);
41
+ expect(result.order.count).toBe(10);
42
+ });
43
+ it("should call API with correct parameters", async () => {
44
+ await manager.place({
45
+ ticker: "TEST-MARKET",
46
+ side: "yes",
47
+ action: "buy",
48
+ price: 50,
49
+ count: 10,
50
+ });
51
+ expect(mockApi.createOrder).toHaveBeenCalledWith(expect.objectContaining({
52
+ ticker: "TEST-MARKET",
53
+ type: "limit",
54
+ side: "yes",
55
+ action: "buy",
56
+ yes_price: 50,
57
+ count: 10,
58
+ }));
59
+ });
60
+ it("should use no_price for NO orders", async () => {
61
+ await manager.place({
62
+ ticker: "TEST-MARKET",
63
+ side: "no",
64
+ action: "buy",
65
+ price: 50,
66
+ count: 10,
67
+ });
68
+ expect(mockApi.createOrder).toHaveBeenCalledWith(expect.objectContaining({
69
+ side: "no",
70
+ no_price: 50,
71
+ yes_price: undefined,
72
+ }));
73
+ });
74
+ it("should handle API errors", async () => {
75
+ mockApi.createOrder.mockRejectedValue(new Error("API Error"));
76
+ const result = await manager.place({
77
+ ticker: "TEST-MARKET",
78
+ side: "yes",
79
+ action: "buy",
80
+ price: 50,
81
+ count: 10,
82
+ });
83
+ expect(result.success).toBe(false);
84
+ expect(result.error).toBe("API Error");
85
+ expect(result.order.status).toBe("failed");
86
+ });
87
+ it("should track order in internal state", async () => {
88
+ const result = await manager.place({
89
+ ticker: "TEST-MARKET",
90
+ side: "yes",
91
+ action: "buy",
92
+ price: 50,
93
+ count: 10,
94
+ });
95
+ const order = manager.get(result.order.clientOrderId);
96
+ expect(order).toBeDefined();
97
+ expect(order.id).toBe("kalshi-order-123");
98
+ });
99
+ });
100
+ describe("placeBulk", () => {
101
+ it("should place multiple orders", async () => {
102
+ const results = await manager.placeBulk([
103
+ { ticker: "TEST-MARKET", side: "yes", action: "buy", price: 45, count: 10 },
104
+ { ticker: "TEST-MARKET", side: "yes", action: "sell", price: 55, count: 10 },
105
+ ]);
106
+ expect(results).toHaveLength(2);
107
+ expect(results[0].success).toBe(true);
108
+ expect(results[1].success).toBe(true);
109
+ });
110
+ });
111
+ describe("cancel", () => {
112
+ it("should cancel an existing order", async () => {
113
+ const placed = await manager.place({
114
+ ticker: "TEST-MARKET",
115
+ side: "yes",
116
+ action: "buy",
117
+ price: 50,
118
+ count: 10,
119
+ });
120
+ const cancelled = await manager.cancel(placed.order.clientOrderId);
121
+ expect(cancelled).toBe(true);
122
+ expect(mockApi.cancelOrder).toHaveBeenCalledWith("kalshi-order-123");
123
+ const order = manager.get(placed.order.clientOrderId);
124
+ expect(order.status).toBe("cancelled");
125
+ });
126
+ it("should return false for unknown order", async () => {
127
+ const cancelled = await manager.cancel("unknown-order");
128
+ expect(cancelled).toBe(false);
129
+ });
130
+ it("should handle cancel API errors gracefully", async () => {
131
+ const placed = await manager.place({
132
+ ticker: "TEST-MARKET",
133
+ side: "yes",
134
+ action: "buy",
135
+ price: 50,
136
+ count: 10,
137
+ });
138
+ mockApi.cancelOrder.mockRejectedValue(new Error("Already filled"));
139
+ const cancelled = await manager.cancel(placed.order.clientOrderId);
140
+ expect(cancelled).toBe(false);
141
+ });
142
+ });
143
+ describe("cancelAll", () => {
144
+ it("should cancel all active orders", async () => {
145
+ await manager.place({
146
+ ticker: "MARKET-A",
147
+ side: "yes",
148
+ action: "buy",
149
+ price: 50,
150
+ count: 10,
151
+ });
152
+ await manager.place({
153
+ ticker: "MARKET-B",
154
+ side: "yes",
155
+ action: "buy",
156
+ price: 50,
157
+ count: 10,
158
+ });
159
+ const cancelled = await manager.cancelAll();
160
+ expect(cancelled).toBe(2);
161
+ });
162
+ it("should filter by ticker", async () => {
163
+ await manager.place({
164
+ ticker: "MARKET-A",
165
+ side: "yes",
166
+ action: "buy",
167
+ price: 50,
168
+ count: 10,
169
+ });
170
+ await manager.place({
171
+ ticker: "MARKET-B",
172
+ side: "yes",
173
+ action: "buy",
174
+ price: 50,
175
+ count: 10,
176
+ });
177
+ const cancelled = await manager.cancelAll("MARKET-A");
178
+ expect(cancelled).toBe(1);
179
+ });
180
+ });
181
+ describe("getActive", () => {
182
+ it("should return only active orders", async () => {
183
+ await manager.place({
184
+ ticker: "TEST-MARKET",
185
+ side: "yes",
186
+ action: "buy",
187
+ price: 50,
188
+ count: 10,
189
+ });
190
+ const active = manager.getActive();
191
+ expect(active).toHaveLength(1);
192
+ });
193
+ it("should filter by ticker", async () => {
194
+ await manager.place({
195
+ ticker: "MARKET-A",
196
+ side: "yes",
197
+ action: "buy",
198
+ price: 50,
199
+ count: 10,
200
+ });
201
+ await manager.place({
202
+ ticker: "MARKET-B",
203
+ side: "yes",
204
+ action: "buy",
205
+ price: 50,
206
+ count: 10,
207
+ });
208
+ const active = manager.getActive("MARKET-A");
209
+ expect(active).toHaveLength(1);
210
+ expect(active[0].ticker).toBe("MARKET-A");
211
+ });
212
+ it("should not include cancelled orders", async () => {
213
+ const placed = await manager.place({
214
+ ticker: "TEST-MARKET",
215
+ side: "yes",
216
+ action: "buy",
217
+ price: 50,
218
+ count: 10,
219
+ });
220
+ await manager.cancel(placed.order.clientOrderId);
221
+ const active = manager.getActive();
222
+ expect(active).toHaveLength(0);
223
+ });
224
+ });
225
+ describe("getAll", () => {
226
+ it("should return all orders including cancelled", async () => {
227
+ const placed = await manager.place({
228
+ ticker: "TEST-MARKET",
229
+ side: "yes",
230
+ action: "buy",
231
+ price: 50,
232
+ count: 10,
233
+ });
234
+ await manager.cancel(placed.order.clientOrderId);
235
+ const all = manager.getAll();
236
+ expect(all).toHaveLength(1);
237
+ expect(all[0].status).toBe("cancelled");
238
+ });
239
+ });
240
+ describe("updateStatus", () => {
241
+ it("should update order status", async () => {
242
+ const placed = await manager.place({
243
+ ticker: "TEST-MARKET",
244
+ side: "yes",
245
+ action: "buy",
246
+ price: 50,
247
+ count: 10,
248
+ });
249
+ manager.updateStatus(placed.order.clientOrderId, "filled", 10, 50);
250
+ const order = manager.get(placed.order.clientOrderId);
251
+ expect(order.status).toBe("filled");
252
+ expect(order.filledCount).toBe(10);
253
+ expect(order.avgFillPrice).toBe(50);
254
+ });
255
+ });
256
+ describe("updateQuote", () => {
257
+ it("should cancel existing and place new orders", async () => {
258
+ // Place initial order
259
+ await manager.place({
260
+ ticker: "TEST-MARKET",
261
+ side: "yes",
262
+ action: "buy",
263
+ price: 45,
264
+ count: 10,
265
+ });
266
+ // Update quote
267
+ const result = await manager.updateQuote({
268
+ ticker: "TEST-MARKET",
269
+ side: "yes",
270
+ bidPrice: 48,
271
+ bidSize: 15,
272
+ askPrice: 52,
273
+ askSize: 15,
274
+ });
275
+ expect(result.cancelled).toBe(1);
276
+ expect(result.placed).toHaveLength(2); // bid and ask
277
+ });
278
+ it("should skip invalid prices", async () => {
279
+ const result = await manager.updateQuote({
280
+ ticker: "TEST-MARKET",
281
+ side: "yes",
282
+ bidPrice: 0, // Invalid
283
+ bidSize: 10,
284
+ askPrice: 100, // Invalid
285
+ askSize: 10,
286
+ });
287
+ expect(result.placed).toHaveLength(0);
288
+ });
289
+ it("should skip zero size", async () => {
290
+ const result = await manager.updateQuote({
291
+ ticker: "TEST-MARKET",
292
+ side: "yes",
293
+ bidPrice: 45,
294
+ bidSize: 0, // Zero
295
+ askPrice: 55,
296
+ askSize: 10,
297
+ });
298
+ expect(result.placed).toHaveLength(1); // Only ask
299
+ });
300
+ });
301
+ describe("cleanup", () => {
302
+ it("should remove old completed orders", async () => {
303
+ const placed = await manager.place({
304
+ ticker: "TEST-MARKET",
305
+ side: "yes",
306
+ action: "buy",
307
+ price: 50,
308
+ count: 10,
309
+ });
310
+ // Mark as filled
311
+ manager.updateStatus(placed.order.clientOrderId, "filled");
312
+ // Backdate the order
313
+ const order = manager.get(placed.order.clientOrderId);
314
+ order.createdAt = new Date(Date.now() - 48 * 60 * 60 * 1000); // 48 hours ago
315
+ const removed = manager.cleanup(24 * 60 * 60 * 1000); // 24 hour max age
316
+ expect(removed).toBe(1);
317
+ expect(manager.getAll()).toHaveLength(0);
318
+ });
319
+ it("should not remove active orders", async () => {
320
+ await manager.place({
321
+ ticker: "TEST-MARKET",
322
+ side: "yes",
323
+ action: "buy",
324
+ price: 50,
325
+ count: 10,
326
+ });
327
+ const removed = manager.cleanup(0); // Even with 0 max age
328
+ expect(removed).toBe(0);
329
+ expect(manager.getAll()).toHaveLength(1);
330
+ });
331
+ });
332
+ });
333
+ //# sourceMappingURL=order-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order-manager.test.js","sourceRoot":"","sources":["../../src/mm/order-manager.test.ts"],"names":[],"mappings":"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"}