@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.
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mm/index.d.ts +11 -0
- package/dist/mm/index.d.ts.map +1 -0
- package/dist/mm/index.js +14 -0
- package/dist/mm/index.js.map +1 -0
- package/dist/mm/inventory.d.ts +70 -0
- package/dist/mm/inventory.d.ts.map +1 -0
- package/dist/mm/inventory.js +171 -0
- package/dist/mm/inventory.js.map +1 -0
- package/dist/mm/inventory.test.d.ts +2 -0
- package/dist/mm/inventory.test.d.ts.map +1 -0
- package/dist/mm/inventory.test.js +358 -0
- package/dist/mm/inventory.test.js.map +1 -0
- package/dist/mm/order-manager.d.ts +93 -0
- package/dist/mm/order-manager.d.ts.map +1 -0
- package/dist/mm/order-manager.js +262 -0
- package/dist/mm/order-manager.js.map +1 -0
- package/dist/mm/order-manager.test.d.ts +2 -0
- package/dist/mm/order-manager.test.d.ts.map +1 -0
- package/dist/mm/order-manager.test.js +333 -0
- package/dist/mm/order-manager.test.js.map +1 -0
- package/dist/mm/orderbook.d.ts +162 -0
- package/dist/mm/orderbook.d.ts.map +1 -0
- package/dist/mm/orderbook.js +271 -0
- package/dist/mm/orderbook.js.map +1 -0
- package/dist/mm/orderbook.test.d.ts +2 -0
- package/dist/mm/orderbook.test.d.ts.map +1 -0
- package/dist/mm/orderbook.test.js +264 -0
- package/dist/mm/orderbook.test.js.map +1 -0
- package/dist/mm/risk.d.ts +77 -0
- package/dist/mm/risk.d.ts.map +1 -0
- package/dist/mm/risk.js +179 -0
- package/dist/mm/risk.js.map +1 -0
- package/dist/mm/risk.test.d.ts +2 -0
- package/dist/mm/risk.test.d.ts.map +1 -0
- package/dist/mm/risk.test.js +297 -0
- package/dist/mm/risk.test.js.map +1 -0
- package/dist/mm/types.d.ts +128 -0
- package/dist/mm/types.d.ts.map +1 -0
- package/dist/mm/types.js +7 -0
- package/dist/mm/types.js.map +1 -0
- package/dist/websocket/auth.d.ts +9 -2
- package/dist/websocket/auth.d.ts.map +1 -1
- package/dist/websocket/auth.js +18 -13
- package/dist/websocket/auth.js.map +1 -1
- package/dist/websocket/auth.test.js +15 -6
- package/dist/websocket/auth.test.js.map +1 -1
- package/dist/websocket/client.d.ts.map +1 -1
- package/dist/websocket/client.js +6 -0
- package/dist/websocket/client.js.map +1 -1
- package/dist/websocket/types.d.ts +13 -1
- package/dist/websocket/types.d.ts.map +1 -1
- 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 @@
|
|
|
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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"}
|