pmxtjs 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/API_REFERENCE.md +88 -0
  2. package/coverage/clover.xml +334 -0
  3. package/coverage/coverage-final.json +4 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +131 -0
  8. package/coverage/lcov-report/pmxt/BaseExchange.ts.html +256 -0
  9. package/coverage/lcov-report/pmxt/exchanges/Kalshi.ts.html +1132 -0
  10. package/coverage/lcov-report/pmxt/exchanges/Polymarket.ts.html +1456 -0
  11. package/coverage/lcov-report/pmxt/exchanges/index.html +131 -0
  12. package/coverage/lcov-report/pmxt/index.html +116 -0
  13. package/coverage/lcov-report/prettify.css +1 -0
  14. package/coverage/lcov-report/prettify.js +2 -0
  15. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  16. package/coverage/lcov-report/sorter.js +210 -0
  17. package/coverage/lcov-report/src/BaseExchange.ts.html +256 -0
  18. package/coverage/lcov-report/src/exchanges/Kalshi.ts.html +1132 -0
  19. package/coverage/lcov-report/src/exchanges/Polymarket.ts.html +1456 -0
  20. package/coverage/lcov-report/src/exchanges/index.html +131 -0
  21. package/coverage/lcov-report/src/index.html +116 -0
  22. package/coverage/lcov.info +766 -0
  23. package/examples/get_event_prices.ts +37 -0
  24. package/examples/historical_prices.ts +117 -0
  25. package/examples/orderbook.ts +102 -0
  26. package/examples/recent_trades.ts +29 -0
  27. package/examples/search_events.ts +68 -0
  28. package/examples/search_market.ts +29 -0
  29. package/jest.config.js +11 -0
  30. package/package.json +21 -21
  31. package/pmxt-0.1.0.tgz +0 -0
  32. package/src/BaseExchange.ts +57 -0
  33. package/src/exchanges/Kalshi.ts +349 -0
  34. package/src/exchanges/Polymarket.ts +457 -0
  35. package/src/index.ts +5 -0
  36. package/src/types.ts +61 -0
  37. package/test/exchanges/kalshi/ApiErrors.test.ts +132 -0
  38. package/test/exchanges/kalshi/EmptyResponse.test.ts +44 -0
  39. package/test/exchanges/kalshi/FetchAndNormalizeMarkets.test.ts +56 -0
  40. package/test/exchanges/kalshi/LiveApi.integration.test.ts +40 -0
  41. package/test/exchanges/kalshi/MarketHistory.test.ts +185 -0
  42. package/test/exchanges/kalshi/OrderBook.test.ts +149 -0
  43. package/test/exchanges/kalshi/SearchMarkets.test.ts +174 -0
  44. package/test/exchanges/kalshi/VolumeFallback.test.ts +44 -0
  45. package/test/exchanges/polymarket/DataValidation.test.ts +271 -0
  46. package/test/exchanges/polymarket/ErrorHandling.test.ts +34 -0
  47. package/test/exchanges/polymarket/FetchAndNormalizeMarkets.test.ts +68 -0
  48. package/test/exchanges/polymarket/GetMarketsBySlug.test.ts +268 -0
  49. package/test/exchanges/polymarket/LiveApi.integration.test.ts +44 -0
  50. package/test/exchanges/polymarket/MarketHistory.test.ts +207 -0
  51. package/test/exchanges/polymarket/OrderBook.test.ts +167 -0
  52. package/test/exchanges/polymarket/RequestParameters.test.ts +39 -0
  53. package/test/exchanges/polymarket/SearchMarkets.test.ts +176 -0
  54. package/test/exchanges/polymarket/TradeHistory.test.ts +248 -0
  55. package/tsconfig.json +12 -0
  56. package/Cargo.toml +0 -15
  57. package/README.md +0 -47
  58. package/src/lib.rs +0 -6
