pmxt-core 2.20.1 → 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 (111) 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/package.json +3 -3
  58. package/dist/exchanges/baozi/fetchEvents.d.ts +0 -8
  59. package/dist/exchanges/baozi/fetchEvents.js +0 -39
  60. package/dist/exchanges/baozi/fetchMarkets.d.ts +0 -5
  61. package/dist/exchanges/baozi/fetchMarkets.js +0 -160
  62. package/dist/exchanges/baozi/fetchOHLCV.d.ts +0 -6
  63. package/dist/exchanges/baozi/fetchOHLCV.js +0 -10
  64. package/dist/exchanges/baozi/fetchOrderBook.d.ts +0 -12
  65. package/dist/exchanges/baozi/fetchOrderBook.js +0 -36
  66. package/dist/exchanges/baozi/fetchTrades.d.ts +0 -6
  67. package/dist/exchanges/baozi/fetchTrades.js +0 -10
  68. package/dist/exchanges/kalshi/fetchEvents.d.ts +0 -5
  69. package/dist/exchanges/kalshi/fetchEvents.js +0 -196
  70. package/dist/exchanges/kalshi/fetchMarkets.d.ts +0 -6
  71. package/dist/exchanges/kalshi/fetchMarkets.js +0 -247
  72. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +0 -3
  73. package/dist/exchanges/kalshi/fetchOHLCV.js +0 -97
  74. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -2
  75. package/dist/exchanges/kalshi/fetchOrderBook.js +0 -60
  76. package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -3
  77. package/dist/exchanges/kalshi/fetchTrades.js +0 -33
  78. package/dist/exchanges/limitless/fetchEvents.d.ts +0 -4
  79. package/dist/exchanges/limitless/fetchEvents.js +0 -173
  80. package/dist/exchanges/limitless/fetchMarkets.d.ts +0 -3
  81. package/dist/exchanges/limitless/fetchMarkets.js +0 -152
  82. package/dist/exchanges/limitless/fetchOHLCV.d.ts +0 -7
  83. package/dist/exchanges/limitless/fetchOHLCV.js +0 -49
  84. package/dist/exchanges/limitless/fetchOrderBook.d.ts +0 -6
  85. package/dist/exchanges/limitless/fetchOrderBook.js +0 -41
  86. package/dist/exchanges/limitless/fetchTrades.d.ts +0 -8
  87. package/dist/exchanges/limitless/fetchTrades.js +0 -27
  88. package/dist/exchanges/myriad/fetchEvents.d.ts +0 -4
  89. package/dist/exchanges/myriad/fetchEvents.js +0 -48
  90. package/dist/exchanges/myriad/fetchMarkets.d.ts +0 -4
  91. package/dist/exchanges/myriad/fetchMarkets.js +0 -102
  92. package/dist/exchanges/myriad/fetchOHLCV.d.ts +0 -3
  93. package/dist/exchanges/myriad/fetchOHLCV.js +0 -83
  94. package/dist/exchanges/myriad/fetchOrderBook.d.ts +0 -2
  95. package/dist/exchanges/myriad/fetchOrderBook.js +0 -39
  96. package/dist/exchanges/polymarket/fetchEvents.d.ts +0 -4
  97. package/dist/exchanges/polymarket/fetchEvents.js +0 -135
  98. package/dist/exchanges/polymarket/fetchMarkets.d.ts +0 -4
  99. package/dist/exchanges/polymarket/fetchMarkets.js +0 -214
  100. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +0 -7
  101. package/dist/exchanges/polymarket/fetchOHLCV.js +0 -98
  102. package/dist/exchanges/polymarket/fetchOrderBook.d.ts +0 -6
  103. package/dist/exchanges/polymarket/fetchOrderBook.js +0 -33
  104. package/dist/exchanges/polymarket/fetchTrades.d.ts +0 -9
  105. package/dist/exchanges/polymarket/fetchTrades.js +0 -43
  106. package/dist/exchanges/probable/fetchEvents.d.ts +0 -6
  107. package/dist/exchanges/probable/fetchEvents.js +0 -151
  108. package/dist/exchanges/probable/fetchMarkets.d.ts +0 -4
  109. package/dist/exchanges/probable/fetchMarkets.js +0 -239
  110. package/dist/exchanges/probable/fetchTrades.d.ts +0 -10
  111. package/dist/exchanges/probable/fetchTrades.js +0 -40
