pmxtjs 0.1.0 → 0.1.1
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/BaseExchange.js +30 -0
- package/{src/exchanges/Kalshi.ts → dist/exchanges/Kalshi.js} +75 -106
- package/{src/exchanges/Polymarket.ts → dist/exchanges/Polymarket.js} +107 -144
- package/dist/index.js +20 -0
- package/dist/types.js +5 -0
- package/package.json +4 -1
- package/API_REFERENCE.md +0 -88
- package/coverage/clover.xml +0 -334
- package/coverage/coverage-final.json +0 -4
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -131
- package/coverage/lcov-report/pmxt/BaseExchange.ts.html +0 -256
- package/coverage/lcov-report/pmxt/exchanges/Kalshi.ts.html +0 -1132
- package/coverage/lcov-report/pmxt/exchanges/Polymarket.ts.html +0 -1456
- package/coverage/lcov-report/pmxt/exchanges/index.html +0 -131
- package/coverage/lcov-report/pmxt/index.html +0 -116
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/src/BaseExchange.ts.html +0 -256
- package/coverage/lcov-report/src/exchanges/Kalshi.ts.html +0 -1132
- package/coverage/lcov-report/src/exchanges/Polymarket.ts.html +0 -1456
- package/coverage/lcov-report/src/exchanges/index.html +0 -131
- package/coverage/lcov-report/src/index.html +0 -116
- package/coverage/lcov.info +0 -766
- package/examples/get_event_prices.ts +0 -37
- package/examples/historical_prices.ts +0 -117
- package/examples/orderbook.ts +0 -102
- package/examples/recent_trades.ts +0 -29
- package/examples/search_events.ts +0 -68
- package/examples/search_market.ts +0 -29
- package/jest.config.js +0 -11
- package/pmxt-0.1.0.tgz +0 -0
- package/src/BaseExchange.ts +0 -57
- package/src/index.ts +0 -5
- package/src/types.ts +0 -61
- package/test/exchanges/kalshi/ApiErrors.test.ts +0 -132
- package/test/exchanges/kalshi/EmptyResponse.test.ts +0 -44
- package/test/exchanges/kalshi/FetchAndNormalizeMarkets.test.ts +0 -56
- package/test/exchanges/kalshi/LiveApi.integration.test.ts +0 -40
- package/test/exchanges/kalshi/MarketHistory.test.ts +0 -185
- package/test/exchanges/kalshi/OrderBook.test.ts +0 -149
- package/test/exchanges/kalshi/SearchMarkets.test.ts +0 -174
- package/test/exchanges/kalshi/VolumeFallback.test.ts +0 -44
- package/test/exchanges/polymarket/DataValidation.test.ts +0 -271
- package/test/exchanges/polymarket/ErrorHandling.test.ts +0 -34
- package/test/exchanges/polymarket/FetchAndNormalizeMarkets.test.ts +0 -68
- package/test/exchanges/polymarket/GetMarketsBySlug.test.ts +0 -268
- package/test/exchanges/polymarket/LiveApi.integration.test.ts +0 -44
- package/test/exchanges/polymarket/MarketHistory.test.ts +0 -207
- package/test/exchanges/polymarket/OrderBook.test.ts +0 -167
- package/test/exchanges/polymarket/RequestParameters.test.ts +0 -39
- package/test/exchanges/polymarket/SearchMarkets.test.ts +0 -176
- package/test/exchanges/polymarket/TradeHistory.test.ts +0 -248
- package/tsconfig.json +0 -12
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PredictionMarketExchange = void 0;
|
|
4
|
+
// ----------------------------------------------------------------------------
|
|
5
|
+
// Base Exchange Class
|
|
6
|
+
// ----------------------------------------------------------------------------
|
|
7
|
+
class PredictionMarketExchange {
|
|
8
|
+
/**
|
|
9
|
+
* Fetch historical price data for a specific market or outcome.
|
|
10
|
+
* @param id - The market ID or specific outcome ID/Token ID depending on the exchange
|
|
11
|
+
*/
|
|
12
|
+
async getMarketHistory(id, params) {
|
|
13
|
+
throw new Error("Method getMarketHistory not implemented.");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetch the current order book (bids/asks) for a specific outcome.
|
|
17
|
+
* Essential for calculating localized spread and depth.
|
|
18
|
+
*/
|
|
19
|
+
async getOrderBook(id) {
|
|
20
|
+
throw new Error("Method getOrderBook not implemented.");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Fetch raw trade history.
|
|
24
|
+
* Useful for generating synthetic OHLCV candles if the exchange doesn't provide them natively.
|
|
25
|
+
*/
|
|
26
|
+
async getTradeHistory(id, params) {
|
|
27
|
+
throw new Error("Method getTradeHistory not implemented.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.PredictionMarketExchange = PredictionMarketExchange;
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.KalshiExchange = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const BaseExchange_1 = require("../BaseExchange");
|
|
9
|
+
class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.baseUrl = "https://api.elections.kalshi.com/trade-api/v2/events";
|
|
13
|
+
}
|
|
14
|
+
get name() {
|
|
7
15
|
return "Kalshi";
|
|
8
16
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
async fetchMarkets(params?: MarketFilterParams): Promise<UnifiedMarket[]> {
|
|
17
|
+
async fetchMarkets(params) {
|
|
12
18
|
const limit = params?.limit || 50;
|
|
13
|
-
|
|
14
19
|
try {
|
|
15
20
|
// Fetch active events with nested markets
|
|
16
21
|
// For small limits, we can optimize by fetching fewer pages
|
|
17
22
|
const allEvents = await this.fetchActiveEvents(limit);
|
|
18
|
-
|
|
19
23
|
// Extract ALL markets from all events
|
|
20
|
-
const allMarkets
|
|
21
|
-
|
|
24
|
+
const allMarkets = [];
|
|
22
25
|
for (const event of allEvents) {
|
|
23
26
|
const markets = event.markets || [];
|
|
24
27
|
for (const market of markets) {
|
|
@@ -28,60 +31,51 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
|
-
|
|
32
34
|
console.log(`Extracted ${allMarkets.length} markets from ${allEvents.length} events.`);
|
|
33
|
-
|
|
34
35
|
// Sort by 24h volume
|
|
35
36
|
if (params?.sort === 'volume') {
|
|
36
37
|
allMarkets.sort((a, b) => b.volume24h - a.volume24h);
|
|
37
|
-
}
|
|
38
|
+
}
|
|
39
|
+
else if (params?.sort === 'liquidity') {
|
|
38
40
|
allMarkets.sort((a, b) => b.liquidity - a.liquidity);
|
|
39
41
|
}
|
|
40
|
-
|
|
41
42
|
return allMarkets.slice(0, limit);
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
44
45
|
console.error("Error fetching Kalshi data:", error);
|
|
45
46
|
return [];
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let allEvents: any[] = [];
|
|
49
|
+
async fetchActiveEvents(targetMarketCount) {
|
|
50
|
+
let allEvents = [];
|
|
51
51
|
let totalMarketCount = 0;
|
|
52
52
|
let cursor = null;
|
|
53
53
|
let page = 0;
|
|
54
|
-
|
|
55
54
|
// Note: Kalshi API uses cursor-based pagination which requires sequential fetching.
|
|
56
55
|
// We cannot parallelize requests for a single list because we need the cursor from page N to fetch page N+1.
|
|
57
56
|
// To optimize, we use the maximum allowed limit (200) and fetch until exhaustion.
|
|
58
|
-
|
|
59
57
|
const MAX_PAGES = 1000; // Safety cap against infinite loops
|
|
60
58
|
const BATCH_SIZE = 200; // Max limit per Kalshi API docs
|
|
61
|
-
|
|
62
59
|
do {
|
|
63
60
|
try {
|
|
64
61
|
// console.log(`Fetching Kalshi page ${page + 1}...`);
|
|
65
|
-
const queryParams
|
|
62
|
+
const queryParams = {
|
|
66
63
|
limit: BATCH_SIZE,
|
|
67
64
|
with_nested_markets: true,
|
|
68
65
|
status: 'open' // Filter to open markets to improve relevance and speed
|
|
69
66
|
};
|
|
70
|
-
if (cursor)
|
|
71
|
-
|
|
72
|
-
const response = await
|
|
67
|
+
if (cursor)
|
|
68
|
+
queryParams.cursor = cursor;
|
|
69
|
+
const response = await axios_1.default.get(this.baseUrl, { params: queryParams });
|
|
73
70
|
const events = response.data.events || [];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
if (events.length === 0)
|
|
72
|
+
break;
|
|
77
73
|
allEvents = allEvents.concat(events);
|
|
78
|
-
|
|
79
74
|
// Count markets in this batch for early termination
|
|
80
75
|
if (targetMarketCount) {
|
|
81
76
|
for (const event of events) {
|
|
82
77
|
totalMarketCount += (event.markets || []).length;
|
|
83
78
|
}
|
|
84
|
-
|
|
85
79
|
// Early termination: if we have enough markets, stop fetching
|
|
86
80
|
// Add a buffer (2x) to ensure we have enough after filtering/sorting
|
|
87
81
|
if (totalMarketCount >= targetMarketCount * 2) {
|
|
@@ -89,51 +83,46 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
89
83
|
break;
|
|
90
84
|
}
|
|
91
85
|
}
|
|
92
|
-
|
|
93
86
|
cursor = response.data.cursor;
|
|
94
87
|
page++;
|
|
95
|
-
|
|
96
88
|
// Log progress every few pages to avoid spam
|
|
97
89
|
if (page % 5 === 0) {
|
|
98
90
|
console.log(`Fetched ${page} pages (${allEvents.length} events) from Kalshi...`);
|
|
99
91
|
}
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
102
94
|
console.error(`Error fetching Kalshi page ${page}:`, e);
|
|
103
95
|
break;
|
|
104
96
|
}
|
|
105
97
|
} while (cursor && page < MAX_PAGES);
|
|
106
|
-
|
|
107
98
|
console.log(`Finished fetching Kalshi: ${allEvents.length} total events across ${page} pages.`);
|
|
108
99
|
return allEvents;
|
|
109
100
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
101
|
+
mapMarketToUnified(event, market) {
|
|
102
|
+
if (!market)
|
|
103
|
+
return null;
|
|
114
104
|
// Calculate price
|
|
115
105
|
let price = 0.5;
|
|
116
106
|
if (market.last_price) {
|
|
117
107
|
price = market.last_price / 100;
|
|
118
|
-
}
|
|
108
|
+
}
|
|
109
|
+
else if (market.yes_ask && market.yes_bid) {
|
|
119
110
|
price = (market.yes_ask + market.yes_bid) / 200;
|
|
120
|
-
}
|
|
111
|
+
}
|
|
112
|
+
else if (market.yes_ask) {
|
|
121
113
|
price = market.yes_ask / 100;
|
|
122
114
|
}
|
|
123
|
-
|
|
124
115
|
// Extract candidate name
|
|
125
|
-
let candidateName
|
|
116
|
+
let candidateName = null;
|
|
126
117
|
if (market.subtitle || market.yes_sub_title) {
|
|
127
118
|
candidateName = market.subtitle || market.yes_sub_title;
|
|
128
119
|
}
|
|
129
|
-
|
|
130
120
|
// Calculate 24h change
|
|
131
121
|
let priceChange = 0;
|
|
132
122
|
if (market.previous_price_dollars !== undefined && market.last_price_dollars !== undefined) {
|
|
133
123
|
priceChange = market.last_price_dollars - market.previous_price_dollars;
|
|
134
124
|
}
|
|
135
|
-
|
|
136
|
-
const outcomes: MarketOutcome[] = [
|
|
125
|
+
const outcomes = [
|
|
137
126
|
{
|
|
138
127
|
id: 'yes',
|
|
139
128
|
label: candidateName || 'Yes',
|
|
@@ -147,7 +136,6 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
147
136
|
priceChange24h: -priceChange // Inverse change for No? simplified assumption
|
|
148
137
|
}
|
|
149
138
|
];
|
|
150
|
-
|
|
151
139
|
return {
|
|
152
140
|
id: market.ticker,
|
|
153
141
|
title: event.title,
|
|
@@ -163,56 +151,50 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
163
151
|
tags: event.tags || []
|
|
164
152
|
};
|
|
165
153
|
}
|
|
166
|
-
|
|
167
|
-
async searchMarkets(query: string, params?: MarketFilterParams): Promise<UnifiedMarket[]> {
|
|
154
|
+
async searchMarkets(query, params) {
|
|
168
155
|
// We must fetch ALL markets to search them locally since we don't have server-side search
|
|
169
156
|
const fetchLimit = 100000;
|
|
170
157
|
try {
|
|
171
158
|
const markets = await this.fetchMarkets({ ...params, limit: fetchLimit });
|
|
172
159
|
const lowerQuery = query.toLowerCase();
|
|
173
|
-
const filtered = markets.filter(market =>
|
|
174
|
-
market.
|
|
175
|
-
market.description.toLowerCase().includes(lowerQuery)
|
|
176
|
-
);
|
|
160
|
+
const filtered = markets.filter(market => market.title.toLowerCase().includes(lowerQuery) ||
|
|
161
|
+
market.description.toLowerCase().includes(lowerQuery));
|
|
177
162
|
const limit = params?.limit || 20;
|
|
178
163
|
return filtered.slice(0, limit);
|
|
179
|
-
}
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
180
166
|
console.error("Error searching Kalshi data:", error);
|
|
181
167
|
return [];
|
|
182
168
|
}
|
|
183
169
|
}
|
|
184
|
-
|
|
185
170
|
/**
|
|
186
171
|
* Fetch specific markets by their event ticker.
|
|
187
172
|
* Useful for looking up a specific event from a URL.
|
|
188
173
|
* @param eventTicker - The event ticker (e.g. "FED-25JAN" or "PRES-2024")
|
|
189
174
|
*/
|
|
190
|
-
async getMarketsBySlug(eventTicker
|
|
175
|
+
async getMarketsBySlug(eventTicker) {
|
|
191
176
|
try {
|
|
192
177
|
// Kalshi API expects uppercase tickers, but URLs use lowercase
|
|
193
178
|
const normalizedTicker = eventTicker.toUpperCase();
|
|
194
179
|
const url = `https://api.elections.kalshi.com/trade-api/v2/events/${normalizedTicker}`;
|
|
195
|
-
const response = await
|
|
180
|
+
const response = await axios_1.default.get(url, {
|
|
196
181
|
params: { with_nested_markets: true }
|
|
197
182
|
});
|
|
198
|
-
|
|
199
183
|
const event = response.data.event;
|
|
200
|
-
if (!event)
|
|
201
|
-
|
|
202
|
-
const unifiedMarkets
|
|
184
|
+
if (!event)
|
|
185
|
+
return [];
|
|
186
|
+
const unifiedMarkets = [];
|
|
203
187
|
const markets = event.markets || [];
|
|
204
|
-
|
|
205
188
|
for (const market of markets) {
|
|
206
189
|
const unifiedMarket = this.mapMarketToUnified(event, market);
|
|
207
190
|
if (unifiedMarket) {
|
|
208
191
|
unifiedMarkets.push(unifiedMarket);
|
|
209
192
|
}
|
|
210
193
|
}
|
|
211
|
-
|
|
212
194
|
return unifiedMarkets;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (axios_1.default.isAxiosError(error) && error.response) {
|
|
216
198
|
if (error.response.status === 404) {
|
|
217
199
|
throw new Error(`Kalshi event not found: "${eventTicker}". Check that the event ticker is correct.`);
|
|
218
200
|
}
|
|
@@ -223,9 +205,8 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
223
205
|
throw error;
|
|
224
206
|
}
|
|
225
207
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const mapping: Record<CandleInterval, number> = {
|
|
208
|
+
mapIntervalToKalshi(interval) {
|
|
209
|
+
const mapping = {
|
|
229
210
|
'1m': 1,
|
|
230
211
|
'5m': 1,
|
|
231
212
|
'15m': 1,
|
|
@@ -235,13 +216,11 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
235
216
|
};
|
|
236
217
|
return mapping[interval];
|
|
237
218
|
}
|
|
238
|
-
|
|
239
|
-
async getMarketHistory(id: string, params: HistoryFilterParams): Promise<PriceCandle[]> {
|
|
219
|
+
async getMarketHistory(id, params) {
|
|
240
220
|
try {
|
|
241
221
|
// Kalshi API expects uppercase tickers
|
|
242
222
|
const normalizedId = id.toUpperCase();
|
|
243
223
|
const interval = this.mapIntervalToKalshi(params.resolution);
|
|
244
|
-
|
|
245
224
|
// Heuristic for series_ticker
|
|
246
225
|
const parts = normalizedId.split('-');
|
|
247
226
|
if (parts.length < 2) {
|
|
@@ -249,13 +228,10 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
249
228
|
}
|
|
250
229
|
const seriesTicker = parts.slice(0, -1).join('-');
|
|
251
230
|
const url = `https://api.elections.kalshi.com/trade-api/v2/series/${seriesTicker}/markets/${normalizedId}/candlesticks`;
|
|
252
|
-
|
|
253
|
-
const queryParams: any = { period_interval: interval };
|
|
254
|
-
|
|
231
|
+
const queryParams = { period_interval: interval };
|
|
255
232
|
const now = Math.floor(Date.now() / 1000);
|
|
256
233
|
let startTs = now - (24 * 60 * 60);
|
|
257
234
|
let endTs = now;
|
|
258
|
-
|
|
259
235
|
if (params.start) {
|
|
260
236
|
startTs = Math.floor(params.start.getTime() / 1000);
|
|
261
237
|
}
|
|
@@ -265,14 +241,11 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
265
241
|
startTs = endTs - (24 * 60 * 60);
|
|
266
242
|
}
|
|
267
243
|
}
|
|
268
|
-
|
|
269
244
|
queryParams.start_ts = startTs;
|
|
270
245
|
queryParams.end_ts = endTs;
|
|
271
|
-
|
|
272
|
-
const response = await axios.get(url, { params: queryParams });
|
|
246
|
+
const response = await axios_1.default.get(url, { params: queryParams });
|
|
273
247
|
const candles = response.data.candlesticks || [];
|
|
274
|
-
|
|
275
|
-
const mappedCandles: PriceCandle[] = candles.map((c: any) => ({
|
|
248
|
+
const mappedCandles = candles.map((c) => ({
|
|
276
249
|
timestamp: c.end_period_ts * 1000,
|
|
277
250
|
open: (c.price.open || 0) / 100,
|
|
278
251
|
high: (c.price.high || 0) / 100,
|
|
@@ -280,13 +253,13 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
280
253
|
close: (c.price.close || 0) / 100,
|
|
281
254
|
volume: c.volume
|
|
282
255
|
}));
|
|
283
|
-
|
|
284
256
|
if (params.limit && mappedCandles.length > params.limit) {
|
|
285
257
|
return mappedCandles.slice(-params.limit);
|
|
286
258
|
}
|
|
287
259
|
return mappedCandles;
|
|
288
|
-
}
|
|
289
|
-
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (axios_1.default.isAxiosError(error) && error.response) {
|
|
290
263
|
const apiError = error.response.data?.error || error.response.data?.message || "Unknown API Error";
|
|
291
264
|
throw new Error(`Kalshi History API Error (${error.response.status}): ${apiError}. Used Ticker: ${id}`);
|
|
292
265
|
}
|
|
@@ -294,56 +267,52 @@ export class KalshiExchange extends PredictionMarketExchange {
|
|
|
294
267
|
throw error;
|
|
295
268
|
}
|
|
296
269
|
}
|
|
297
|
-
|
|
298
|
-
async getOrderBook(id: string): Promise<OrderBook> {
|
|
270
|
+
async getOrderBook(id) {
|
|
299
271
|
try {
|
|
300
272
|
const url = `https://api.elections.kalshi.com/trade-api/v2/markets/${id}/orderbook`;
|
|
301
|
-
const response = await
|
|
273
|
+
const response = await axios_1.default.get(url);
|
|
302
274
|
const data = response.data.orderbook;
|
|
303
|
-
|
|
304
275
|
// Structure: { yes: [[price, qty], ...], no: [[price, qty], ...] }
|
|
305
|
-
const bids = (data.yes || []).map((level
|
|
276
|
+
const bids = (data.yes || []).map((level) => ({
|
|
306
277
|
price: level[0] / 100,
|
|
307
278
|
size: level[1]
|
|
308
279
|
}));
|
|
309
|
-
|
|
310
|
-
const asks = (data.no || []).map((level: number[]) => ({
|
|
280
|
+
const asks = (data.no || []).map((level) => ({
|
|
311
281
|
price: (100 - level[0]) / 100,
|
|
312
282
|
size: level[1]
|
|
313
283
|
}));
|
|
314
|
-
|
|
315
284
|
// Sort bids desc, asks asc
|
|
316
|
-
bids.sort((a
|
|
317
|
-
asks.sort((a
|
|
318
|
-
|
|
285
|
+
bids.sort((a, b) => b.price - a.price);
|
|
286
|
+
asks.sort((a, b) => a.price - b.price);
|
|
319
287
|
return { bids, asks, timestamp: Date.now() };
|
|
320
|
-
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
321
290
|
console.error(`Error fetching Kalshi orderbook for ${id}:`, error);
|
|
322
291
|
return { bids: [], asks: [] };
|
|
323
292
|
}
|
|
324
293
|
}
|
|
325
|
-
|
|
326
|
-
async getTradeHistory(id: string, params: HistoryFilterParams): Promise<Trade[]> {
|
|
294
|
+
async getTradeHistory(id, params) {
|
|
327
295
|
try {
|
|
328
296
|
const url = `https://api.elections.kalshi.com/trade-api/v2/markets/trades`;
|
|
329
|
-
const response = await
|
|
297
|
+
const response = await axios_1.default.get(url, {
|
|
330
298
|
params: {
|
|
331
299
|
ticker: id,
|
|
332
300
|
limit: params.limit || 100
|
|
333
301
|
}
|
|
334
302
|
});
|
|
335
303
|
const trades = response.data.trades || [];
|
|
336
|
-
|
|
337
|
-
return trades.map((t: any) => ({
|
|
304
|
+
return trades.map((t) => ({
|
|
338
305
|
id: t.trade_id,
|
|
339
306
|
timestamp: new Date(t.created_time).getTime(),
|
|
340
307
|
price: t.yes_price / 100,
|
|
341
308
|
amount: t.count,
|
|
342
309
|
side: t.taker_side === 'yes' ? 'buy' : 'sell'
|
|
343
310
|
}));
|
|
344
|
-
}
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
345
313
|
console.error(`Error fetching Kalshi trades for ${id}:`, error);
|
|
346
314
|
return [];
|
|
347
315
|
}
|
|
348
316
|
}
|
|
349
317
|
}
|
|
318
|
+
exports.KalshiExchange = KalshiExchange;
|