@@ -0,0 +1,37 @@
1
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
2
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
3
+
4
+ const main = async () => {
5
+ const polySlug = process.argv[2] || 'who-will-trump-nominate-as-fed-chair';
6
+ const kalshiTicker = process.argv[3] || 'KXFEDCHAIRNOM-29';
7
+
8
+ console.log(`Fetching prices for: ${polySlug} / ${kalshiTicker}\n`);
9
+
10
+ // Polymarket
11
+ const polymarket = new PolymarketExchange();
12
+ const polyMarkets = await polymarket.getMarketsBySlug(polySlug);
13
+
14
+ console.log('--- Polymarket ---');
15
+ polyMarkets
16
+ .sort((a, b) => b.outcomes[0].price - a.outcomes[0].price)
17
+ .slice(0, 10)
18
+ .forEach(m => {
19
+ console.log(`${m.outcomes[0].label}: ${(m.outcomes[0].price * 100).toFixed(1)}% ` +
20
+ `(Vol24h: $${m.volume24h.toLocaleString()})`);
21
+ });
22
+
23
+ // Kalshi
24
+ const kalshi = new KalshiExchange();
25
+ const kalshiMarkets = await kalshi.getMarketsBySlug(kalshiTicker);
26
+
27
+ console.log('\n--- Kalshi ---');
28
+ kalshiMarkets
29
+ .sort((a, b) => b.outcomes[0].price - a.outcomes[0].price)
30
+ .slice(0, 10)
31
+ .forEach(m => {
32
+ console.log(`${m.outcomes[0].label}: ${(m.outcomes[0].price * 100).toFixed(1)}% ` +
33
+ `(Vol24h: $${m.volume24h.toLocaleString()})`);
34
+ });
35
+ };
36
+
37
+ main();
@@ -0,0 +1,117 @@
1
+
2
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
3
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
4
+ import { CandleInterval } from '../src/types';
5
+
6
+ /**
7
+ * START HERE
8
+ *
9
+ * This example fetches historical price data for a specific EVENT.
10
+ *
11
+ * NOTE:
12
+ * An "Event" (e.g. "Who will be Fed Chair?") contains multiple "Markets" or "Outcomes"
13
+ * (e.g. "Kevin Warsh", "Marc Rowan", "Scott Bessent").
14
+ *
15
+ * Price history is tracked at the MARKET/OUTCOME level.
16
+ */
17
+
18
+ const main = async () => {
19
+ // 1. Define the Event Slugs (Hardcoded for simplicity)
20
+ const polySlug = 'who-will-trump-nominate-as-fed-chair';
21
+ const kalshiTicker = 'KXFEDCHAIRNOM-29';
22
+
23
+ console.log(`=== Historical Price Fetcher ===\n`);
24
+ console.log(`Target Event: Fed Chair Nomination (Kevin Warsh - YES)`);
25
+
26
+ // ---------------------------------------------------------
27
+ // Polymarket
28
+ // ---------------------------------------------------------
29
+ const polymarket = new PolymarketExchange();
30
+ console.log('\n--- Polymarket ---');
31
+ try {
32
+ const polyMarkets = await polymarket.getMarketsBySlug(polySlug);
33
+
34
+ if (polyMarkets.length > 0) {
35
+ const eventMarket = polyMarkets[0];
36
+
37
+ // Find "Kevin Warsh" outcome
38
+ const warshOutcome = eventMarket.outcomes.find(o =>
39
+ o.label.toLowerCase().includes('warsh') &&
40
+ !o.label.toLowerCase().includes('not') // Ensure it's YES
41
+ );
42
+
43
+ if (!warshOutcome) {
44
+ console.log("Could not find 'Kevin Warsh' outcome in Polymarket event.");
45
+ } else {
46
+ console.log(`Target Outcome: ${warshOutcome.label}`);
47
+ console.log(`Current Price: ${(warshOutcome.price * 100).toFixed(1)}%`);
48
+
49
+ const clobTokenId = warshOutcome.metadata?.clobTokenId;
50
+
51
+ if (clobTokenId) {
52
+ console.log(`Fetching 1-hour history for "${warshOutcome.label}"...`);
53
+ console.log(`Token ID: ${clobTokenId}`);
54
+
55
+ const history = await polymarket.getMarketHistory(clobTokenId, {
56
+ resolution: '1h',
57
+ limit: 20,
58
+ start: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // 7 days ago
59
+ });
60
+
61
+ console.log(`Received ${history.length} data points.`);
62
+ history.forEach(point => {
63
+ const date = new Date(point.timestamp).toLocaleString();
64
+ console.log(` ${date} | Price: $${point.close.toFixed(3)}`);
65
+ });
66
+ } else {
67
+ console.log('No Token ID found, cannot fetch history.');
68
+ }
69
+ }
70
+ }
71
+ } catch (e) {
72
+ console.error("Polymarket Error:", e);
73
+ }
74
+
75
+ // ---------------------------------------------------------
76
+ // Kalshi
77
+ // ---------------------------------------------------------
78
+ const kalshi = new KalshiExchange();
79
+ console.log('\n--- Kalshi ---');
80
+ try {
81
+ // First get the event to find the markets
82
+ const kalshiMarkets = await kalshi.getMarketsBySlug(kalshiTicker);
83
+
84
+ if (kalshiMarkets.length > 0) {
85
+ // Find the market where the subtitle/title includes Warsh
86
+ // Kalshi often has subtitles like "Kevin Warsh"
87
+ const warshMarket = kalshiMarkets.find(m =>
88
+ m.description.toLowerCase().includes('warsh') ||
89
+ m.outcomes[0].label.toLowerCase().includes('warsh')
90
+ );
91
+
92
+ if (!warshMarket) {
93
+ console.log("Could not find 'Kevin Warsh' market in Kalshi event.");
94
+ } else {
95
+ console.log(`Target Market: ${warshMarket.title} (${warshMarket.description})`);
96
+ console.log(`Ticker: ${warshMarket.id}`);
97
+ console.log(`Current Price: ${(warshMarket.outcomes[0].price * 100).toFixed(1)}%`);
98
+
99
+ console.log(`Fetching 1-hour history...`);
100
+
101
+ const history = await kalshi.getMarketHistory(warshMarket.id, {
102
+ resolution: '1h',
103
+ limit: 10
104
+ });
105
+
106
+ history.forEach(candle => {
107
+ const date = new Date(candle.timestamp).toLocaleString();
108
+ console.log(` ${date} | Price: $${candle.close.toFixed(2)}`);
109
+ });
110
+ }
111
+ }
112
+ } catch (e) {
113
+ console.error("Kalshi Error:", e);
114
+ }
115
+ };
116
+
117
+ main();
@@ -0,0 +1,102 @@
1
+
2
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
3
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
4
+ import { OrderBook } from '../src/types';
5
+
6
+ /**
7
+ * Example: Get Order Book (Multi-Exchange)
8
+ *
9
+ * This example fetches and compares order books from both Polymarket and Kalshi
10
+ * for the "Kevin Warsh" Fed Chair nomination prediction.
11
+ */
12
+
13
+ // Helper to display an order book
14
+ const displayOrderBook = (exchangeName: string, book: OrderBook) => {
15
+ console.log(`\n-----------------------------------------`);
16
+ console.log(`ORDER BOOK: ${exchangeName}`);
17
+ console.log(`-----------------------------------------`);
18
+
19
+ if (book.bids.length === 0 && book.asks.length === 0) {
20
+ console.log("No orders found or market is closed.");
21
+ return;
22
+ }
23
+
24
+ // Show Asks (Sellers) - Reverse to show highest price (lowest/best ask) at bottom
25
+ console.log(`\n --- ASKS (Sellers) ---`);
26
+ const asks = book.asks.slice(0, 5).sort((a, b) => b.price - a.price); // Sort descending for display (high to low)
27
+ asks.forEach(level => {
28
+ console.log(` Price: $${level.price.toFixed(2)} | Size: ${level.size.toLocaleString().padStart(8)}`);
29
+ });
30
+
31
+ // Show Bids (Buyers) - Descending (Highest/best buy first)
32
+ console.log(` --- BIDS (Buyers) ---`);
33
+ const bids = book.bids.slice(0, 5).sort((a, b) => b.price - a.price);
34
+ bids.forEach(level => {
35
+ console.log(` Price: $${level.price.toFixed(2)} | Size: ${level.size.toLocaleString().padStart(8)}`);
36
+ });
37
+ };
38
+
39
+ const main = async () => {
40
+ console.log(`=== Multi-Exchange Order Book Fetcher ===`);
41
+ console.log(`Target: "Kevin Warsh" -> Fed Chair Nomination\n`);
42
+
43
+ // 1. Polymarket
44
+ try {
45
+ const polymarket = new PolymarketExchange();
46
+ const polySlug = 'who-will-trump-nominate-as-fed-chair';
47
+
48
+ console.log(`Fetching Polymarket data...`);
49
+ const markets = await polymarket.getMarketsBySlug(polySlug);
50
+
51
+ if (markets.length > 0) {
52
+ const warshOutcome = markets[0].outcomes.find(o =>
53
+ o.label.toLowerCase().includes('warsh') &&
54
+ !o.label.toLowerCase().includes('not')
55
+ );
56
+
57
+ if (warshOutcome && warshOutcome.metadata?.clobTokenId) {
58
+ const book = await polymarket.getOrderBook(warshOutcome.metadata.clobTokenId);
59
+ displayOrderBook('Polymarket', book);
60
+ } else {
61
+ console.log("Polymarket: Outcome or Token ID not found.");
62
+ }
63
+ }
64
+ } catch (e) {
65
+ console.error("Polymarket Error:", e);
66
+ }
67
+
68
+ // 2. Kalshi
69
+ try {
70
+ const kalshi = new KalshiExchange();
71
+ // Specifically for "Kevin Warsh" in the Fed Chair market.
72
+ // Ticker derived from previous searches.
73
+ const kalshiTicker = 'KXFEDCHAIRNOM-29';
74
+
75
+ console.log(`\nFetching Kalshi data...`);
76
+ // Verify event exists and find the specific market
77
+ const markets = await kalshi.getMarketsBySlug(kalshiTicker);
78
+
79
+ if (markets.length > 0) {
80
+ // Find "Kevin Warsh" market within the event group
81
+ const warshMarket = markets.find(m =>
82
+ m.description.toLowerCase().includes('warsh') ||
83
+ m.outcomes[0].label.toLowerCase().includes('warsh')
84
+ );
85
+
86
+ if (warshMarket) {
87
+ console.log(`Found Market Ticker: ${warshMarket.id}`);
88
+ const book = await kalshi.getOrderBook(warshMarket.id);
89
+ displayOrderBook('Kalshi', book);
90
+ } else {
91
+ console.log("Kalshi: 'Kevin Warsh' market not found in event.");
92
+ }
93
+ } else {
94
+ console.log("Kalshi: Event not found.");
95
+ }
96
+
97
+ } catch (e) {
98
+ console.error("Kalshi Error:", e);
99
+ }
100
+ };
101
+
102
+ main();
@@ -0,0 +1,29 @@
1
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
2
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
3
+
4
+ async function run() {
5
+ const kalshi = new KalshiExchange();
6
+ const poly = new PolymarketExchange();
7
+
8
+ const kMarkets = await kalshi.getMarketsBySlug('KXFEDCHAIRNOM-29');
9
+ // Filter for Kevin Warsh specifically
10
+ const warshMarket = kMarkets.find(m => m.outcomes[0].label.includes('Kevin Warsh'));
11
+
12
+ if (warshMarket) {
13
+ console.log(`--- Kalshi Tape: ${warshMarket.outcomes[0].label} ---`);
14
+ const trades = await kalshi.getTradeHistory(warshMarket.id, { limit: 10, resolution: '1m' });
15
+ trades.forEach(t => console.log(`${new Date(t.timestamp).toLocaleTimeString()} | ${t.side.toUpperCase()} | ${(t.price * 100).toFixed(1)}c | ${t.amount}`));
16
+ }
17
+
18
+ const pMarkets = await poly.getMarketsBySlug('who-will-trump-nominate-as-fed-chair');
19
+ const pWarsh = pMarkets.find(m => m.outcomes[0].label.includes('Kevin Warsh'));
20
+
21
+ if (pWarsh) {
22
+ console.log(`\n--- Polymarket Tape: Kevin Warsh ---`);
23
+ const tokenId = pWarsh.outcomes[0].metadata?.clobTokenId;
24
+ const trades = await poly.getTradeHistory(tokenId, { limit: 5, resolution: '1m' });
25
+ trades.forEach(t => console.log(`${new Date(t.timestamp).toLocaleTimeString()} | ${t.side.toUpperCase()} | ${(t.price * 100).toFixed(1)}c | ${t.amount}`));
26
+ }
27
+ }
28
+
29
+ run();
@@ -0,0 +1,68 @@
1
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
2
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
3
+ import { UnifiedMarket } from '../src/types';
4
+
5
+ interface UnifiedEvent {
6
+ title: string;
7
+ url: string;
8
+ volume24h: number; // Aggregated
9
+ markets: UnifiedMarket[];
10
+ }
11
+
12
+ const groupMarketsByEvent = (markets: UnifiedMarket[]): UnifiedEvent[] => {
13
+ const eventsMap = new Map<string, UnifiedEvent>();
14
+
15
+ for (const m of markets) {
16
+ if (!eventsMap.has(m.url)) {
17
+ eventsMap.set(m.url, {
18
+ title: m.title,
19
+ url: m.url,
20
+ volume24h: 0,
21
+ markets: []
22
+ });
23
+ }
24
+ const event = eventsMap.get(m.url)!;
25
+ event.volume24h += m.volume24h;
26
+ event.markets.push(m);
27
+ }
28
+
29
+ return Array.from(eventsMap.values());
30
+ };
31
+
32
+ const main = async () => {
33
+ const query = process.argv[2] || 'Fed';
34
+ console.log(`Searching for Events matching "${query}"...\n`);
35
+
36
+ // 1. Polymarket
37
+ const polymarket = new PolymarketExchange();
38
+ // Polymarket returns many sub-markets per event
39
+ const polyMarkets = await polymarket.searchMarkets(query, { sort: 'volume' });
40
+ const polyEvents = groupMarketsByEvent(polyMarkets);
41
+
42
+ console.log(`--- Polymarket Events (${polyEvents.length}) ---`);
43
+ polyEvents
44
+ .sort((a, b) => b.volume24h - a.volume24h)
45
+ .slice(0, 5)
46
+ .forEach(e => {
47
+ console.log(`${e.title} (Vol24h: $${e.volume24h.toLocaleString()})`);
48
+ console.log(` -> ${e.markets.length} sub-markets`);
49
+ });
50
+
51
+ console.log('');
52
+
53
+ // 2. Kalshi
54
+ const kalshi = new KalshiExchange();
55
+ const kalshiMarkets = await kalshi.searchMarkets(query);
56
+ const kalshiEvents = groupMarketsByEvent(kalshiMarkets);
57
+
58
+ console.log(`--- Kalshi Events (${kalshiEvents.length}) ---`);
59
+ kalshiEvents
60
+ .sort((a, b) => b.volume24h - a.volume24h)
61
+ .slice(0, 5)
62
+ .forEach(e => {
63
+ console.log(`${e.title} (Vol24h: $${e.volume24h.toLocaleString()})`);
64
+ console.log(` -> ${e.markets.length} sub-markets`);
65
+ });
66
+ };
67
+
68
+ main();
@@ -0,0 +1,29 @@
1
+ import { PolymarketExchange } from '../src/exchanges/Polymarket';
2
+ import { KalshiExchange } from '../src/exchanges/Kalshi';
3
+
4
+ const main = async () => {
5
+ const query = process.argv[2] || 'Fed';
6
+ console.log(`Searching for "${query}"...\n`);
7
+
8
+ // Polymarket
9
+ const polymarket = new PolymarketExchange();
10
+ const polyResults = await polymarket.searchMarkets(query, { sort: 'volume' });
11
+
12
+ console.log(`--- Polymarket Found ${polyResults.length} ---`);
13
+ polyResults.slice(0, 10).forEach(m => {
14
+ const label = m.outcomes[0]?.label || 'Unknown';
15
+ console.log(`[${m.id}] ${m.title} - ${label} (Vol24h: $${m.volume24h.toLocaleString()})`);
16
+ });
17
+
18
+ // Kalshi
19
+ const kalshi = new KalshiExchange();
20
+ const kalshiResults = await kalshi.searchMarkets(query);
21
+
22
+ console.log(`\n--- Kalshi Found ${kalshiResults.length} ---`);
23
+ kalshiResults.slice(0, 10).forEach(m => {
24
+ const label = m.outcomes[0]?.label || 'Unknown';
25
+ console.log(`[${m.id}] ${m.title} - ${label} (Vol24h: $${m.volume24h.toLocaleString()})`);
26
+ });
27
+ };
28
+
29
+ main();
package/jest.config.js ADDED
@@ -0,0 +1,11 @@
1
+ const { createDefaultPreset } = require("ts-jest");
2
+
3
+ const tsJestTransformCfg = createDefaultPreset().transform;
4
+
5
+ /** @type {import("jest").Config} **/
6
+ module.exports = {
7
+ testEnvironment: "node",
8
+ transform: {
9
+ ...tsJestTransformCfg,
10
+ },
11
+ };
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
- "name": "pmxtjs",
3
- "version": "0.0.1",
4
- "description": "The ccxt for Prediction Markets (Node.js bindings)",
5
- "main": "index.js",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/samueltinnerholm/PMXT.git"
9
- },
10
- "keywords": [
11
- "prediction-markets",
12
- "trading",
13
- "polymarket",
14
- "kalshi",
15
- "ccxt"
16
- ],
17
- "author": "PMXT Team",
18
- "license": "MIT",
19
- "bugs": {
20
- "url": "https://github.com/samueltinnerholm/PMXT/issues"
21
- },
22
- "homepage": "https://github.com/samueltinnerholm/PMXT#readme"
2
+ "name": "pmxtjs",
3
+ "version": "0.1.0",
4
+ "description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "directories": {
8
+ "example": "examples",
9
+ "test": "test"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "test": "jest -c jest.config.js"
14
+ },
15
+ "keywords": [],
16
+ "author": "",
17
+ "license": "ISC",
18
+ "type": "commonjs",
19
+ "dependencies": {
20
+ "axios": "^1.7.9",
21
+ "tsx": "^4.21.0"
22
+ }
23
23
  }