@@ -1,247 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetCache = resetCache;
4
- exports.fetchMarkets = fetchMarkets;
5
- const utils_1 = require("./utils");
6
- const errors_1 = require("./errors");
7
- async function fetchActiveEvents(callApi, targetMarketCount, status = "open") {
8
- let allEvents = [];
9
- let totalMarketCount = 0;
10
- let cursor = null;
11
- let page = 0;
12
- // Note: Kalshi API uses cursor-based pagination which requires sequential fetching.
13
- // We cannot parallelize requests for a single list because we need the cursor from page N to fetch page N+1.
14
- // To optimize, we use the maximum allowed limit (200) and fetch until exhaustion.
15
- const MAX_PAGES = 1000; // Safety cap against infinite loops
16
- const BATCH_SIZE = 200; // Max limit per Kalshi API docs
17
- do {
18
- try {
19
- const queryParams = {
20
- limit: BATCH_SIZE,
21
- with_nested_markets: true,
22
- status: status, // Filter by status (default 'open')
23
- };
24
- if (cursor)
25
- queryParams.cursor = cursor;
26
- const data = await callApi("GetEvents", queryParams);
27
- const events = data.events || [];
28
- if (events.length === 0)
29
- break;
30
- allEvents = allEvents.concat(events);
31
- // Count markets in this batch for early termination
32
- if (targetMarketCount) {
33
- for (const event of events) {
34
- totalMarketCount += (event.markets || []).length;
35
- }
36
- // Early termination: if we have enough markets, stop fetching
37
- // Use 1.5x multiplier to ensure we have enough for sorting/filtering
38
- if (totalMarketCount >= targetMarketCount * 1.5) {
39
- break;
40
- }
41
- }
42
- cursor = data.cursor;
43
- page++;
44
- // Additional safety: if no target specified, limit to reasonable number of pages
45
- if (!targetMarketCount && page >= 10) {
46
- break;
47
- }
48
- }
49
- catch (e) {
50
- throw errors_1.kalshiErrorMapper.mapError(e);
51
- }
52
- } while (cursor && page < MAX_PAGES);
53
- return allEvents;
54
- }
55
- async function fetchSeriesMap(callApi) {
56
- try {
57
- const data = await callApi("GetSeriesList");
58
- const seriesList = data.series || [];
59
- const map = new Map();
60
- for (const series of seriesList) {
61
- if (series.tags && series.tags.length > 0) {
62
- map.set(series.ticker, series.tags);
63
- }
64
- }
65
- return map;
66
- }
67
- catch (e) {
68
- throw errors_1.kalshiErrorMapper.mapError(e);
69
- }
70
- }
71
- // Simple in-memory cache to avoid redundant API calls within a short period
72
- let cachedEvents = null;
73
- let cachedSeriesMap = null;
74
- let lastCacheTime = 0;
75
- const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
76
- // Export a function to reset the cache (useful for testing)
77
- function resetCache() {
78
- cachedEvents = null;
79
- cachedSeriesMap = null;
80
- lastCacheTime = 0;
81
- }
82
- async function fetchMarkets(params, callApi) {
83
- try {
84
- // Handle marketId lookup (Kalshi marketId is the ticker)
85
- if (params?.marketId) {
86
- return await fetchMarketsBySlug(params.marketId, callApi);
87
- }
88
- // Handle slug-based lookup (event ticker)
89
- if (params?.slug) {
90
- return await fetchMarketsBySlug(params.slug, callApi);
91
- }
92
- // Handle outcomeId lookup (strip -NO suffix, use as ticker)
93
- if (params?.outcomeId) {
94
- const ticker = params.outcomeId.replace(/-NO$/, "");
95
- return await fetchMarketsBySlug(ticker, callApi);
96
- }
97
- // Handle eventId lookup (event ticker works the same way)
98
- if (params?.eventId) {
99
- return await fetchMarketsBySlug(params.eventId, callApi);
100
- }
101
- // Handle query-based search
102
- if (params?.query) {
103
- return await searchMarkets(params.query, params, callApi);
104
- }
105
- // Default: fetch markets
106
- return await fetchMarketsDefault(params, callApi);
107
- }
108
- catch (error) {
109
- throw errors_1.kalshiErrorMapper.mapError(error);
110
- }
111
- }
112
- async function fetchMarketsBySlug(eventTicker, callApi) {
113
- // Kalshi API expects uppercase tickers, but URLs use lowercase
114
- const normalizedTicker = eventTicker.toUpperCase();
115
- const data = await callApi("GetEvent", {
116
- event_ticker: normalizedTicker,
117
- with_nested_markets: true,
118
- });
119
- const event = data.event;
120
- if (!event)
121
- return [];
122
- // Enrichment: Fetch series tags if they exist
123
- if (event.series_ticker) {
124
- try {
125
- const seriesData = await callApi("GetSeries", {
126
- series_ticker: event.series_ticker,
127
- });
128
- const series = seriesData.series;
129
- if (series && series.tags && series.tags.length > 0) {
130
- if (!event.tags || event.tags.length === 0) {
131
- event.tags = series.tags;
132
- }
133
- }
134
- }
135
- catch (e) {
136
- // Ignore errors fetching series info - non-critical
137
- }
138
- }
139
- const unifiedMarkets = [];
140
- const markets = event.markets || [];
141
- for (const market of markets) {
142
- const unifiedMarket = (0, utils_1.mapMarketToUnified)(event, market);
143
- if (unifiedMarket) {
144
- unifiedMarkets.push(unifiedMarket);
145
- }
146
- }
147
- return unifiedMarkets;
148
- }
149
- async function searchMarkets(query, params, callApi) {
150
- // We must fetch ALL markets to search them locally since we don't have server-side search
151
- const searchLimit = 250000;
152
- const markets = await fetchMarketsDefault({ ...params, limit: searchLimit }, callApi);
153
- const lowerQuery = query.toLowerCase();
154
- const searchIn = params?.searchIn || "title"; // Default to title-only search
155
- const filtered = markets.filter((market) => {
156
- const titleMatch = (market.title || "").toLowerCase().includes(lowerQuery);
157
- const descMatch = (market.description || "")
158
- .toLowerCase()
159
- .includes(lowerQuery);
160
- if (searchIn === "title")
161
- return titleMatch;
162
- if (searchIn === "description")
163
- return descMatch;
164
- return titleMatch || descMatch; // 'both'
165
- });
166
- const limit = params?.limit || 250000;
167
- return filtered.slice(0, limit);
168
- }
169
- async function fetchMarketsDefault(params, callApi) {
170
- const limit = params?.limit || 250000;
171
- const offset = params?.offset || 0;
172
- const now = Date.now();
173
- const status = params?.status || "active"; // Default to 'active'
174
- // Map 'active' -> 'open', 'closed' -> 'closed'
175
- // Kalshi statuses: 'open', 'closed', 'settled'
176
- let apiStatus = "open";
177
- if (status === "closed" || status === "inactive")
178
- apiStatus = "closed";
179
- else if (status === "all")
180
- apiStatus = "open"; // Fallback for all? Or loop? For now default to open.
181
- try {
182
- let events;
183
- let seriesMap;
184
- // Check if we have valid cached data
185
- // Only use global cache for the default 'active'/'open' case
186
- const useCache = status === "active" || !params?.status;
187
- if (useCache &&
188
- cachedEvents &&
189
- cachedSeriesMap &&
190
- now - lastCacheTime < CACHE_TTL) {
191
- events = cachedEvents;
192
- seriesMap = cachedSeriesMap;
193
- }
194
- else {
195
- // Optimize fetch limit based on request parameters
196
- // If sorting is required (e.g. by volume), we need to fetch a larger set (or all) to sort correctly.
197
- // If no sorting is requested, we only need to fetch enough to satisfy the limit.
198
- const isSorted = params?.sort &&
199
- (params.sort === "volume" || params.sort === "liquidity");
200
- const fetchLimit = isSorted ? 1000 : limit;
201
- const [allEvents, fetchedSeriesMap] = await Promise.all([
202
- fetchActiveEvents(callApi, fetchLimit, apiStatus),
203
- fetchSeriesMap(callApi),
204
- ]);
205
- events = allEvents;
206
- seriesMap = fetchedSeriesMap;
207
- // Cache the dataset ONLY if:
208
- // 1. We fetched a comprehensive set (>= 1000)
209
- // 2. It's the standard 'open' status query
210
- if (fetchLimit >= 1000 && useCache) {
211
- cachedEvents = allEvents;
212
- cachedSeriesMap = fetchedSeriesMap;
213
- lastCacheTime = now;
214
- }
215
- }
216
- // Extract ALL markets from all events
217
- const allMarkets = [];
218
- // ... rest of the logic
219
- for (const event of events) {
220
- // Enrich event with tags from Series
221
- if (event.series_ticker && seriesMap.has(event.series_ticker)) {
222
- // If event has no tags or empty tags, use series tags
223
- if (!event.tags || event.tags.length === 0) {
224
- event.tags = seriesMap.get(event.series_ticker);
225
- }
226
- }
227
- const markets = event.markets || [];
228
- for (const market of markets) {
229
- const unifiedMarket = (0, utils_1.mapMarketToUnified)(event, market);
230
- if (unifiedMarket) {
231
- allMarkets.push(unifiedMarket);
232
- }
233
- }
234
- }
235
- // Sort by 24h volume
236
- if (params?.sort === "volume") {
237
- allMarkets.sort((a, b) => b.volume24h - a.volume24h);
238
- }
239
- else if (params?.sort === "liquidity") {
240
- allMarkets.sort((a, b) => b.liquidity - a.liquidity);
241
- }
242
- return allMarkets.slice(offset, offset + limit);
243
- }
244
- catch (error) {
245
- throw errors_1.kalshiErrorMapper.mapError(error);
246
- }
247
- }
@@ -1,3 +0,0 @@
1
- import { OHLCVParams } from "../../BaseExchange";
2
- import { PriceCandle } from "../../types";
3
- export declare function fetchOHLCV(id: string, params: OHLCVParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<PriceCandle[]>;
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchOHLCV = fetchOHLCV;
4
- const utils_1 = require("./utils");
5
- const validation_1 = require("../../utils/validation");
6
- const errors_1 = require("./errors");
7
- const price_1 = require("./price");
8
- async function fetchOHLCV(id, params, callApi) {
9
- (0, validation_1.validateIdFormat)(id, "OHLCV");
10
- // Validate resolution is provided
11
- if (!params.resolution) {
12
- throw new Error("fetchOHLCV requires a resolution parameter. Use OHLCVParams with resolution specified.");
13
- }
14
- try {
15
- // Kalshi API expects uppercase tickers
16
- // Handle virtual "-NO" suffix by stripping it (fetching the underlying market history)
17
- const cleanedId = id.replace(/-NO$/, "");
18
- const normalizedId = cleanedId.toUpperCase();
19
- const interval = (0, utils_1.mapIntervalToKalshi)(params.resolution);
20
- // Heuristic for series_ticker
21
- const parts = normalizedId.split("-");
22
- if (parts.length < 2) {
23
- throw new Error(`Invalid Kalshi Ticker format: "${id}". Expected format like "FED-25JAN29-B4.75".`);
24
- }
25
- const seriesTicker = parts.slice(0, -1).join("-");
26
- const now = Math.floor(Date.now() / 1000);
27
- let startTs = now - 24 * 60 * 60;
28
- let endTs = now;
29
- // Helper to handle string dates (from JSON)
30
- // IMPORTANT: Python sends naive datetimes as ISO strings without 'Z' suffix.
31
- // We must treat these as UTC, not local time.
32
- const ensureDate = (d) => {
33
- if (typeof d === "string") {
34
- // If string doesn't end with 'Z' and doesn't have timezone offset, append 'Z'
35
- if (!d.endsWith("Z") && !d.match(/[+-]\d{2}:\d{2}$/)) {
36
- return new Date(d + "Z");
37
- }
38
- return new Date(d);
39
- }
40
- return d;
41
- };
42
- const pStart = params.start ? ensureDate(params.start) : undefined;
43
- const pEnd = params.end ? ensureDate(params.end) : undefined;
44
- if (pStart) {
45
- startTs = Math.floor(pStart.getTime() / 1000);
46
- }
47
- if (pEnd) {
48
- endTs = Math.floor(pEnd.getTime() / 1000);
49
- if (!pStart) {
50
- startTs = endTs - 24 * 60 * 60;
51
- }
52
- }
53
- const data = await callApi("GetMarketCandlesticks", {
54
- series_ticker: seriesTicker,
55
- ticker: normalizedId,
56
- period_interval: interval,
57
- start_ts: startTs,
58
- end_ts: endTs,
59
- });
60
- const candles = data.candlesticks || [];
61
- const mappedCandles = candles.map((c) => {
62
- // Priority:
63
- // 1. Transaction price (close)
64
- // 2. Mid price (average of yes_ask and yes_bid close)
65
- // 3. Fallback to 0 if everything is missing
66
- const p = c.price || {};
67
- const ask = c.yes_ask || {};
68
- const bid = c.yes_bid || {};
69
- const getVal = (field) => {
70
- if (p[field] !== null && p[field] !== undefined)
71
- return p[field];
72
- if (ask[field] !== null &&
73
- bid[field] !== null &&
74
- ask[field] !== undefined &&
75
- bid[field] !== undefined) {
76
- return (ask[field] + bid[field]) / 2;
77
- }
78
- return p.previous || 0;
79
- };
80
- return {
81
- timestamp: c.end_period_ts * 1000,
82
- open: (0, price_1.fromKalshiCents)(getVal("open")),
83
- high: (0, price_1.fromKalshiCents)(getVal("high")),
84
- low: (0, price_1.fromKalshiCents)(getVal("low")),
85
- close: (0, price_1.fromKalshiCents)(getVal("close")),
86
- volume: c.volume || 0,
87
- };
88
- });
89
- if (params.limit && mappedCandles.length > params.limit) {
90
- return mappedCandles.slice(-params.limit);
91
- }
92
- return mappedCandles;
93
- }
94
- catch (error) {
95
- throw errors_1.kalshiErrorMapper.mapError(error);
96
- }
97
- }
@@ -1,2 +0,0 @@
1
- import { OrderBook } from "../../types";
2
- export declare function fetchOrderBook(baseUrl: string, id: string): Promise<OrderBook>;
@@ -1,60 +0,0 @@
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.fetchOrderBook = fetchOrderBook;
7
- const axios_1 = __importDefault(require("axios"));
8
- const validation_1 = require("../../utils/validation");
9
- const errors_1 = require("./errors");
10
- const config_1 = require("./config");
11
- async function fetchOrderBook(baseUrl, id) {
12
- (0, validation_1.validateIdFormat)(id, "OrderBook");
13
- try {
14
- // Check if this is a NO outcome request
15
- const isNoOutcome = id.endsWith("-NO");
16
- const ticker = id.replace(/-NO$/, "");
17
- const url = (0, config_1.getMarketsUrl)(baseUrl, ticker, ["orderbook"]);
18
- const response = await axios_1.default.get(url);
19
- const data = response.data.orderbook_fp;
20
- // Structure: { yes_dollars: [["price", "qty"], ...], no_dollars: [["price", "qty"], ...] }
21
- // Prices are dollar strings (e.g. "0.15"), quantities are fixed-point strings (e.g. "100.00")
22
- // - yes_dollars: bids for buying YES at price X
23
- // - no_dollars: bids for buying NO at price X
24
- let bids;
25
- let asks;
26
- if (isNoOutcome) {
27
- // NO outcome order book:
28
- // - Bids: people buying NO (use data.no_dollars directly)
29
- // - Asks: people selling NO = people buying YES (invert data.yes_dollars)
30
- bids = (data.no_dollars || []).map((level) => ({
31
- price: parseFloat(level[0]),
32
- size: parseFloat(level[1]),
33
- }));
34
- asks = (data.yes_dollars || []).map((level) => ({
35
- price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
36
- size: parseFloat(level[1]),
37
- }));
38
- }
39
- else {
40
- // YES outcome order book:
41
- // - Bids: people buying YES (use data.yes_dollars directly)
42
- // - Asks: people selling YES = people buying NO (invert data.no_dollars)
43
- bids = (data.yes_dollars || []).map((level) => ({
44
- price: parseFloat(level[0]),
45
- size: parseFloat(level[1]),
46
- }));
47
- asks = (data.no_dollars || []).map((level) => ({
48
- price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
49
- size: parseFloat(level[1]),
50
- }));
51
- }
52
- // Sort bids desc, asks asc
53
- bids.sort((a, b) => b.price - a.price);
54
- asks.sort((a, b) => a.price - b.price);
55
- return { bids, asks, timestamp: Date.now() };
56
- }
57
- catch (error) {
58
- throw errors_1.kalshiErrorMapper.mapError(error);
59
- }
60
- }
@@ -1,3 +0,0 @@
1
- import { HistoryFilterParams, TradesParams } from "../../BaseExchange";
2
- import { Trade } from "../../types";
3
- export declare function fetchTrades(baseUrl: string, id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
@@ -1,33 +0,0 @@
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.fetchTrades = fetchTrades;
7
- const axios_1 = __importDefault(require("axios"));
8
- const errors_1 = require("./errors");
9
- const config_1 = require("./config");
10
- const price_1 = require("./price");
11
- async function fetchTrades(baseUrl, id, params) {
12
- try {
13
- const ticker = id.replace(/-NO$/, "");
14
- const url = (0, config_1.getMarketsUrl)(baseUrl, undefined, ["trades"]);
15
- const response = await axios_1.default.get(url, {
16
- params: {
17
- ticker: ticker,
18
- limit: params.limit || 100,
19
- },
20
- });
21
- const trades = response.data.trades || [];
22
- return trades.map((t) => ({
23
- id: t.trade_id,
24
- timestamp: new Date(t.created_time).getTime(),
25
- price: (0, price_1.fromKalshiCents)(t.yes_price),
26
- amount: t.count,
27
- side: t.taker_side === "yes" ? "buy" : "sell",
28
- }));
29
- }
30
- catch (error) {
31
- throw errors_1.kalshiErrorMapper.mapError(error);
32
- }
33
- }
@@ -1,4 +0,0 @@
1
- import { EventFetchParams } from '../../BaseExchange';
2
- import { UnifiedEvent } from '../../types';
3
- import { AxiosInstance } from 'axios';
4
- export declare function fetchEvents(params: EventFetchParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>, http?: AxiosInstance): Promise<UnifiedEvent[]>;
@@ -1,173 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.fetchEvents = fetchEvents;
40
- const utils_1 = require("./utils");
41
- const errors_1 = require("./errors");
42
- const axios_1 = __importDefault(require("axios"));
43
- async function fetchEventBySlug(slug, http = axios_1.default) {
44
- const { HttpClient, MarketFetcher } = await Promise.resolve().then(() => __importStar(require('@limitless-exchange/sdk')));
45
- const httpClient = new HttpClient({ baseURL: utils_1.LIMITLESS_API_URL });
46
- const marketFetcher = new MarketFetcher(httpClient);
47
- const market = await marketFetcher.getMarket(slug);
48
- if (!market)
49
- return null;
50
- let marketsList = [];
51
- if (market.markets && Array.isArray(market.markets)) {
52
- marketsList = market.markets
53
- .map((child) => (0, utils_1.mapMarketToUnified)(child))
54
- .filter((m) => m !== null);
55
- }
56
- else {
57
- const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
58
- if (unifiedMarket)
59
- marketsList = [unifiedMarket];
60
- }
61
- const unifiedEvent = {
62
- id: market.slug,
63
- title: market.title || market.question,
64
- description: market.description || '',
65
- slug: market.slug,
66
- markets: marketsList,
67
- volume24h: marketsList.reduce((sum, m) => sum + m.volume24h, 0),
68
- volume: marketsList.some(m => m.volume !== undefined) ? marketsList.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
69
- url: `https://limitless.exchange/markets/${market.slug}`,
70
- image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
71
- category: market.categories?.[0],
72
- tags: market.tags || []
73
- };
74
- return unifiedEvent;
75
- }
76
- function rawMarketToEvent(market) {
77
- let marketsList = [];
78
- if (market.markets && Array.isArray(market.markets)) {
79
- marketsList = market.markets
80
- .map((child) => (0, utils_1.mapMarketToUnified)(child))
81
- .filter((m) => m !== null);
82
- }
83
- else {
84
- const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
85
- if (unifiedMarket)
86
- marketsList = [unifiedMarket];
87
- }
88
- const unifiedEvent = {
89
- id: market.slug,
90
- title: market.title || market.question,
91
- description: market.description || '',
92
- slug: market.slug,
93
- markets: marketsList,
94
- volume24h: marketsList.reduce((sum, m) => sum + m.volume24h, 0),
95
- volume: marketsList.some(m => m.volume !== undefined) ? marketsList.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
96
- url: `https://limitless.exchange/markets/${market.slug}`,
97
- image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
98
- category: market.categories?.[0],
99
- tags: market.tags || []
100
- };
101
- return unifiedEvent;
102
- }
103
- async function fetchEvents(params, callApi, http = axios_1.default) {
104
- try {
105
- // Handle eventId/slug lookup (same thing for Limitless)
106
- if (params.eventId || params.slug) {
107
- const slug = params.eventId || params.slug;
108
- const event = await fetchEventBySlug(slug, http);
109
- return event ? [event] : [];
110
- }
111
- // Query-based search: use the /markets/search endpoint
112
- if (params.query) {
113
- return await searchEvents(params, callApi);
114
- }
115
- // Default: fetch active group markets from /markets/active
116
- // On Limitless, "events" = group markets (tradeType === 'group')
117
- return await fetchEventsDefault(params, http);
118
- }
119
- catch (error) {
120
- throw errors_1.limitlessErrorMapper.mapError(error);
121
- }
122
- }
123
- async function searchEvents(params, callApi) {
124
- // NOTE: The Limitless /markets/search endpoint currently only returns active/funded markets.
125
- const data = await callApi('MarketSearchController_search', {
126
- query: params.query,
127
- limit: params?.limit || 10000,
128
- similarityThreshold: 0.5,
129
- });
130
- let markets = data?.markets || [];
131
- const status = params?.status || 'active';
132
- if (status === 'active') {
133
- markets = markets.filter((m) => !m.expired && m.winningOutcomeIndex === null);
134
- }
135
- else if (status === 'inactive' || status === 'closed') {
136
- markets = markets.filter((m) => m.expired === true || m.winningOutcomeIndex !== null);
137
- }
138
- return markets.map(rawMarketToEvent);
139
- }
140
- async function fetchEventsDefault(params, http = axios_1.default) {
141
- // Limitless has no dedicated /events endpoint.
142
- // Group markets (tradeType === 'group') are the semantic equivalent of events.
143
- // We use GET /markets/active and filter for groups only.
144
- const limit = params?.limit || 10000;
145
- let page = 1;
146
- const pageSize = 25; // Limitless API hard limit
147
- const MAX_PAGES = 40; // Safety cap
148
- const allGroups = [];
149
- while (allGroups.length < limit && page <= MAX_PAGES) {
150
- const response = await http.get(`${utils_1.LIMITLESS_API_URL}/markets/active`, {
151
- params: {
152
- page,
153
- limit: pageSize,
154
- tradeType: 'group',
155
- sortBy: params?.sort === 'newest' ? 'newest' : params?.sort === 'liquidity' ? 'lp_rewards' : 'high_value',
156
- }
157
- });
158
- const items = response.data?.data || response.data || [];
159
- if (items.length === 0)
160
- break;
161
- for (const item of items) {
162
- if (allGroups.length >= limit)
163
- break;
164
- const event = rawMarketToEvent(item);
165
- allGroups.push(event);
166
- }
167
- // If the page returned fewer items than the page size, we've reached the end
168
- if (items.length < pageSize)
169
- break;
170
- page++;
171
- }
172
- return allGroups;
173
- }
@@ -1,3 +0,0 @@
1
- import { MarketFetchParams } from '../../BaseExchange';
2
- import { UnifiedMarket } from '../../types';
3
- export declare function fetchMarkets(params?: MarketFetchParams, apiKey?: string, callApi?: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<UnifiedMarket[]>;