pmxt-core 2.20.0 → 2.20.2

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 (113) hide show
  1. package/dist/exchanges/baozi/fetcher.d.ts +40 -0
  2. package/dist/exchanges/baozi/fetcher.js +155 -0
  3. package/dist/exchanges/baozi/index.d.ts +2 -0
  4. package/dist/exchanges/baozi/index.js +60 -131
  5. package/dist/exchanges/baozi/normalizer.d.ts +14 -0
  6. package/dist/exchanges/baozi/normalizer.js +208 -0
  7. package/dist/exchanges/interfaces.d.ts +28 -0
  8. package/dist/exchanges/interfaces.js +2 -0
  9. package/dist/exchanges/kalshi/api.d.ts +1 -1
  10. package/dist/exchanges/kalshi/api.js +1 -1
  11. package/dist/exchanges/kalshi/fetcher.d.ts +126 -0
  12. package/dist/exchanges/kalshi/fetcher.js +313 -0
  13. package/dist/exchanges/kalshi/index.d.ts +6 -6
  14. package/dist/exchanges/kalshi/index.js +119 -202
  15. package/dist/exchanges/kalshi/normalizer.d.ts +25 -0
  16. package/dist/exchanges/kalshi/normalizer.js +294 -0
  17. package/dist/exchanges/limitless/api.d.ts +1 -1
  18. package/dist/exchanges/limitless/api.js +1 -1
  19. package/dist/exchanges/limitless/fetcher.d.ts +81 -0
  20. package/dist/exchanges/limitless/fetcher.js +238 -0
  21. package/dist/exchanges/limitless/index.d.ts +6 -9
  22. package/dist/exchanges/limitless/index.js +81 -79
  23. package/dist/exchanges/limitless/normalizer.d.ts +14 -0
  24. package/dist/exchanges/limitless/normalizer.js +117 -0
  25. package/dist/exchanges/limitless/websocket.d.ts +3 -0
  26. package/dist/exchanges/limitless/websocket.js +5 -4
  27. package/dist/exchanges/myriad/api.d.ts +1 -1
  28. package/dist/exchanges/myriad/api.js +1 -1
  29. package/dist/exchanges/myriad/fetcher.d.ts +73 -0
  30. package/dist/exchanges/myriad/fetcher.js +217 -0
  31. package/dist/exchanges/myriad/index.d.ts +2 -0
  32. package/dist/exchanges/myriad/index.js +40 -97
  33. package/dist/exchanges/myriad/normalizer.d.ts +14 -0
  34. package/dist/exchanges/myriad/normalizer.js +167 -0
  35. package/dist/exchanges/myriad/websocket.d.ts +3 -1
  36. package/dist/exchanges/myriad/websocket.js +4 -3
  37. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  38. package/dist/exchanges/polymarket/api-clob.js +1 -1
  39. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  40. package/dist/exchanges/polymarket/api-data.js +1 -1
  41. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  42. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  43. package/dist/exchanges/polymarket/fetcher.d.ts +99 -0
  44. package/dist/exchanges/polymarket/fetcher.js +335 -0
  45. package/dist/exchanges/polymarket/index.d.ts +2 -0
  46. package/dist/exchanges/polymarket/index.js +80 -66
  47. package/dist/exchanges/polymarket/normalizer.d.ts +18 -0
  48. package/dist/exchanges/polymarket/normalizer.js +126 -0
  49. package/dist/exchanges/probable/api.d.ts +1 -1
  50. package/dist/exchanges/probable/api.js +1 -1
  51. package/dist/exchanges/probable/fetcher.d.ts +106 -0
  52. package/dist/exchanges/probable/fetcher.js +357 -0
  53. package/dist/exchanges/probable/index.d.ts +3 -1
  54. package/dist/exchanges/probable/index.js +73 -105
  55. package/dist/exchanges/probable/normalizer.d.ts +14 -0
  56. package/dist/exchanges/probable/normalizer.js +109 -0
  57. package/dist/utils/error-mapper.d.ts +8 -0
  58. package/dist/utils/error-mapper.js +58 -26
  59. package/package.json +3 -3
  60. package/dist/exchanges/baozi/fetchEvents.d.ts +0 -8
  61. package/dist/exchanges/baozi/fetchEvents.js +0 -39
  62. package/dist/exchanges/baozi/fetchMarkets.d.ts +0 -5
  63. package/dist/exchanges/baozi/fetchMarkets.js +0 -160
  64. package/dist/exchanges/baozi/fetchOHLCV.d.ts +0 -6
  65. package/dist/exchanges/baozi/fetchOHLCV.js +0 -10
  66. package/dist/exchanges/baozi/fetchOrderBook.d.ts +0 -12
  67. package/dist/exchanges/baozi/fetchOrderBook.js +0 -36
  68. package/dist/exchanges/baozi/fetchTrades.d.ts +0 -6
  69. package/dist/exchanges/baozi/fetchTrades.js +0 -10
  70. package/dist/exchanges/kalshi/fetchEvents.d.ts +0 -5
  71. package/dist/exchanges/kalshi/fetchEvents.js +0 -196
  72. package/dist/exchanges/kalshi/fetchMarkets.d.ts +0 -6
  73. package/dist/exchanges/kalshi/fetchMarkets.js +0 -247
  74. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +0 -3
  75. package/dist/exchanges/kalshi/fetchOHLCV.js +0 -97
  76. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -2
  77. package/dist/exchanges/kalshi/fetchOrderBook.js +0 -60
  78. package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -3
  79. package/dist/exchanges/kalshi/fetchTrades.js +0 -33
  80. package/dist/exchanges/limitless/fetchEvents.d.ts +0 -4
  81. package/dist/exchanges/limitless/fetchEvents.js +0 -173
  82. package/dist/exchanges/limitless/fetchMarkets.d.ts +0 -3
  83. package/dist/exchanges/limitless/fetchMarkets.js +0 -152
  84. package/dist/exchanges/limitless/fetchOHLCV.d.ts +0 -7
  85. package/dist/exchanges/limitless/fetchOHLCV.js +0 -49
  86. package/dist/exchanges/limitless/fetchOrderBook.d.ts +0 -6
  87. package/dist/exchanges/limitless/fetchOrderBook.js +0 -41
  88. package/dist/exchanges/limitless/fetchTrades.d.ts +0 -8
  89. package/dist/exchanges/limitless/fetchTrades.js +0 -27
  90. package/dist/exchanges/myriad/fetchEvents.d.ts +0 -4
  91. package/dist/exchanges/myriad/fetchEvents.js +0 -48
  92. package/dist/exchanges/myriad/fetchMarkets.d.ts +0 -4
  93. package/dist/exchanges/myriad/fetchMarkets.js +0 -102
  94. package/dist/exchanges/myriad/fetchOHLCV.d.ts +0 -3
  95. package/dist/exchanges/myriad/fetchOHLCV.js +0 -83
  96. package/dist/exchanges/myriad/fetchOrderBook.d.ts +0 -2
  97. package/dist/exchanges/myriad/fetchOrderBook.js +0 -39
  98. package/dist/exchanges/polymarket/fetchEvents.d.ts +0 -4
  99. package/dist/exchanges/polymarket/fetchEvents.js +0 -135
  100. package/dist/exchanges/polymarket/fetchMarkets.d.ts +0 -4
  101. package/dist/exchanges/polymarket/fetchMarkets.js +0 -214
  102. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +0 -7
  103. package/dist/exchanges/polymarket/fetchOHLCV.js +0 -98
  104. package/dist/exchanges/polymarket/fetchOrderBook.d.ts +0 -6
  105. package/dist/exchanges/polymarket/fetchOrderBook.js +0 -33
  106. package/dist/exchanges/polymarket/fetchTrades.d.ts +0 -9
  107. package/dist/exchanges/polymarket/fetchTrades.js +0 -43
  108. package/dist/exchanges/probable/fetchEvents.d.ts +0 -6
  109. package/dist/exchanges/probable/fetchEvents.js +0 -151
  110. package/dist/exchanges/probable/fetchMarkets.d.ts +0 -4
  111. package/dist/exchanges/probable/fetchMarkets.js +0 -239
  112. package/dist/exchanges/probable/fetchTrades.d.ts +0 -10
  113. package/dist/exchanges/probable/fetchTrades.js +0 -40
