Skip to content

Commit 481ac07

Browse files
committed
Add polymarket exchange basis
Signed-off-by: Herklos <herklos.dev@protonmail.com>
1 parent 02a818d commit 481ac07

7 files changed

Lines changed: 8158 additions & 0 deletions

File tree

examples/ts/polymarket-authenticated-example.ts

Lines changed: 572 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
import { polymarket, NetworkError, ExchangeError } from '../../js/ccxt.js';
2+
3+
// AUTO-TRANSPILE #
4+
5+
/**
6+
* Polymarket Example
7+
*
8+
* This example demonstrates how to use CCXT with Polymarket,
9+
* a decentralized prediction market platform.
10+
*
11+
* Features demonstrated:
12+
* - Fetching markets (prediction markets)
13+
* - Fetching order books for specific outcomes
14+
* - Fetching tickers for markets
15+
* - Working with market metadata (outcomes, token IDs, etc.)
16+
* - Fetching public trades for markets
17+
* - Fetching trading fees for markets
18+
* - Fetching user positions from Data-API
19+
* - Fetching user total value from Data-API
20+
* - Fetching open interest for markets
21+
*/
22+
23+
async function example () {
24+
// Initialize Polymarket exchange
25+
const exchange = new polymarket ({
26+
'enableRateLimit': true, // Enable rate limiting
27+
});
28+
29+
try {
30+
console.log ('\n=== Loading Markets ===\n');
31+
32+
// Load all markets
33+
await exchange.loadMarkets ();
34+
35+
console.log ('Loaded', exchange.symbols.length, 'markets');
36+
console.log ('\nFirst 5 markets:');
37+
for (let i = 0; i < Math.min (5, exchange.symbols.length); i++) {
38+
const symbol = exchange.symbols[i];
39+
const market = exchange.markets[symbol];
40+
console.log (' -', symbol);
41+
console.log (' ID:', market['id']);
42+
console.log (' Question:', market['info']['question']);
43+
if (market['info']['outcomes']) {
44+
console.log (' Outcomes:', market['info']['outcomes'].join (', '));
45+
}
46+
}
47+
48+
// Example 1: Fetch a specific market's ticker
49+
console.log ('\n=== Fetching Ticker ===\n');
50+
51+
if (exchange.symbols.length > 0) {
52+
const symbol = exchange.symbols[0];
53+
console.log ('Fetching ticker for:', symbol);
54+
55+
const ticker = await exchange.fetchTicker (symbol);
56+
console.log ('Ticker data:');
57+
console.log (' Symbol:', ticker['symbol']);
58+
console.log (' Last Price:', ticker['last']);
59+
console.log (' Bid:', ticker['bid']);
60+
console.log (' Ask:', ticker['ask']);
61+
console.log (' Volume:', ticker['baseVolume']);
62+
if (ticker['info']['volume24hr']) {
63+
console.log (' 24h Volume:', ticker['info']['volume24hr']);
64+
}
65+
}
66+
67+
// Example 2: Fetch order book for a market
68+
console.log ('\n=== Fetching Order Book ===\n');
69+
70+
if (exchange.symbols.length > 0) {
71+
const symbol = exchange.symbols[0];
72+
const market = exchange.markets[symbol];
73+
74+
// Check if market has CLOB token IDs
75+
const clobTokenIds = market['info']['clobTokenIds'];
76+
77+
if (clobTokenIds && clobTokenIds.length > 0) {
78+
console.log ('Fetching order book for:', symbol);
79+
console.log ('Token ID:', clobTokenIds[0]);
80+
81+
// Fetch order book using the token ID
82+
const orderbook = await exchange.fetchOrderBook (symbol, undefined, {
83+
'token_id': clobTokenIds[0],
84+
});
85+
86+
console.log ('Order Book:');
87+
console.log (' Bids:', orderbook['bids'].length, 'levels');
88+
if (orderbook['bids'].length > 0) {
89+
console.log (' Best bid:', orderbook['bids'][0]);
90+
}
91+
console.log (' Asks:', orderbook['asks'].length, 'levels');
92+
if (orderbook['asks'].length > 0) {
93+
console.log (' Best ask:', orderbook['asks'][0]);
94+
}
95+
} else {
96+
console.log ('Market', symbol, 'does not have CLOB order book available');
97+
}
98+
}
99+
100+
// Example 3: Fetch all tickers
101+
console.log ('\n=== Fetching All Tickers ===\n');
102+
103+
console.log ('Fetching tickers for first 3 markets...');
104+
const symbolsToFetch = exchange.symbols.slice (0, 3);
105+
console.log ('Symbols to fetch:', symbolsToFetch);
106+
const tickers = await exchange.fetchTickers (symbolsToFetch);
107+
108+
console.log ('Fetched', Object.keys (tickers).length, 'tickers:');
109+
for (const symbol in tickers) {
110+
const ticker = tickers[symbol];
111+
console.log (' ', symbol, '- Last:', ticker['last'], 'Volume:', ticker['baseVolume']);
112+
}
113+
114+
// Example 4: Filter markets by criteria
115+
console.log ('\n=== Filtering Markets ===\n');
116+
117+
// Find markets with high volume
118+
const marketsWithVolume: string[] = [];
119+
for (let i = 0; i < exchange.symbols.length; i++) {
120+
const symbol = exchange.symbols[i];
121+
const volume = exchange.markets[symbol]['info']['volume'];
122+
if (volume && parseFloat (volume) > 10000) {
123+
marketsWithVolume.push (symbol);
124+
}
125+
}
126+
127+
console.log ('Markets with volume > 10,000:', marketsWithVolume.length);
128+
if (marketsWithVolume.length > 0) {
129+
console.log ('Examples:');
130+
for (let i = 0; i < Math.min (3, marketsWithVolume.length); i++) {
131+
const symbol = marketsWithVolume[i];
132+
const market = exchange.markets[symbol];
133+
console.log (' -', symbol, 'Volume:', market['info']['volume']);
134+
}
135+
}
136+
137+
// Example 5: Access market metadata
138+
console.log ('\n=== Market Metadata ===\n');
139+
140+
if (exchange.symbols.length > 0) {
141+
const symbol = exchange.symbols[0];
142+
const market = exchange.markets[symbol];
143+
const info = market['info'];
144+
145+
console.log ('Market:', symbol);
146+
console.log (' Question:', info['question']);
147+
console.log (' Category:', info['category']);
148+
console.log (' Active:', info['active']);
149+
console.log (' Closed:', info['closed']);
150+
console.log (' Outcomes:', info['outcomes']);
151+
if (info['outcomePrices']) {
152+
console.log (' Outcome Prices:', info['outcomePrices']);
153+
}
154+
if (info['clobTokenIds']) {
155+
console.log (' CLOB Token IDs:', info['clobTokenIds']);
156+
}
157+
if (info['endDateIso']) {
158+
console.log (' End Date:', info['endDateIso']);
159+
}
160+
if (info['liquidity']) {
161+
console.log (' Liquidity:', info['liquidity']);
162+
}
163+
}
164+
165+
// Example 6: Fetch trades for a market
166+
console.log ('\n=== Fetching Trades ===\n');
167+
168+
if (exchange.symbols.length > 0) {
169+
const symbol = exchange.symbols[0];
170+
const market = exchange.markets[symbol];
171+
const clobTokenIds = market['info']['clobTokenIds'];
172+
173+
if (clobTokenIds && clobTokenIds.length > 0) {
174+
console.log ('Fetching recent trades for:', symbol);
175+
console.log ('Token ID:', clobTokenIds[0]);
176+
177+
try {
178+
const trades = await exchange.fetchTrades (symbol, undefined, 5);
179+
console.log ('Fetched', trades.length, 'trades:');
180+
for (let i = 0; i < Math.min (5, trades.length); i++) {
181+
const trade = trades[i];
182+
console.log (' Trade ID:', trade['id'] || 'N/A');
183+
console.log (' Side:', trade['side'] || 'N/A');
184+
console.log (' Amount:', trade['amount'] || 'N/A');
185+
console.log (' Price:', trade['price'] || 'N/A');
186+
console.log (' Cost:', trade['cost'] || 'N/A');
187+
console.log (' Date:', trade['datetime'] || 'N/A');
188+
console.log ();
189+
}
190+
} catch (e) {
191+
console.log ('Error fetching trades:', e instanceof Error ? e.message : String (e));
192+
}
193+
} else {
194+
console.log ('Market', symbol, 'does not have CLOB token ID for trades');
195+
}
196+
}
197+
198+
// Example 7: Fetch trading fee for a market
199+
console.log ('\n=== Fetching Trading Fee ===\n');
200+
201+
if (exchange.symbols.length > 0) {
202+
const symbol = exchange.symbols[0];
203+
const market = exchange.markets[symbol];
204+
const clobTokenIds = market['info']['clobTokenIds'];
205+
206+
if (clobTokenIds && clobTokenIds.length > 0) {
207+
console.log ('Fetching trading fee for:', symbol);
208+
console.log ('Token ID:', clobTokenIds[0]);
209+
210+
try {
211+
const fee = await exchange.fetchTradingFee (symbol, {
212+
'token_id': clobTokenIds[0],
213+
});
214+
console.log ('Trading Fee:');
215+
console.log (' Symbol:', fee['symbol'] || 'N/A');
216+
console.log (' Maker Fee:', fee['maker'] || 'N/A');
217+
console.log (' Taker Fee:', fee['taker'] || 'N/A');
218+
console.log (' Percentage:', fee['percentage'] || 'N/A');
219+
} catch (e) {
220+
console.log ('Error fetching trading fee:', e instanceof Error ? e.message : String (e));
221+
}
222+
} else {
223+
console.log ('Market', symbol, 'does not have CLOB token ID for trading fee');
224+
}
225+
}
226+
227+
// Example 8: Fetch OHLCV (candlestick) data
228+
console.log ('\n=== Fetching OHLCV Data ===\n');
229+
230+
if (exchange.symbols.length > 0) {
231+
const symbol = exchange.symbols[0];
232+
const market = exchange.markets[symbol];
233+
const clobTokenIds = market['info']['clobTokenIds'];
234+
235+
if (clobTokenIds && clobTokenIds.length > 0) {
236+
console.log ('Fetching OHLCV data for:', symbol);
237+
console.log ('Token ID:', clobTokenIds[0]);
238+
239+
// Fetch OHLCV data (1 hour candles)
240+
const ohlcv = await exchange.fetchOHLCV (symbol, '1h', undefined, 10, {
241+
'token_id': clobTokenIds[0],
242+
});
243+
244+
console.log ('Fetched', ohlcv.length, 'candles:');
245+
for (let i = 0; i < Math.min (5, ohlcv.length); i++) {
246+
const candle = ohlcv[i];
247+
const timestamp = candle[0];
248+
const openPrice = candle[1];
249+
const high = candle[2];
250+
const low = candle[3];
251+
const close = candle[4];
252+
const volume = candle[5];
253+
console.log (` ${exchange.iso8601 (timestamp)}: O=${openPrice}, H=${high}, L=${low}, C=${close}, V=${volume}`);
254+
}
255+
} else {
256+
console.log ('Market', symbol, 'does not have CLOB token ID for OHLCV data');
257+
}
258+
}
259+
260+
// Example 9: Fetch user positions
261+
console.log ('\n=== Fetching User Positions ===\n');
262+
263+
const userAddress = '0x29c5fb6caaa7fc4235358dc79fcd0584162e2788';
264+
console.log ('Fetching positions for user:', userAddress);
265+
266+
try {
267+
const positions = await exchange.getUserPositions (userAddress);
268+
console.log ('Fetched', positions.length, 'positions');
269+
if (positions.length > 0) {
270+
console.log ('\nCurrent positions:');
271+
for (let i = 0; i < Math.min (5, positions.length); i++) {
272+
const position = positions[i];
273+
console.log (' Position:');
274+
console.log (' Asset:', position['asset'] || 'N/A');
275+
console.log (' Condition ID:', position['conditionId'] || 'N/A');
276+
console.log (' Size:', position['size'] || 'N/A');
277+
console.log (' Average Price:', position['avgPrice'] || 'N/A');
278+
console.log (' Current Price:', position['curPrice'] || 'N/A');
279+
console.log (' Current Value:', position['currentValue'] || 'N/A');
280+
console.log (' Initial Value:', position['initialValue'] || 'N/A');
281+
console.log (' Cash PnL:', position['cashPnl'] || 'N/A');
282+
console.log (' Percent PnL:', position['percentPnl'] || 'N/A');
283+
console.log (' Title:', position['title'] || 'N/A');
284+
console.log (' Outcome:', position['outcome'] || 'N/A');
285+
console.log (' Redeemable:', position['redeemable'] || false);
286+
console.log (' Mergeable:', position['mergeable'] || false);
287+
console.log ();
288+
}
289+
} else {
290+
console.log (' No positions found for this user');
291+
}
292+
} catch (e) {
293+
console.log ('Error fetching positions:', e instanceof Error ? e.message : String (e));
294+
}
295+
296+
// Example 10: Fetch user total value
297+
console.log ('\n=== Fetching User Total Value ===\n');
298+
299+
const userAddress2 = '0x29c5fb6caaa7fc4235358dc79fcd0584162e2788';
300+
console.log ('Fetching total value for user:', userAddress2);
301+
302+
try {
303+
const totalValueData = await exchange.getUserTotalValue (userAddress2);
304+
console.log ('Total Value:', totalValueData['value'] || 'N/A');
305+
} catch (e) {
306+
console.log ('Error fetching total value:', e instanceof Error ? e.message : String (e));
307+
}
308+
309+
// Example 11: Fetch open interest for a market
310+
console.log ('\n=== Fetching Open Interest ===\n');
311+
312+
if (exchange.symbols.length > 0) {
313+
const symbol = exchange.symbols[0];
314+
console.log ('Fetching open interest for:', symbol);
315+
try {
316+
const openInterest = await exchange.fetchOpenInterest (symbol);
317+
console.log ('Open Interest:');
318+
console.log (' Symbol:', openInterest['symbol'] || 'N/A');
319+
console.log (' Open Interest Amount:', openInterest['openInterestAmount'] || 'N/A');
320+
console.log (' Open Interest Value:', openInterest['openInterestValue'] || 'N/A');
321+
} catch (e) {
322+
console.log ('Error fetching open interest:', e instanceof Error ? e.message : String (e));
323+
}
324+
}
325+
326+
} catch (e) {
327+
const errorMessage = e instanceof Error ? e.message : String (e);
328+
console.log ('Error:', errorMessage);
329+
if (e instanceof NetworkError) {
330+
console.log ('Network error - please check your internet connection');
331+
} else if (e instanceof ExchangeError) {
332+
console.log ('Exchange error -', errorMessage);
333+
} else {
334+
console.log ('Unexpected error:', e);
335+
}
336+
} finally {
337+
await exchange.close ();
338+
}
339+
}
340+
341+
await example ();
342+

0 commit comments

Comments
 (0)