package/pmxt-0.1.0.tgz ADDED
Binary file
@@ -0,0 +1,57 @@
1
+ import { UnifiedMarket, PriceCandle, CandleInterval, OrderBook, Trade } from './types';
2
+
3
+ export interface MarketFilterParams {
4
+ limit?: number;
5
+ offset?: number;
6
+ sort?: 'volume' | 'liquidity' | 'newest';
7
+ }
8
+
9
+ export interface HistoryFilterParams {
10
+ resolution: CandleInterval;
11
+ start?: Date;
12
+ end?: Date;
13
+ limit?: number;
14
+ }
15
+
16
+ // ----------------------------------------------------------------------------
17
+ // Base Exchange Class
18
+ // ----------------------------------------------------------------------------
19
+
20
+ export abstract class PredictionMarketExchange {
21
+ abstract get name(): string;
22
+
23
+ /**
24
+ * Fetch all relevant markets from the source.
25
+ */
26
+ abstract fetchMarkets(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
27
+
28
+ /**
29
+ * Search for markets matching a keyword query.
30
+ * Searches across title and description fields.
31
+ */
32
+ abstract searchMarkets(query: string, params?: MarketFilterParams): Promise<UnifiedMarket[]>;
33
+
34
+ /**
35
+ * Fetch historical price data for a specific market or outcome.
36
+ * @param id - The market ID or specific outcome ID/Token ID depending on the exchange
37
+ */
38
+ async getMarketHistory(id: string, params: HistoryFilterParams): Promise<PriceCandle[]> {
39
+ throw new Error("Method getMarketHistory not implemented.");
40
+ }
41
+
42
+ /**
43
+ * Fetch the current order book (bids/asks) for a specific outcome.
44
+ * Essential for calculating localized spread and depth.
45
+ */
46
+ async getOrderBook(id: string): Promise<OrderBook> {
47
+ throw new Error("Method getOrderBook not implemented.");
48
+ }
49
+
50
+ /**
51
+ * Fetch raw trade history.
52
+ * Useful for generating synthetic OHLCV candles if the exchange doesn't provide them natively.
53
+ */
54
+ async getTradeHistory(id: string, params: HistoryFilterParams): Promise<Trade[]> {
55
+ throw new Error("Method getTradeHistory not implemented.");
56
+ }
57
+ }