@newyorkcompute/kalshi-core 0.2.0 → 0.4.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 (75) hide show
  1. package/dist/config.d.ts +61 -6
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +56 -5
  4. package/dist/config.js.map +1 -1
  5. package/dist/config.test.d.ts +2 -0
  6. package/dist/config.test.d.ts.map +1 -0
  7. package/dist/config.test.js +94 -0
  8. package/dist/config.test.js.map +1 -0
  9. package/dist/format.d.ts +71 -2
  10. package/dist/format.d.ts.map +1 -1
  11. package/dist/format.js +71 -2
  12. package/dist/format.js.map +1 -1
  13. package/dist/format.test.js +42 -1
  14. package/dist/format.test.js.map +1 -1
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/mm/index.d.ts +10 -0
  20. package/dist/mm/index.d.ts.map +1 -0
  21. package/dist/mm/index.js +12 -0
  22. package/dist/mm/index.js.map +1 -0
  23. package/dist/mm/inventory.d.ts +70 -0
  24. package/dist/mm/inventory.d.ts.map +1 -0
  25. package/dist/mm/inventory.js +171 -0
  26. package/dist/mm/inventory.js.map +1 -0
  27. package/dist/mm/inventory.test.d.ts +2 -0
  28. package/dist/mm/inventory.test.d.ts.map +1 -0
  29. package/dist/mm/inventory.test.js +358 -0
  30. package/dist/mm/inventory.test.js.map +1 -0
  31. package/dist/mm/order-manager.d.ts +81 -0
  32. package/dist/mm/order-manager.d.ts.map +1 -0
  33. package/dist/mm/order-manager.js +216 -0
  34. package/dist/mm/order-manager.js.map +1 -0
  35. package/dist/mm/order-manager.test.d.ts +2 -0
  36. package/dist/mm/order-manager.test.d.ts.map +1 -0
  37. package/dist/mm/order-manager.test.js +333 -0
  38. package/dist/mm/order-manager.test.js.map +1 -0
  39. package/dist/mm/risk.d.ts +77 -0
  40. package/dist/mm/risk.d.ts.map +1 -0
  41. package/dist/mm/risk.js +179 -0
  42. package/dist/mm/risk.js.map +1 -0
  43. package/dist/mm/risk.test.d.ts +2 -0
  44. package/dist/mm/risk.test.d.ts.map +1 -0
  45. package/dist/mm/risk.test.js +297 -0
  46. package/dist/mm/risk.test.js.map +1 -0
  47. package/dist/mm/types.d.ts +128 -0
  48. package/dist/mm/types.d.ts.map +1 -0
  49. package/dist/mm/types.js +7 -0
  50. package/dist/mm/types.js.map +1 -0
  51. package/dist/websocket/auth.d.ts +35 -0
  52. package/dist/websocket/auth.d.ts.map +1 -0
  53. package/dist/websocket/auth.js +60 -0
  54. package/dist/websocket/auth.js.map +1 -0
  55. package/dist/websocket/auth.test.d.ts +2 -0
  56. package/dist/websocket/auth.test.d.ts.map +1 -0
  57. package/dist/websocket/auth.test.js +65 -0
  58. package/dist/websocket/auth.test.js.map +1 -0
  59. package/dist/websocket/client.d.ts +95 -0
  60. package/dist/websocket/client.d.ts.map +1 -0
  61. package/dist/websocket/client.js +358 -0
  62. package/dist/websocket/client.js.map +1 -0
  63. package/dist/websocket/index.d.ts +9 -0
  64. package/dist/websocket/index.d.ts.map +1 -0
  65. package/dist/websocket/index.js +9 -0
  66. package/dist/websocket/index.js.map +1 -0
  67. package/dist/websocket/types.d.ts +172 -0
  68. package/dist/websocket/types.d.ts.map +1 -0
  69. package/dist/websocket/types.js +12 -0
  70. package/dist/websocket/types.js.map +1 -0
  71. package/dist/websocket/types.test.d.ts +2 -0
  72. package/dist/websocket/types.test.d.ts.map +1 -0
  73. package/dist/websocket/types.test.js +17 -0
  74. package/dist/websocket/types.test.js.map +1 -0
  75. package/package.json +8 -4