@@ -36,6 +36,8 @@ export declare class KalshiExchange extends PredictionMarketExchange {
36
36
  private auth?;
37
37
  private wsConfig?;
38
38
  private config;
39
+ private readonly fetcher;
40
+ private readonly normalizer;
39
41
  constructor(options?: ExchangeCredentials | KalshiExchangeOptions);
40
42
  get name(): string;
41
43
  protected sign(method: string, path: string, _params: Record<string, any>): Record<string, string>;
@@ -47,18 +49,16 @@ export declare class KalshiExchange extends PredictionMarketExchange {
47
49
  fetchOrderBook(id: string): Promise<OrderBook>;
48
50
  fetchTrades(id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
49
51
  fetchBalance(): Promise<Balance[]>;
52
+ fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
53
+ fetchPositions(): Promise<Position[]>;
54
+ fetchClosedOrders(params?: OrderHistoryParams): Promise<Order[]>;
55
+ fetchAllOrders(params?: OrderHistoryParams): Promise<Order[]>;
50
56
  buildOrder(params: CreateOrderParams): Promise<BuiltOrder>;
51
57
  submitOrder(built: BuiltOrder): Promise<Order>;
52
58
  createOrder(params: CreateOrderParams): Promise<Order>;
53
59
  cancelOrder(orderId: string): Promise<Order>;
54
60
  fetchOrder(orderId: string): Promise<Order>;
55
61
  fetchOpenOrders(marketId?: string): Promise<Order[]>;
56
- fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
57
- fetchClosedOrders(params?: OrderHistoryParams): Promise<Order[]>;
58
- fetchAllOrders(params?: OrderHistoryParams): Promise<Order[]>;
59
- fetchPositions(): Promise<Position[]>;
60
- private mapKalshiOrder;
61
- private mapKalshiOrderStatus;
62
62
  private ws?;
63
63
  watchOrderBook(id: string, limit?: number): Promise<OrderBook>;
64
64
  watchTrades(id: string, address?: string, since?: number, limit?: number): Promise<Trade[]>;
@@ -2,9 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KalshiExchange = void 0;
4
4
  const BaseExchange_1 = require("../../BaseExchange");
5
- const fetchMarkets_1 = require("./fetchMarkets");
6
- const fetchEvents_1 = require("./fetchEvents");
7
- const fetchOHLCV_1 = require("./fetchOHLCV");
8
5
  const auth_1 = require("./auth");
9
6
  const validation_1 = require("../../utils/validation");
10
7
  const websocket_1 = require("./websocket");
@@ -13,7 +10,8 @@ const errors_2 = require("../../errors");
13
10
  const openapi_1 = require("../../utils/openapi");
14
11
  const api_1 = require("./api");
15
12
  const config_1 = require("./config");
16
- const price_1 = require("./price");
13
+ const fetcher_1 = require("./fetcher");
14
+ const normalizer_1 = require("./normalizer");
17
15
  class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
18
16
  has = {
19
17
  fetchMarkets: true,
@@ -40,19 +38,18 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
40
38
  auth;
41
39
  wsConfig;
42
40
  config;
41
+ fetcher;
42
+ normalizer;
43
43
  constructor(options) {
44
- // Support both old signature (credentials only) and new signature (options object)
45
44
  let credentials;
46
45
  let wsConfig;
47
46
  let demoMode = false;
48
47
  if (options && "credentials" in options) {
49
- // New signature: KalshiExchangeOptions / KalshiInternalOptions
50
48
  credentials = options.credentials;
51
49
  wsConfig = options.websocket;
52
50
  demoMode = options.demoMode || false;
53
51
  }
54
52
  else {
55
- // Old signature: ExchangeCredentials directly
56
53
  credentials = options;
57
54
  }
58
55
  super(credentials);
@@ -64,6 +61,13 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
64
61
  }
65
62
  const descriptor = (0, openapi_1.parseOpenApiSpec)(api_1.kalshiApiSpec, this.config.apiUrl + config_1.KALSHI_PATHS.TRADE_API);
66
63
  this.defineImplicitApi(descriptor);
64
+ const ctx = {
65
+ http: this.http,
66
+ callApi: this.callApi.bind(this),
67
+ getHeaders: () => ({}),
68
+ };
69
+ this.fetcher = new fetcher_1.KalshiFetcher(ctx);
70
+ this.normalizer = new normalizer_1.KalshiNormalizer();
67
71
  }
68
72
  get name() {
69
73
  return "Kalshi";
@@ -73,16 +77,11 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
73
77
  // ----------------------------------------------------------------------------
74
78
  sign(method, path, _params) {
75
79
  const auth = this.ensureAuth();
76
- // The implicit API passes just the spec path (e.g. /portfolio/balance),
77
- // but Kalshi's signature requires the full path including /trade-api/v2.
78
80
  return auth.getHeaders(method, "/trade-api/v2" + path);
79
81
  }
80
82
  mapImplicitApiError(error) {
81
83
  throw errors_1.kalshiErrorMapper.mapError(error);
82
84
  }
83
- // ----------------------------------------------------------------------------
84
- // Helpers
85
- // ----------------------------------------------------------------------------
86
85
  ensureAuth() {
87
86
  if (!this.auth) {
88
87
  throw new errors_2.AuthenticationError("Trading operations require authentication. " +
@@ -91,86 +90,128 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
91
90
  return this.auth;
92
91
  }
93
92
  // ----------------------------------------------------------------------------
94
- // Market Data Methods - Implementation for CCXT-style API
93
+ // Market Data (fetcher -> normalizer)
95
94
  // ----------------------------------------------------------------------------
96
95
  async fetchMarketsImpl(params) {
97
- return (0, fetchMarkets_1.fetchMarkets)(params, this.callApi.bind(this));
96
+ const rawEvents = await this.fetcher.fetchRawMarkets(params);
97
+ const allMarkets = [];
98
+ for (const event of rawEvents) {
99
+ const markets = this.normalizer.normalizeMarketsFromEvent(event);
100
+ allMarkets.push(...markets);
101
+ }
102
+ // Query-based search (client-side filtering)
103
+ if (params?.query) {
104
+ const lowerQuery = params.query.toLowerCase();
105
+ const searchIn = params?.searchIn || 'title';
106
+ const filtered = allMarkets.filter((market) => {
107
+ const titleMatch = (market.title || '').toLowerCase().includes(lowerQuery);
108
+ const descMatch = (market.description || '').toLowerCase().includes(lowerQuery);
109
+ if (searchIn === 'title')
110
+ return titleMatch;
111
+ if (searchIn === 'description')
112
+ return descMatch;
113
+ return titleMatch || descMatch;
114
+ });
115
+ return filtered.slice(0, params?.limit || 250000);
116
+ }
117
+ // Client-side sort
118
+ if (params?.sort === 'volume') {
119
+ allMarkets.sort((a, b) => b.volume24h - a.volume24h);
120
+ }
121
+ else if (params?.sort === 'liquidity') {
122
+ allMarkets.sort((a, b) => b.liquidity - a.liquidity);
123
+ }
124
+ const offset = params?.offset || 0;
125
+ const limit = params?.limit || 250000;
126
+ return allMarkets.slice(offset, offset + limit);
98
127
  }
99
128
  async fetchEventsImpl(params) {
100
- return (0, fetchEvents_1.fetchEvents)(params, this.callApi.bind(this));
129
+ const rawEvents = await this.fetcher.fetchRawEvents(params);
130
+ const limit = params?.limit || 10000;
131
+ const query = (params?.query || '').toLowerCase();
132
+ const filtered = query
133
+ ? rawEvents.filter((event) => (event.title || '').toLowerCase().includes(query))
134
+ : rawEvents;
135
+ const sort = params?.sort || 'volume';
136
+ const sorted = (0, normalizer_1.sortRawEvents)(filtered, sort);
137
+ return sorted
138
+ .map((raw) => this.normalizer.normalizeEvent(raw))
139
+ .filter((e) => e !== null)
140
+ .slice(0, limit);
101
141
  }
102
142
  async fetchOHLCV(id, params) {
103
- return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.callApi.bind(this));
143
+ const rawCandles = await this.fetcher.fetchRawOHLCV(id, params);
144
+ return this.normalizer.normalizeOHLCV(rawCandles, params);
104
145
  }
105
146
  async fetchOrderBook(id) {
106
147
  (0, validation_1.validateIdFormat)(id, "OrderBook");
107
- const isNoOutcome = id.endsWith("-NO");
108
- const ticker = id.replace(/-NO$/, "");
109
- const data = (await this.callApi("GetMarketOrderbook", { ticker }))
110
- .orderbook_fp;
111
- let bids;
112
- let asks;
113
- if (isNoOutcome) {
114
- bids = (data.no_dollars || []).map((level) => ({
115
- price: parseFloat(level[0]),
116
- size: parseFloat(level[1]),
117
- }));
118
- asks = (data.yes_dollars || []).map((level) => ({
119
- price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
120
- size: parseFloat(level[1]),
121
- }));
122
- }
123
- else {
124
- bids = (data.yes_dollars || []).map((level) => ({
125
- price: parseFloat(level[0]),
126
- size: parseFloat(level[1]),
127
- }));
128
- asks = (data.no_dollars || []).map((level) => ({
129
- price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
130
- size: parseFloat(level[1]),
131
- }));
132
- }
133
- bids.sort((a, b) => b.price - a.price);
134
- asks.sort((a, b) => a.price - b.price);
135
- return { bids, asks, timestamp: Date.now() };
148
+ const raw = await this.fetcher.fetchRawOrderBook(id);
149
+ return this.normalizer.normalizeOrderBook(raw, id);
136
150
  }
137
151
  async fetchTrades(id, params) {
138
152
  if ("resolution" in params && params.resolution !== undefined) {
139
153
  console.warn('[pmxt] Warning: The "resolution" parameter is deprecated for fetchTrades() and will be ignored. ' +
140
154
  "It will be removed in v3.0.0. Please remove it from your code.");
141
155
  }
142
- const ticker = id.replace(/-NO$/, "");
143
- const data = await this.callApi("GetTrades", {
144
- ticker,
145
- limit: params.limit || 100,
146
- });
147
- const trades = data.trades || [];
148
- return trades.map((t) => ({
149
- id: t.trade_id,
150
- timestamp: new Date(t.created_time).getTime(),
151
- price: (0, price_1.fromKalshiCents)(t.yes_price),
152
- amount: t.count,
153
- side: t.taker_side === "yes" ? "buy" : "sell",
154
- }));
156
+ const rawTrades = await this.fetcher.fetchRawTrades(id, params);
157
+ return rawTrades.map((raw, i) => this.normalizer.normalizeTrade(raw, i));
155
158
  }
156
159
  // ----------------------------------------------------------------------------
157
- // User Data Methods
160
+ // User Data (fetcher -> normalizer)
158
161
  // ----------------------------------------------------------------------------
159
162
  async fetchBalance() {
160
- const data = await this.callApi("GetBalance");
161
- const available = data.balance / 100;
162
- const total = data.portfolio_value / 100;
163
- return [
164
- {
165
- currency: "USD",
166
- total,
167
- available,
168
- locked: total - available,
169
- },
170
- ];
163
+ const raw = await this.fetcher.fetchRawBalance();
164
+ return this.normalizer.normalizeBalance(raw);
165
+ }
166
+ async fetchMyTrades(params) {
167
+ const rawFills = await this.fetcher.fetchRawMyTrades(params || {});
168
+ return rawFills.map((raw, i) => this.normalizer.normalizeUserTrade(raw, i));
169
+ }
170
+ async fetchPositions() {
171
+ const rawPositions = await this.fetcher.fetchRawPositions();
172
+ return rawPositions.map((raw) => this.normalizer.normalizePosition(raw));
173
+ }
174
+ async fetchClosedOrders(params) {
175
+ const queryParams = {};
176
+ if (params?.marketId)
177
+ queryParams.ticker = params.marketId;
178
+ if (params?.until)
179
+ queryParams.max_ts = Math.floor(params.until.getTime() / 1000);
180
+ if (params?.limit)
181
+ queryParams.limit = params.limit;
182
+ if (params?.cursor)
183
+ queryParams.cursor = params.cursor;
184
+ const rawOrders = await this.fetcher.fetchRawHistoricalOrders(queryParams);
185
+ return rawOrders.map((o) => this.normalizer.normalizeOrder(o));
186
+ }
187
+ async fetchAllOrders(params) {
188
+ const queryParams = {};
189
+ if (params?.marketId)
190
+ queryParams.ticker = params.marketId;
191
+ if (params?.since)
192
+ queryParams.min_ts = Math.floor(params.since.getTime() / 1000);
193
+ if (params?.until)
194
+ queryParams.max_ts = Math.floor(params.until.getTime() / 1000);
195
+ if (params?.limit)
196
+ queryParams.limit = params.limit;
197
+ const historicalParams = { ...queryParams };
198
+ delete historicalParams.min_ts;
199
+ const [liveOrders, historicalOrders] = await Promise.all([
200
+ this.fetcher.fetchRawOrders(queryParams),
201
+ this.fetcher.fetchRawHistoricalOrders(historicalParams),
202
+ ]);
203
+ const seen = new Set();
204
+ const all = [];
205
+ for (const o of [...liveOrders, ...historicalOrders]) {
206
+ if (!seen.has(o.order_id)) {
207
+ seen.add(o.order_id);
208
+ all.push(this.normalizer.normalizeOrder(o));
209
+ }
210
+ }
211
+ return all.sort((a, b) => b.timestamp - a.timestamp);
171
212
  }
172
213
  // ----------------------------------------------------------------------------
173
- // Trading Methods
214
+ // Trading
174
215
  // ----------------------------------------------------------------------------
175
216
  async buildOrder(params) {
176
217
  const isYesSide = params.side === "buy";
@@ -191,15 +232,11 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
191
232
  body.no_price = priceInCents;
192
233
  }
193
234
  }
194
- return {
195
- exchange: this.name,
196
- params,
197
- raw: body,
198
- };
235
+ return { exchange: this.name, params, raw: body };
199
236
  }
200
237
  async submitOrder(built) {
201
238
  const data = await this.callApi("CreateOrder", built.raw);
202
- return this.mapKalshiOrder(data.order);
239
+ return this.normalizer.normalizeOrder(data.order);
203
240
  }
204
241
  async createOrder(params) {
205
242
  const built = await this.buildOrder(params);
@@ -223,160 +260,40 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
223
260
  }
224
261
  async fetchOrder(orderId) {
225
262
  const data = await this.callApi("GetOrder", { order_id: orderId });
226
- return this.mapKalshiOrder(data.order);
263
+ return this.normalizer.normalizeOrder(data.order);
227
264
  }
228
265
  async fetchOpenOrders(marketId) {
229
266
  const queryParams = { status: "resting" };
230
- if (marketId) {
267
+ if (marketId)
231
268
  queryParams.ticker = marketId;
232
- }
233
- const data = await this.callApi("GetOrders", queryParams);
234
- const orders = data.orders || [];
235
- return orders.map((order) => this.mapKalshiOrder(order));
236
- }
237
- async fetchMyTrades(params) {
238
- const queryParams = {};
239
- if (params?.outcomeId || params?.marketId) {
240
- queryParams.ticker = (params.outcomeId || params.marketId).replace(/-NO$/, "");
241
- }
242
- if (params?.since)
243
- queryParams.min_ts = Math.floor(params.since.getTime() / 1000);
244
- if (params?.until)
245
- queryParams.max_ts = Math.floor(params.until.getTime() / 1000);
246
- if (params?.limit)
247
- queryParams.limit = params.limit;
248
- if (params?.cursor)
249
- queryParams.cursor = params.cursor;
250
- const data = await this.callApi("GetFills", queryParams);
251
- return (data.fills || []).map((f) => ({
252
- id: f.fill_id,
253
- timestamp: new Date(f.created_time).getTime(),
254
- price: (0, price_1.fromKalshiCents)(f.yes_price),
255
- amount: f.count,
256
- side: f.side === "yes" ? "buy" : "sell",
257
- orderId: f.order_id,
258
- }));
259
- }
260
- async fetchClosedOrders(params) {
261
- const queryParams = {};
262
- if (params?.marketId)
263
- queryParams.ticker = params.marketId;
264
- if (params?.until)
265
- queryParams.max_ts = Math.floor(params.until.getTime() / 1000);
266
- if (params?.limit)
267
- queryParams.limit = params.limit;
268
- if (params?.cursor)
269
- queryParams.cursor = params.cursor;
270
- const data = await this.callApi("GetHistoricalOrders", queryParams);
271
- return (data.orders || []).map((o) => this.mapKalshiOrder(o));
272
- }
273
- async fetchAllOrders(params) {
274
- const queryParams = {};
275
- if (params?.marketId)
276
- queryParams.ticker = params.marketId;
277
- if (params?.since)
278
- queryParams.min_ts = Math.floor(params.since.getTime() / 1000);
279
- if (params?.until)
280
- queryParams.max_ts = Math.floor(params.until.getTime() / 1000);
281
- if (params?.limit)
282
- queryParams.limit = params.limit;
283
- const historicalParams = { ...queryParams };
284
- delete historicalParams.min_ts; // GetHistoricalOrders only supports max_ts
285
- const [liveData, historicalData] = await Promise.all([
286
- this.callApi("GetOrders", queryParams),
287
- this.callApi("GetHistoricalOrders", historicalParams),
288
- ]);
289
- const seen = new Set();
290
- const all = [];
291
- for (const o of [
292
- ...(liveData.orders || []),
293
- ...(historicalData.orders || []),
294
- ]) {
295
- if (!seen.has(o.order_id)) {
296
- seen.add(o.order_id);
297
- all.push(this.mapKalshiOrder(o));
298
- }
299
- }
300
- return all.sort((a, b) => b.timestamp - a.timestamp);
301
- }
302
- async fetchPositions() {
303
- const data = await this.callApi("GetPositions");
304
- const positions = data.market_positions || [];
305
- return positions.map((pos) => {
306
- const absPosition = Math.abs(pos.position);
307
- const entryPrice = absPosition > 0 ? pos.total_cost / absPosition / 100 : 0;
308
- return {
309
- marketId: pos.ticker,
310
- outcomeId: pos.ticker,
311
- outcomeLabel: pos.ticker,
312
- size: pos.position,
313
- entryPrice,
314
- currentPrice: pos.market_price ? pos.market_price / 100 : entryPrice,
315
- unrealizedPnL: pos.market_exposure ? pos.market_exposure / 100 : 0,
316
- realizedPnL: pos.realized_pnl ? pos.realized_pnl / 100 : 0,
317
- };
318
- });
319
- }
320
- // Helper to map a raw Kalshi order object to a unified Order
321
- mapKalshiOrder(order) {
322
- return {
323
- id: order.order_id,
324
- marketId: order.ticker,
325
- outcomeId: order.ticker,
326
- side: order.side === "yes" ? "buy" : "sell",
327
- type: order.type === "limit" ? "limit" : "market",
328
- price: order.yes_price ? order.yes_price / 100 : undefined,
329
- amount: order.count,
330
- status: this.mapKalshiOrderStatus(order.status),
331
- filled: order.count - (order.remaining_count || 0),
332
- remaining: order.remaining_count || 0,
333
- timestamp: new Date(order.created_time).getTime(),
334
- };
335
- }
336
- // Helper to map Kalshi order status to unified status
337
- mapKalshiOrderStatus(status) {
338
- switch ((status ?? "").toLowerCase()) {
339
- case "resting":
340
- return "open";
341
- case "canceled":
342
- case "cancelled":
343
- return "cancelled";
344
- case "executed":
345
- case "filled":
346
- return "filled";
347
- default:
348
- return "open";
349
- }
269
+ const rawOrders = await this.fetcher.fetchRawOrders(queryParams);
270
+ return rawOrders.map((o) => this.normalizer.normalizeOrder(o));
350
271
  }
351
272
  // ----------------------------------------------------------------------------
352
- // WebSocket Methods
273
+ // WebSocket
353
274
  // ----------------------------------------------------------------------------
354
275
  ws;
355
276
  async watchOrderBook(id, limit) {
356
277
  const auth = this.ensureAuth();
357
278
  if (!this.ws) {
358
- // Merge wsConfig with wsUrl from config
359
279
  const wsConfigWithUrl = {
360
280
  ...this.wsConfig,
361
281
  wsUrl: this.wsConfig?.wsUrl || this.config.wsUrl,
362
282
  };
363
283
  this.ws = new websocket_1.KalshiWebSocket(auth, wsConfigWithUrl);
364
284
  }
365
- // Normalize ticker (strip -NO suffix if present)
366
285
  const marketTicker = id.replace(/-NO$/, "");
367
286
  return this.ws.watchOrderBook(marketTicker);
368
287
  }
369
288
  async watchTrades(id, address, since, limit) {
370
289
  const auth = this.ensureAuth();
371
290
  if (!this.ws) {
372
- // Merge wsConfig with wsUrl from config
373
291
  const wsConfigWithUrl = {
374
292
  ...this.wsConfig,
375
293
  wsUrl: this.wsConfig?.wsUrl || this.config.wsUrl,
376
294
  };
377
295
  this.ws = new websocket_1.KalshiWebSocket(auth, wsConfigWithUrl);
378
296
  }
379
- // Normalize ticker (strip -NO suffix if present)
380
297
  const marketTicker = id.replace(/-NO$/, "");
381
298
  return this.ws.watchTrades(marketTicker);
382
299
  }
@@ -0,0 +1,25 @@
1
+ import { OHLCVParams } from '../../BaseExchange';
2
+ import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Position, Balance } from '../../types';
3
+ import { IExchangeNormalizer } from '../interfaces';
4
+ import { KalshiRawEvent, KalshiRawMarket, KalshiRawCandlestick, KalshiRawTrade, KalshiRawFill, KalshiRawOrder, KalshiRawPosition, KalshiRawOrderBookFp } from './fetcher';
5
+ export declare class KalshiNormalizer implements IExchangeNormalizer<KalshiRawEvent, KalshiRawEvent> {
6
+ normalizeMarket(raw: KalshiRawEvent): UnifiedMarket | null;
7
+ normalizeMarketsFromEvent(rawEvent: KalshiRawEvent): UnifiedMarket[];
8
+ normalizeRawMarket(event: KalshiRawEvent, market: KalshiRawMarket): UnifiedMarket | null;
9
+ normalizeEvent(raw: KalshiRawEvent): UnifiedEvent | null;
10
+ normalizeOHLCV(rawCandles: KalshiRawCandlestick[], params: OHLCVParams): PriceCandle[];
11
+ normalizeOrderBook(raw: {
12
+ orderbook_fp: KalshiRawOrderBookFp;
13
+ }, id: string): OrderBook;
14
+ normalizeTrade(raw: KalshiRawTrade, _index: number): Trade;
15
+ normalizeUserTrade(raw: KalshiRawFill, _index: number): UserTrade;
16
+ normalizeOrder(raw: KalshiRawOrder): import('../../types').Order;
17
+ normalizePosition(raw: KalshiRawPosition): Position;
18
+ normalizeBalance(raw: {
19
+ balance: number;
20
+ portfolio_value: number;
21
+ }): Balance[];
22
+ private mapOrderStatus;
23
+ private deriveEventDescription;
24
+ }
25
+ export declare function sortRawEvents(events: any[], sort: string): any[];