@@ -0,0 +1,358 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { InventoryTracker } from "./inventory.js";
3
+ describe("InventoryTracker", () => {
4
+ let tracker;
5
+ beforeEach(() => {
6
+ tracker = new InventoryTracker();
7
+ });
8
+ describe("onFill", () => {
9
+ it("should add YES contracts on buy", () => {
10
+ const fill = {
11
+ orderId: "order1",
12
+ ticker: "TEST-MARKET",
13
+ side: "yes",
14
+ action: "buy",
15
+ count: 10,
16
+ price: 50,
17
+ timestamp: new Date(),
18
+ };
19
+ tracker.onFill(fill);
20
+ const position = tracker.getPosition("TEST-MARKET");
21
+ expect(position).toBeDefined();
22
+ expect(position.yesContracts).toBe(10);
23
+ expect(position.noContracts).toBe(0);
24
+ expect(position.netExposure).toBe(10);
25
+ });
26
+ it("should subtract YES contracts on sell", () => {
27
+ // First buy
28
+ tracker.onFill({
29
+ orderId: "order1",
30
+ ticker: "TEST-MARKET",
31
+ side: "yes",
32
+ action: "buy",
33
+ count: 10,
34
+ price: 50,
35
+ timestamp: new Date(),
36
+ });
37
+ // Then sell
38
+ tracker.onFill({
39
+ orderId: "order2",
40
+ ticker: "TEST-MARKET",
41
+ side: "yes",
42
+ action: "sell",
43
+ count: 5,
44
+ price: 55,
45
+ timestamp: new Date(),
46
+ });
47
+ const position = tracker.getPosition("TEST-MARKET");
48
+ expect(position.yesContracts).toBe(5);
49
+ expect(position.netExposure).toBe(5);
50
+ });
51
+ it("should add NO contracts on buy", () => {
52
+ const fill = {
53
+ orderId: "order1",
54
+ ticker: "TEST-MARKET",
55
+ side: "no",
56
+ action: "buy",
57
+ count: 10,
58
+ price: 50,
59
+ timestamp: new Date(),
60
+ };
61
+ tracker.onFill(fill);
62
+ const position = tracker.getPosition("TEST-MARKET");
63
+ expect(position.noContracts).toBe(10);
64
+ expect(position.yesContracts).toBe(0);
65
+ expect(position.netExposure).toBe(-10); // Negative because NO
66
+ });
67
+ it("should track multiple markets independently", () => {
68
+ tracker.onFill({
69
+ orderId: "order1",
70
+ ticker: "MARKET-A",
71
+ side: "yes",
72
+ action: "buy",
73
+ count: 10,
74
+ price: 50,
75
+ timestamp: new Date(),
76
+ });
77
+ tracker.onFill({
78
+ orderId: "order2",
79
+ ticker: "MARKET-B",
80
+ side: "yes",
81
+ action: "buy",
82
+ count: 20,
83
+ price: 60,
84
+ timestamp: new Date(),
85
+ });
86
+ expect(tracker.getPosition("MARKET-A").yesContracts).toBe(10);
87
+ expect(tracker.getPosition("MARKET-B").yesContracts).toBe(20);
88
+ });
89
+ it("should update daily stats", () => {
90
+ tracker.onFill({
91
+ orderId: "order1",
92
+ ticker: "TEST-MARKET",
93
+ side: "yes",
94
+ action: "buy",
95
+ count: 10,
96
+ price: 50,
97
+ timestamp: new Date(),
98
+ });
99
+ tracker.onFill({
100
+ orderId: "order2",
101
+ ticker: "TEST-MARKET",
102
+ side: "yes",
103
+ action: "buy",
104
+ count: 5,
105
+ price: 55,
106
+ timestamp: new Date(),
107
+ });
108
+ const summary = tracker.getPnLSummary();
109
+ expect(summary.fillsToday).toBe(2);
110
+ expect(summary.volumeToday).toBe(15);
111
+ });
112
+ });
113
+ describe("getTotalExposure", () => {
114
+ it("should return 0 with no positions", () => {
115
+ expect(tracker.getTotalExposure()).toBe(0);
116
+ });
117
+ it("should sum absolute exposures across markets", () => {
118
+ tracker.onFill({
119
+ orderId: "order1",
120
+ ticker: "MARKET-A",
121
+ side: "yes",
122
+ action: "buy",
123
+ count: 10,
124
+ price: 50,
125
+ timestamp: new Date(),
126
+ });
127
+ tracker.onFill({
128
+ orderId: "order2",
129
+ ticker: "MARKET-B",
130
+ side: "no",
131
+ action: "buy",
132
+ count: 5,
133
+ price: 50,
134
+ timestamp: new Date(),
135
+ });
136
+ // A: +10 yes = +10 exposure
137
+ // B: +5 no = -5 exposure (absolute = 5)
138
+ expect(tracker.getTotalExposure()).toBe(15);
139
+ });
140
+ });
141
+ describe("getNetExposure", () => {
142
+ it("should return 0 for unknown ticker", () => {
143
+ expect(tracker.getNetExposure("UNKNOWN")).toBe(0);
144
+ });
145
+ it("should return correct net exposure", () => {
146
+ tracker.onFill({
147
+ orderId: "order1",
148
+ ticker: "TEST-MARKET",
149
+ side: "yes",
150
+ action: "buy",
151
+ count: 10,
152
+ price: 50,
153
+ timestamp: new Date(),
154
+ });
155
+ expect(tracker.getNetExposure("TEST-MARKET")).toBe(10);
156
+ });
157
+ });
158
+ describe("getAllPositions", () => {
159
+ it("should return empty array with no positions", () => {
160
+ expect(tracker.getAllPositions()).toEqual([]);
161
+ });
162
+ it("should return all positions", () => {
163
+ tracker.onFill({
164
+ orderId: "order1",
165
+ ticker: "MARKET-A",
166
+ side: "yes",
167
+ action: "buy",
168
+ count: 10,
169
+ price: 50,
170
+ timestamp: new Date(),
171
+ });
172
+ tracker.onFill({
173
+ orderId: "order2",
174
+ ticker: "MARKET-B",
175
+ side: "yes",
176
+ action: "buy",
177
+ count: 20,
178
+ price: 60,
179
+ timestamp: new Date(),
180
+ });
181
+ const positions = tracker.getAllPositions();
182
+ expect(positions).toHaveLength(2);
183
+ });
184
+ });
185
+ describe("resetDaily", () => {
186
+ it("should reset daily stats", () => {
187
+ tracker.onFill({
188
+ orderId: "order1",
189
+ ticker: "TEST-MARKET",
190
+ side: "yes",
191
+ action: "buy",
192
+ count: 10,
193
+ price: 50,
194
+ timestamp: new Date(),
195
+ });
196
+ tracker.resetDaily();
197
+ const summary = tracker.getPnLSummary();
198
+ expect(summary.fillsToday).toBe(0);
199
+ expect(summary.volumeToday).toBe(0);
200
+ expect(summary.realizedToday).toBe(0);
201
+ });
202
+ it("should preserve positions after reset", () => {
203
+ tracker.onFill({
204
+ orderId: "order1",
205
+ ticker: "TEST-MARKET",
206
+ side: "yes",
207
+ action: "buy",
208
+ count: 10,
209
+ price: 50,
210
+ timestamp: new Date(),
211
+ });
212
+ tracker.resetDaily();
213
+ const position = tracker.getPosition("TEST-MARKET");
214
+ expect(position.yesContracts).toBe(10);
215
+ });
216
+ });
217
+ describe("clear", () => {
218
+ it("should remove all positions", () => {
219
+ tracker.onFill({
220
+ orderId: "order1",
221
+ ticker: "TEST-MARKET",
222
+ side: "yes",
223
+ action: "buy",
224
+ count: 10,
225
+ price: 50,
226
+ timestamp: new Date(),
227
+ });
228
+ tracker.clear();
229
+ expect(tracker.getAllPositions()).toEqual([]);
230
+ expect(tracker.getPosition("TEST-MARKET")).toBeUndefined();
231
+ });
232
+ });
233
+ describe("initializeFromPortfolio", () => {
234
+ it("should initialize positions from portfolio data", () => {
235
+ tracker.initializeFromPortfolio([
236
+ { ticker: "MARKET-A", yesContracts: 10, noContracts: 0, costBasis: 500 },
237
+ { ticker: "MARKET-B", yesContracts: 0, noContracts: 5, costBasis: 250 },
238
+ ]);
239
+ const posA = tracker.getPosition("MARKET-A");
240
+ expect(posA.yesContracts).toBe(10);
241
+ expect(posA.netExposure).toBe(10);
242
+ const posB = tracker.getPosition("MARKET-B");
243
+ expect(posB.noContracts).toBe(5);
244
+ expect(posB.netExposure).toBe(-5);
245
+ });
246
+ });
247
+ describe("getPnLSummary with currentPrices", () => {
248
+ it("should calculate unrealized PnL for YES position", () => {
249
+ // Buy 10 YES @ 50¢ = 500¢ cost
250
+ tracker.onFill({
251
+ orderId: "order1",
252
+ ticker: "TEST-MARKET",
253
+ side: "yes",
254
+ action: "buy",
255
+ count: 10,
256
+ price: 50,
257
+ timestamp: new Date(),
258
+ });
259
+ // Current price is 60¢ - unrealized profit = 10 * (60 - 50) = 100¢
260
+ const prices = new Map([["TEST-MARKET", 60]]);
261
+ const summary = tracker.getPnLSummary(prices);
262
+ expect(summary.unrealized).toBe(100);
263
+ expect(summary.total).toBe(100);
264
+ });
265
+ it("should calculate unrealized PnL for NO position", () => {
266
+ // Buy 10 NO @ 40¢ = 400¢ cost
267
+ tracker.onFill({
268
+ orderId: "order1",
269
+ ticker: "TEST-MARKET",
270
+ side: "no",
271
+ action: "buy",
272
+ count: 10,
273
+ price: 40,
274
+ timestamp: new Date(),
275
+ });
276
+ // Current YES price is 50¢, so NO value = 10 * (100-50) = 500¢
277
+ // Unrealized = 500 - 400 = 100¢
278
+ const prices = new Map([["TEST-MARKET", 50]]);
279
+ const summary = tracker.getPnLSummary(prices);
280
+ expect(summary.unrealized).toBe(100);
281
+ });
282
+ it("should skip positions with zero exposure", () => {
283
+ tracker.initializeFromPortfolio([
284
+ { ticker: "MARKET-A", yesContracts: 0, noContracts: 0, costBasis: 0 },
285
+ ]);
286
+ const prices = new Map([["MARKET-A", 50]]);
287
+ const summary = tracker.getPnLSummary(prices);
288
+ expect(summary.unrealized).toBe(0);
289
+ });
290
+ it("should skip markets without current price", () => {
291
+ tracker.onFill({
292
+ orderId: "order1",
293
+ ticker: "TEST-MARKET",
294
+ side: "yes",
295
+ action: "buy",
296
+ count: 10,
297
+ price: 50,
298
+ timestamp: new Date(),
299
+ });
300
+ // Empty prices map
301
+ const prices = new Map();
302
+ const summary = tracker.getPnLSummary(prices);
303
+ expect(summary.unrealized).toBe(0);
304
+ });
305
+ });
306
+ describe("sell NO contracts", () => {
307
+ it("should subtract NO contracts on sell", () => {
308
+ // First buy NO
309
+ tracker.onFill({
310
+ orderId: "order1",
311
+ ticker: "TEST-MARKET",
312
+ side: "no",
313
+ action: "buy",
314
+ count: 10,
315
+ price: 40,
316
+ timestamp: new Date(),
317
+ });
318
+ // Then sell NO
319
+ tracker.onFill({
320
+ orderId: "order2",
321
+ ticker: "TEST-MARKET",
322
+ side: "no",
323
+ action: "sell",
324
+ count: 5,
325
+ price: 45,
326
+ timestamp: new Date(),
327
+ });
328
+ const position = tracker.getPosition("TEST-MARKET");
329
+ expect(position.noContracts).toBe(5);
330
+ expect(position.netExposure).toBe(-5);
331
+ });
332
+ it("should calculate realized PnL when selling NO", () => {
333
+ // Buy 10 NO @ 40¢
334
+ tracker.onFill({
335
+ orderId: "order1",
336
+ ticker: "TEST-MARKET",
337
+ side: "no",
338
+ action: "buy",
339
+ count: 10,
340
+ price: 40,
341
+ timestamp: new Date(),
342
+ });
343
+ // Sell 5 NO @ 50¢ - profit = 5 * (50 - 40) = 50¢
344
+ tracker.onFill({
345
+ orderId: "order2",
346
+ ticker: "TEST-MARKET",
347
+ side: "no",
348
+ action: "sell",
349
+ count: 5,
350
+ price: 50,
351
+ timestamp: new Date(),
352
+ });
353
+ const summary = tracker.getPnLSummary();
354
+ expect(summary.realizedToday).toBeGreaterThan(0);
355
+ });
356
+ });
357
+ });
358
+ //# sourceMappingURL=inventory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inventory.test.js","sourceRoot":"","sources":["../../src/mm/inventory.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Order Manager
3
+ *
4
+ * Manages the lifecycle of orders for market making.
5
+ * Handles placement, cancellation, and tracking of orders.
6
+ */
7
+ import type { OrdersApi } from "kalshi-typescript";
8
+ import type { ManagedOrder, Side, Action, OrderStatus, Quote } from "./types.js";
9
+ /** Input for creating a new order */
10
+ export interface CreateOrderInput {
11
+ ticker: string;
12
+ side: Side;
13
+ action: Action;
14
+ price: number;
15
+ count: number;
16
+ }
17
+ /** Result of order placement */
18
+ export interface PlaceOrderResult {
19
+ success: boolean;
20
+ order?: ManagedOrder;
21
+ error?: string;
22
+ }
23
+ /**
24
+ * OrderManager handles order lifecycle for market making
25
+ */
26
+ export declare class OrderManager {
27
+ private orders;
28
+ private ordersApi;
29
+ constructor(ordersApi: OrdersApi);
30
+ /**
31
+ * Place a new order
32
+ */
33
+ place(input: CreateOrderInput): Promise<PlaceOrderResult>;
34
+ /**
35
+ * Place multiple orders (for two-sided quotes)
36
+ */
37
+ placeBulk(inputs: CreateOrderInput[]): Promise<PlaceOrderResult[]>;
38
+ /**
39
+ * Cancel a specific order by client order ID
40
+ */
41
+ cancel(clientOrderId: string): Promise<boolean>;
42
+ /**
43
+ * Cancel all orders, optionally filtered by ticker
44
+ */
45
+ cancelAll(ticker?: string): Promise<number>;
46
+ /**
47
+ * Get all active (open/partial) orders
48
+ */
49
+ getActive(ticker?: string): ManagedOrder[];
50
+ /**
51
+ * Get all orders (including filled/cancelled)
52
+ */
53
+ getAll(): ManagedOrder[];
54
+ /**
55
+ * Get order by client order ID
56
+ */
57
+ get(clientOrderId: string): ManagedOrder | undefined;
58
+ /**
59
+ * Update order status (called when we receive fill/cancel events)
60
+ */
61
+ updateStatus(clientOrderId: string, status: OrderStatus, filledCount?: number, avgFillPrice?: number): void;
62
+ /**
63
+ * Update quotes for a market (cancel old, place new)
64
+ *
65
+ * This is the main method for market making - it atomically updates
66
+ * the bid/ask quotes for a given market.
67
+ */
68
+ updateQuote(quote: Quote): Promise<{
69
+ cancelled: number;
70
+ placed: PlaceOrderResult[];
71
+ }>;
72
+ /**
73
+ * Clean up old completed orders (keep memory bounded)
74
+ */
75
+ cleanup(maxAge?: number): number;
76
+ /**
77
+ * Map Kalshi order status to our internal status
78
+ */
79
+ private mapKalshiStatus;
80
+ }
81
+ //# sourceMappingURL=order-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order-manager.d.ts","sourceRoot":"","sources":["../../src/mm/order-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EACV,YAAY,EACZ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,EACN,MAAM,YAAY,CAAC;AAEpB,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,SAAS,CAAY;gBAEjB,SAAS,EAAE,SAAS;IAIhC;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6C/D;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAKxE;;OAEG;IACG,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBrD;;OAEG;IACG,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBjD;;OAEG;IACH,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE;IAa1C;;OAEG;IACH,MAAM,IAAI,YAAY,EAAE;IAIxB;;OAEG;IACH,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIpD;;OAEG;IACH,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI;IAaP;;;;;OAKG;IACG,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,gBAAgB,EAAE,CAAC;KAC5B,CAAC;IAkCF;;OAEG;IACH,OAAO,CAAC,MAAM,GAAE,MAA4B,GAAG,MAAM;IAgBrD;;OAEG;IACH,OAAO,CAAC,eAAe;CAexB"}
@@ -0,0 +1,216 @@
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 (cancel old, place new)
148
+ *
149
+ * This is the main method for market making - it atomically updates
150
+ * the bid/ask quotes for a given market.
151
+ */
152
+ async updateQuote(quote) {
153
+ // 1. Cancel existing orders for this ticker
154
+ const cancelled = await this.cancelAll(quote.ticker);
155
+ // 2. Place new bid and ask orders
156
+ const orders = [];
157
+ // Bid (buy YES at bid price)
158
+ if (quote.bidSize > 0 && quote.bidPrice >= 1 && quote.bidPrice <= 99) {
159
+ orders.push({
160
+ ticker: quote.ticker,
161
+ side: quote.side,
162
+ action: "buy",
163
+ price: quote.bidPrice,
164
+ count: quote.bidSize,
165
+ });
166
+ }
167
+ // Ask (sell YES at ask price, or buy NO)
168
+ if (quote.askSize > 0 && quote.askPrice >= 1 && quote.askPrice <= 99) {
169
+ orders.push({
170
+ ticker: quote.ticker,
171
+ side: quote.side,
172
+ action: "sell",
173
+ price: quote.askPrice,
174
+ count: quote.askSize,
175
+ });
176
+ }
177
+ const placed = await this.placeBulk(orders);
178
+ return { cancelled, placed };
179
+ }
180
+ /**
181
+ * Clean up old completed orders (keep memory bounded)
182
+ */
183
+ cleanup(maxAge = 24 * 60 * 60 * 1000) {
184
+ const now = Date.now();
185
+ const completedStatuses = ["filled", "cancelled", "failed"];
186
+ let removed = 0;
187
+ for (const [id, order] of this.orders) {
188
+ if (!completedStatuses.includes(order.status))
189
+ continue;
190
+ if (now - order.createdAt.getTime() > maxAge) {
191
+ this.orders.delete(id);
192
+ removed++;
193
+ }
194
+ }
195
+ return removed;
196
+ }
197
+ /**
198
+ * Map Kalshi order status to our internal status
199
+ */
200
+ mapKalshiStatus(status) {
201
+ switch (status?.toLowerCase()) {
202
+ case "resting":
203
+ return "open";
204
+ case "pending":
205
+ return "pending";
206
+ case "executed":
207
+ return "filled";
208
+ case "canceled":
209
+ case "cancelled":
210
+ return "cancelled";
211
+ default:
212
+ return "pending";
213
+ }
214
+ }
215
+ }
216
+ //# sourceMappingURL=order-manager.js.map