pmxt-core 2.23.0 → 2.25.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.
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/auth.js +42 -8
- package/dist/exchanges/polymarket/index.js +56 -19
- package/dist/exchanges/polymarket_us/config.d.ts +18 -0
- package/dist/exchanges/polymarket_us/config.js +22 -0
- package/dist/exchanges/polymarket_us/errors.d.ts +19 -0
- package/dist/exchanges/polymarket_us/errors.js +123 -0
- package/dist/exchanges/polymarket_us/errors.test.d.ts +1 -0
- package/dist/exchanges/polymarket_us/errors.test.js +54 -0
- package/dist/exchanges/polymarket_us/index.d.ts +90 -0
- package/dist/exchanges/polymarket_us/index.js +366 -0
- package/dist/exchanges/polymarket_us/index.test.d.ts +8 -0
- package/dist/exchanges/polymarket_us/index.test.js +237 -0
- package/dist/exchanges/polymarket_us/normalizer.d.ts +55 -0
- package/dist/exchanges/polymarket_us/normalizer.js +385 -0
- package/dist/exchanges/polymarket_us/normalizer.test.d.ts +1 -0
- package/dist/exchanges/polymarket_us/normalizer.test.js +224 -0
- package/dist/exchanges/polymarket_us/price.d.ts +94 -0
- package/dist/exchanges/polymarket_us/price.js +149 -0
- package/dist/exchanges/polymarket_us/price.test.d.ts +1 -0
- package/dist/exchanges/polymarket_us/price.test.js +131 -0
- package/dist/exchanges/polymarket_us/websocket.d.ts +39 -0
- package/dist/exchanges/polymarket_us/websocket.js +181 -0
- package/dist/exchanges/polymarket_us/websocket.test.d.ts +8 -0
- package/dist/exchanges/polymarket_us/websocket.test.js +162 -0
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/smarkets/api.d.ts +8067 -0
- package/dist/exchanges/smarkets/api.js +10698 -0
- package/dist/exchanges/smarkets/auth.d.ts +56 -0
- package/dist/exchanges/smarkets/auth.js +105 -0
- package/dist/exchanges/smarkets/config.d.ts +41 -0
- package/dist/exchanges/smarkets/config.js +47 -0
- package/dist/exchanges/smarkets/errors.d.ts +31 -0
- package/dist/exchanges/smarkets/errors.js +186 -0
- package/dist/exchanges/smarkets/fetcher.d.ts +177 -0
- package/dist/exchanges/smarkets/fetcher.js +342 -0
- package/dist/exchanges/smarkets/index.d.ts +54 -0
- package/dist/exchanges/smarkets/index.js +285 -0
- package/dist/exchanges/smarkets/normalizer.d.ts +18 -0
- package/dist/exchanges/smarkets/normalizer.js +267 -0
- package/dist/exchanges/smarkets/price.d.ts +26 -0
- package/dist/exchanges/smarkets/price.js +44 -0
- package/dist/exchanges/smarkets/price.test.d.ts +1 -0
- package/dist/exchanges/smarkets/price.test.js +50 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -1
- package/dist/server/app.js +18 -2
- package/package.json +4 -3
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { UnifiedMarket, UnifiedEvent, OrderBook, Trade, UserTrade, Position, Balance, Order } from '../../types';
|
|
2
|
+
import { IExchangeNormalizer } from '../interfaces';
|
|
3
|
+
import { SmarketsRawEventWithMarkets, SmarketsRawEvent, SmarketsRawMarket, SmarketsRawContract, SmarketsRawQuote, SmarketsRawActivityRow, SmarketsRawOrder, SmarketsRawVolume, SmarketsRawBalance } from './fetcher';
|
|
4
|
+
export declare class SmarketsNormalizer implements IExchangeNormalizer<SmarketsRawEventWithMarkets, SmarketsRawEventWithMarkets> {
|
|
5
|
+
normalizeMarket(raw: SmarketsRawEventWithMarkets): UnifiedMarket | null;
|
|
6
|
+
normalizeMarketsFromEvent(raw: SmarketsRawEventWithMarkets): UnifiedMarket[];
|
|
7
|
+
normalizeRawMarket(event: SmarketsRawEvent, market: SmarketsRawMarket, contracts: SmarketsRawContract[], volumes: SmarketsRawVolume[]): UnifiedMarket | null;
|
|
8
|
+
normalizeEvent(raw: SmarketsRawEventWithMarkets): UnifiedEvent | null;
|
|
9
|
+
normalizeOrderBook(raw: Record<string, SmarketsRawQuote>, _id: string): OrderBook;
|
|
10
|
+
normalizeActivityTrade(raw: SmarketsRawActivityRow, index: number): Trade;
|
|
11
|
+
normalizeActivityUserTrade(raw: SmarketsRawActivityRow, index: number): UserTrade;
|
|
12
|
+
normalizeOrder(raw: SmarketsRawOrder): Order;
|
|
13
|
+
normalizeCreateOrderResponse(raw: Record<string, any>): Order;
|
|
14
|
+
normalizePosition(raw: SmarketsRawOrder): Position;
|
|
15
|
+
normalizeBalance(raw: SmarketsRawBalance): Balance[];
|
|
16
|
+
private mapOrderStatus;
|
|
17
|
+
private mapOrderType;
|
|
18
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SmarketsNormalizer = void 0;
|
|
4
|
+
const market_utils_1 = require("../../utils/market-utils");
|
|
5
|
+
const price_1 = require("./price");
|
|
6
|
+
// ----------------------------------------------------------------------------
|
|
7
|
+
// Helpers
|
|
8
|
+
// ----------------------------------------------------------------------------
|
|
9
|
+
function extractEventCategory(event) {
|
|
10
|
+
const eventType = event.type;
|
|
11
|
+
if (typeof eventType === 'object' && eventType !== null) {
|
|
12
|
+
return eventType.domain;
|
|
13
|
+
}
|
|
14
|
+
if (typeof eventType === 'string') {
|
|
15
|
+
// e.g. "football_match" -> "football"
|
|
16
|
+
const parts = eventType.split('_');
|
|
17
|
+
if (parts.length >= 2) {
|
|
18
|
+
return parts.slice(0, -1).join('_');
|
|
19
|
+
}
|
|
20
|
+
return eventType;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
function buildEventUrl(event) {
|
|
25
|
+
if (event.full_slug) {
|
|
26
|
+
return `https://smarkets.com${event.full_slug}`;
|
|
27
|
+
}
|
|
28
|
+
return `https://smarkets.com/event/${event.id}/${event.slug}`;
|
|
29
|
+
}
|
|
30
|
+
function buildContractOutcome(contract, marketId) {
|
|
31
|
+
return {
|
|
32
|
+
outcomeId: contract.id,
|
|
33
|
+
marketId,
|
|
34
|
+
label: contract.name,
|
|
35
|
+
price: 0,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// ----------------------------------------------------------------------------
|
|
39
|
+
// Normalizer
|
|
40
|
+
// ----------------------------------------------------------------------------
|
|
41
|
+
class SmarketsNormalizer {
|
|
42
|
+
normalizeMarket(raw) {
|
|
43
|
+
if (!raw || !raw.markets || raw.markets.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
return this.normalizeRawMarket(raw.event, raw.markets[0], raw.contracts, raw.volumes);
|
|
46
|
+
}
|
|
47
|
+
normalizeMarketsFromEvent(raw) {
|
|
48
|
+
const results = [];
|
|
49
|
+
for (const market of raw.markets) {
|
|
50
|
+
const marketContracts = raw.contracts.filter(c => c.market_id === market.id);
|
|
51
|
+
const marketVolumes = raw.volumes.filter(v => v.market_id === market.id);
|
|
52
|
+
const um = this.normalizeRawMarket(raw.event, market, marketContracts, marketVolumes);
|
|
53
|
+
if (um)
|
|
54
|
+
results.push(um);
|
|
55
|
+
}
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
normalizeRawMarket(event, market, contracts, volumes) {
|
|
59
|
+
if (!market)
|
|
60
|
+
return null;
|
|
61
|
+
const marketContracts = contracts.filter(c => c.market_id === market.id);
|
|
62
|
+
const volume = volumes.find(v => v.market_id === market.id);
|
|
63
|
+
const outcomes = marketContracts.map(contract => buildContractOutcome(contract, market.id));
|
|
64
|
+
const category = extractEventCategory(event);
|
|
65
|
+
const tags = [];
|
|
66
|
+
if (category)
|
|
67
|
+
tags.push(category);
|
|
68
|
+
if (market.category && !tags.includes(market.category)) {
|
|
69
|
+
tags.push(market.category);
|
|
70
|
+
}
|
|
71
|
+
if (market.categories) {
|
|
72
|
+
for (const cat of market.categories) {
|
|
73
|
+
if (!tags.includes(cat))
|
|
74
|
+
tags.push(cat);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Derive resolution date from event end_date or start_datetime
|
|
78
|
+
const resolutionDate = event.end_date
|
|
79
|
+
? new Date(event.end_date)
|
|
80
|
+
: event.start_datetime
|
|
81
|
+
? new Date(event.start_datetime)
|
|
82
|
+
: new Date();
|
|
83
|
+
const um = {
|
|
84
|
+
marketId: market.id,
|
|
85
|
+
eventId: event.id,
|
|
86
|
+
title: event.name,
|
|
87
|
+
description: market.description || market.name || '',
|
|
88
|
+
slug: market.slug,
|
|
89
|
+
outcomes,
|
|
90
|
+
resolutionDate,
|
|
91
|
+
volume24h: 0, // Smarkets does not provide 24h volume separately
|
|
92
|
+
volume: volume ? (0, price_1.fromQuantityUnits)(volume.volume) : undefined,
|
|
93
|
+
liquidity: 0,
|
|
94
|
+
url: buildEventUrl(event),
|
|
95
|
+
category,
|
|
96
|
+
tags,
|
|
97
|
+
};
|
|
98
|
+
(0, market_utils_1.addBinaryOutcomes)(um);
|
|
99
|
+
return um;
|
|
100
|
+
}
|
|
101
|
+
normalizeEvent(raw) {
|
|
102
|
+
if (!raw || !raw.event)
|
|
103
|
+
return null;
|
|
104
|
+
const markets = this.normalizeMarketsFromEvent(raw);
|
|
105
|
+
const category = extractEventCategory(raw.event);
|
|
106
|
+
return {
|
|
107
|
+
id: raw.event.id,
|
|
108
|
+
title: raw.event.name,
|
|
109
|
+
description: raw.event.description || '',
|
|
110
|
+
slug: raw.event.slug,
|
|
111
|
+
markets,
|
|
112
|
+
volume24h: markets.reduce((sum, m) => sum + m.volume24h, 0),
|
|
113
|
+
volume: markets.some(m => m.volume !== undefined)
|
|
114
|
+
? markets.reduce((sum, m) => sum + (m.volume ?? 0), 0)
|
|
115
|
+
: undefined,
|
|
116
|
+
url: buildEventUrl(raw.event),
|
|
117
|
+
category,
|
|
118
|
+
tags: category ? [category] : [],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
normalizeOrderBook(raw, _id) {
|
|
122
|
+
const allBids = [];
|
|
123
|
+
const allAsks = [];
|
|
124
|
+
for (const contractId of Object.keys(raw)) {
|
|
125
|
+
const quote = raw[contractId];
|
|
126
|
+
if (!quote)
|
|
127
|
+
continue;
|
|
128
|
+
for (const bid of (quote.bids || [])) {
|
|
129
|
+
allBids.push({
|
|
130
|
+
price: (0, price_1.fromBasisPoints)(bid.price),
|
|
131
|
+
size: (0, price_1.fromQuantityUnits)(bid.quantity),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
for (const offer of (quote.offers || [])) {
|
|
135
|
+
allAsks.push({
|
|
136
|
+
price: (0, price_1.fromBasisPoints)(offer.price),
|
|
137
|
+
size: (0, price_1.fromQuantityUnits)(offer.quantity),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const sortedBids = [...allBids].sort((a, b) => b.price - a.price);
|
|
142
|
+
const sortedAsks = [...allAsks].sort((a, b) => a.price - b.price);
|
|
143
|
+
return {
|
|
144
|
+
bids: sortedBids,
|
|
145
|
+
asks: sortedAsks,
|
|
146
|
+
timestamp: Date.now(),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
normalizeActivityTrade(raw, index) {
|
|
150
|
+
const price = raw.price !== null ? (0, price_1.fromBasisPoints)(raw.price) : 0;
|
|
151
|
+
const amount = raw.quantity !== null ? (0, price_1.fromQuantityUnits)(raw.quantity) : 0;
|
|
152
|
+
let side = 'unknown';
|
|
153
|
+
if (raw.side === 'buy')
|
|
154
|
+
side = 'buy';
|
|
155
|
+
else if (raw.side === 'sell')
|
|
156
|
+
side = 'sell';
|
|
157
|
+
return {
|
|
158
|
+
id: `${raw.seq}-${raw.subseq}`,
|
|
159
|
+
timestamp: new Date(raw.timestamp).getTime(),
|
|
160
|
+
price,
|
|
161
|
+
amount,
|
|
162
|
+
side,
|
|
163
|
+
outcomeId: raw.contract_id || undefined,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
normalizeActivityUserTrade(raw, index) {
|
|
167
|
+
const trade = this.normalizeActivityTrade(raw, index);
|
|
168
|
+
return {
|
|
169
|
+
...trade,
|
|
170
|
+
orderId: raw.order_id || undefined,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
normalizeOrder(raw) {
|
|
174
|
+
return {
|
|
175
|
+
id: raw.id,
|
|
176
|
+
marketId: raw.market_id,
|
|
177
|
+
outcomeId: raw.contract_id,
|
|
178
|
+
side: raw.side === 'buy' ? 'buy' : 'sell',
|
|
179
|
+
type: this.mapOrderType(raw.type),
|
|
180
|
+
price: (0, price_1.fromBasisPoints)(raw.price),
|
|
181
|
+
amount: (0, price_1.fromQuantityUnits)(raw.quantity),
|
|
182
|
+
status: this.mapOrderStatus(raw.state),
|
|
183
|
+
filled: (0, price_1.fromQuantityUnits)(raw.quantity_filled),
|
|
184
|
+
remaining: (0, price_1.fromQuantityUnits)(raw.quantity_unfilled),
|
|
185
|
+
timestamp: new Date(raw.created_datetime).getTime(),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
normalizeCreateOrderResponse(raw) {
|
|
189
|
+
const totalExecuted = raw.total_executed_quantity || 0;
|
|
190
|
+
const availableQty = raw.available_quantity || 0;
|
|
191
|
+
const quantity = raw.quantity || (totalExecuted + availableQty);
|
|
192
|
+
let status = 'open';
|
|
193
|
+
if (totalExecuted > 0 && availableQty === 0) {
|
|
194
|
+
status = 'filled';
|
|
195
|
+
}
|
|
196
|
+
else if (totalExecuted > 0) {
|
|
197
|
+
status = 'open';
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
status = 'pending';
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
id: raw.order_id,
|
|
204
|
+
marketId: raw.market_id,
|
|
205
|
+
outcomeId: raw.contract_id,
|
|
206
|
+
side: raw.side === 'buy' ? 'buy' : 'sell',
|
|
207
|
+
type: 'limit',
|
|
208
|
+
price: (0, price_1.fromBasisPoints)(raw.price),
|
|
209
|
+
amount: (0, price_1.fromQuantityUnits)(quantity),
|
|
210
|
+
status,
|
|
211
|
+
filled: (0, price_1.fromQuantityUnits)(totalExecuted),
|
|
212
|
+
remaining: (0, price_1.fromQuantityUnits)(availableQty),
|
|
213
|
+
timestamp: Date.now(),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
normalizePosition(raw) {
|
|
217
|
+
const size = (0, price_1.fromQuantityUnits)(raw.quantity_filled);
|
|
218
|
+
const entryPrice = raw.average_price_matched
|
|
219
|
+
? (0, price_1.fromBasisPoints)(raw.average_price_matched)
|
|
220
|
+
: (0, price_1.fromBasisPoints)(raw.price);
|
|
221
|
+
return {
|
|
222
|
+
marketId: raw.market_id,
|
|
223
|
+
outcomeId: raw.contract_id,
|
|
224
|
+
outcomeLabel: raw.contract_id,
|
|
225
|
+
size: raw.side === 'buy' ? size : -size,
|
|
226
|
+
entryPrice,
|
|
227
|
+
currentPrice: entryPrice,
|
|
228
|
+
unrealizedPnL: 0,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
normalizeBalance(raw) {
|
|
232
|
+
const balance = parseFloat(raw.balance || '0');
|
|
233
|
+
const available = parseFloat(raw.available_balance || '0');
|
|
234
|
+
return [{
|
|
235
|
+
currency: raw.currency || 'GBP',
|
|
236
|
+
total: balance,
|
|
237
|
+
available,
|
|
238
|
+
locked: balance - available,
|
|
239
|
+
}];
|
|
240
|
+
}
|
|
241
|
+
// -- Private helpers ------------------------------------------------------
|
|
242
|
+
mapOrderStatus(state) {
|
|
243
|
+
switch (state) {
|
|
244
|
+
case 'created':
|
|
245
|
+
return 'pending';
|
|
246
|
+
case 'partial':
|
|
247
|
+
return 'open';
|
|
248
|
+
case 'filled':
|
|
249
|
+
case 'settled':
|
|
250
|
+
return 'filled';
|
|
251
|
+
default:
|
|
252
|
+
return 'open';
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
mapOrderType(type) {
|
|
256
|
+
switch (type) {
|
|
257
|
+
case 'immediate_or_cancel':
|
|
258
|
+
return 'market';
|
|
259
|
+
case 'good_til_cancelled':
|
|
260
|
+
case 'good_til_halted':
|
|
261
|
+
case 'keep_in_play':
|
|
262
|
+
default:
|
|
263
|
+
return 'limit';
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.SmarketsNormalizer = SmarketsNormalizer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smarkets price and quantity conversion utilities.
|
|
3
|
+
*
|
|
4
|
+
* Smarkets uses percentage basis points (0-10000) for prices
|
|
5
|
+
* and 1/10000 GBP units for quantities.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Convert Smarkets basis points (0-10000) to probability (0.0-1.0).
|
|
9
|
+
*/
|
|
10
|
+
export declare function fromBasisPoints(basisPoints: number): number;
|
|
11
|
+
/**
|
|
12
|
+
* Convert probability (0.0-1.0) to Smarkets basis points (0-10000).
|
|
13
|
+
*/
|
|
14
|
+
export declare function toBasisPoints(probability: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* Convert Smarkets quantity units (1/10000 GBP) to GBP.
|
|
17
|
+
*/
|
|
18
|
+
export declare function fromQuantityUnits(units: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Convert GBP to Smarkets quantity units (1/10000 GBP).
|
|
21
|
+
*/
|
|
22
|
+
export declare function toQuantityUnits(gbp: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get the complement probability (for binary markets: No = 1 - Yes).
|
|
25
|
+
*/
|
|
26
|
+
export declare function invertProbability(price: number): number;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Smarkets price and quantity conversion utilities.
|
|
4
|
+
*
|
|
5
|
+
* Smarkets uses percentage basis points (0-10000) for prices
|
|
6
|
+
* and 1/10000 GBP units for quantities.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.fromBasisPoints = fromBasisPoints;
|
|
10
|
+
exports.toBasisPoints = toBasisPoints;
|
|
11
|
+
exports.fromQuantityUnits = fromQuantityUnits;
|
|
12
|
+
exports.toQuantityUnits = toQuantityUnits;
|
|
13
|
+
exports.invertProbability = invertProbability;
|
|
14
|
+
const BASIS_POINTS_SCALE = 10000;
|
|
15
|
+
/**
|
|
16
|
+
* Convert Smarkets basis points (0-10000) to probability (0.0-1.0).
|
|
17
|
+
*/
|
|
18
|
+
function fromBasisPoints(basisPoints) {
|
|
19
|
+
return basisPoints / BASIS_POINTS_SCALE;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Convert probability (0.0-1.0) to Smarkets basis points (0-10000).
|
|
23
|
+
*/
|
|
24
|
+
function toBasisPoints(probability) {
|
|
25
|
+
return Math.round(probability * BASIS_POINTS_SCALE);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Convert Smarkets quantity units (1/10000 GBP) to GBP.
|
|
29
|
+
*/
|
|
30
|
+
function fromQuantityUnits(units) {
|
|
31
|
+
return units / BASIS_POINTS_SCALE;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Convert GBP to Smarkets quantity units (1/10000 GBP).
|
|
35
|
+
*/
|
|
36
|
+
function toQuantityUnits(gbp) {
|
|
37
|
+
return Math.round(gbp * BASIS_POINTS_SCALE);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the complement probability (for binary markets: No = 1 - Yes).
|
|
41
|
+
*/
|
|
42
|
+
function invertProbability(price) {
|
|
43
|
+
return 1 - price;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const price_1 = require("./price");
|
|
4
|
+
describe('Smarkets price conversions', () => {
|
|
5
|
+
describe('fromBasisPoints', () => {
|
|
6
|
+
test('converts basis points to a probability', () => {
|
|
7
|
+
expect((0, price_1.fromBasisPoints)(0)).toBe(0);
|
|
8
|
+
expect((0, price_1.fromBasisPoints)(5500)).toBe(0.55);
|
|
9
|
+
expect((0, price_1.fromBasisPoints)(10000)).toBe(1);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('toBasisPoints', () => {
|
|
13
|
+
test('converts a probability to basis points', () => {
|
|
14
|
+
expect((0, price_1.toBasisPoints)(0)).toBe(0);
|
|
15
|
+
expect((0, price_1.toBasisPoints)(0.55)).toBe(5500);
|
|
16
|
+
expect((0, price_1.toBasisPoints)(1)).toBe(10000);
|
|
17
|
+
});
|
|
18
|
+
test('rounds non-integer results', () => {
|
|
19
|
+
expect((0, price_1.toBasisPoints)(0.12345)).toBe(1235);
|
|
20
|
+
});
|
|
21
|
+
test('round-trips with fromBasisPoints', () => {
|
|
22
|
+
const bp = (0, price_1.toBasisPoints)(0.42);
|
|
23
|
+
expect((0, price_1.fromBasisPoints)(bp)).toBeCloseTo(0.42);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('fromQuantityUnits', () => {
|
|
27
|
+
test('converts quantity units to GBP', () => {
|
|
28
|
+
expect((0, price_1.fromQuantityUnits)(0)).toBe(0);
|
|
29
|
+
expect((0, price_1.fromQuantityUnits)(10000)).toBe(1);
|
|
30
|
+
expect((0, price_1.fromQuantityUnits)(25000)).toBe(2.5);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('toQuantityUnits', () => {
|
|
34
|
+
test('converts GBP to quantity units', () => {
|
|
35
|
+
expect((0, price_1.toQuantityUnits)(0)).toBe(0);
|
|
36
|
+
expect((0, price_1.toQuantityUnits)(1)).toBe(10000);
|
|
37
|
+
expect((0, price_1.toQuantityUnits)(2.5)).toBe(25000);
|
|
38
|
+
});
|
|
39
|
+
test('rounds fractional units', () => {
|
|
40
|
+
expect((0, price_1.toQuantityUnits)(0.123456)).toBe(1235);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('invertProbability', () => {
|
|
44
|
+
test('returns the complement of a probability', () => {
|
|
45
|
+
expect((0, price_1.invertProbability)(0)).toBe(1);
|
|
46
|
+
expect((0, price_1.invertProbability)(1)).toBe(0);
|
|
47
|
+
expect((0, price_1.invertProbability)(0.3)).toBeCloseTo(0.7);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export * from './exchanges/baozi';
|
|
|
12
12
|
export * from './exchanges/myriad';
|
|
13
13
|
export * from './exchanges/opinion';
|
|
14
14
|
export * from './exchanges/metaculus';
|
|
15
|
+
export * from './exchanges/smarkets';
|
|
16
|
+
export * from './exchanges/polymarket_us';
|
|
15
17
|
export * from './server/app';
|
|
16
18
|
export * from './server/utils/port-manager';
|
|
17
19
|
export * from './server/utils/lock-file';
|
|
@@ -24,6 +26,8 @@ import { BaoziExchange } from './exchanges/baozi';
|
|
|
24
26
|
import { MyriadExchange } from './exchanges/myriad';
|
|
25
27
|
import { OpinionExchange } from './exchanges/opinion';
|
|
26
28
|
import { MetaculusExchange } from './exchanges/metaculus';
|
|
29
|
+
import { SmarketsExchange } from './exchanges/smarkets';
|
|
30
|
+
import { PolymarketUSExchange } from './exchanges/polymarket_us';
|
|
27
31
|
declare const pmxt: {
|
|
28
32
|
Polymarket: typeof PolymarketExchange;
|
|
29
33
|
Limitless: typeof LimitlessExchange;
|
|
@@ -34,6 +38,8 @@ declare const pmxt: {
|
|
|
34
38
|
Myriad: typeof MyriadExchange;
|
|
35
39
|
Opinion: typeof OpinionExchange;
|
|
36
40
|
Metaculus: typeof MetaculusExchange;
|
|
41
|
+
Smarkets: typeof SmarketsExchange;
|
|
42
|
+
PolymarketUS: typeof PolymarketUSExchange;
|
|
37
43
|
};
|
|
38
44
|
export declare const Polymarket: typeof PolymarketExchange;
|
|
39
45
|
export declare const Limitless: typeof LimitlessExchange;
|
|
@@ -44,4 +50,6 @@ export declare const Baozi: typeof BaoziExchange;
|
|
|
44
50
|
export declare const Myriad: typeof MyriadExchange;
|
|
45
51
|
export declare const Opinion: typeof OpinionExchange;
|
|
46
52
|
export declare const Metaculus: typeof MetaculusExchange;
|
|
53
|
+
export declare const Smarkets: typeof SmarketsExchange;
|
|
54
|
+
export declare const PolymarketUS: typeof PolymarketUSExchange;
|
|
47
55
|
export default pmxt;
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.Metaculus = exports.Opinion = exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
|
|
17
|
+
exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
|
|
18
18
|
__exportStar(require("./BaseExchange"), exports);
|
|
19
19
|
__exportStar(require("./types"), exports);
|
|
20
20
|
__exportStar(require("./utils/math"), exports);
|
|
@@ -30,6 +30,8 @@ __exportStar(require("./exchanges/baozi"), exports);
|
|
|
30
30
|
__exportStar(require("./exchanges/myriad"), exports);
|
|
31
31
|
__exportStar(require("./exchanges/opinion"), exports);
|
|
32
32
|
__exportStar(require("./exchanges/metaculus"), exports);
|
|
33
|
+
__exportStar(require("./exchanges/smarkets"), exports);
|
|
34
|
+
__exportStar(require("./exchanges/polymarket_us"), exports);
|
|
33
35
|
__exportStar(require("./server/app"), exports);
|
|
34
36
|
__exportStar(require("./server/utils/port-manager"), exports);
|
|
35
37
|
__exportStar(require("./server/utils/lock-file"), exports);
|
|
@@ -42,6 +44,8 @@ const baozi_1 = require("./exchanges/baozi");
|
|
|
42
44
|
const myriad_1 = require("./exchanges/myriad");
|
|
43
45
|
const opinion_1 = require("./exchanges/opinion");
|
|
44
46
|
const metaculus_1 = require("./exchanges/metaculus");
|
|
47
|
+
const smarkets_1 = require("./exchanges/smarkets");
|
|
48
|
+
const polymarket_us_1 = require("./exchanges/polymarket_us");
|
|
45
49
|
const pmxt = {
|
|
46
50
|
Polymarket: polymarket_1.PolymarketExchange,
|
|
47
51
|
Limitless: limitless_1.LimitlessExchange,
|
|
@@ -52,6 +56,8 @@ const pmxt = {
|
|
|
52
56
|
Myriad: myriad_1.MyriadExchange,
|
|
53
57
|
Opinion: opinion_1.OpinionExchange,
|
|
54
58
|
Metaculus: metaculus_1.MetaculusExchange,
|
|
59
|
+
Smarkets: smarkets_1.SmarketsExchange,
|
|
60
|
+
PolymarketUS: polymarket_us_1.PolymarketUSExchange,
|
|
55
61
|
};
|
|
56
62
|
exports.Polymarket = polymarket_1.PolymarketExchange;
|
|
57
63
|
exports.Limitless = limitless_1.LimitlessExchange;
|
|
@@ -62,4 +68,6 @@ exports.Baozi = baozi_1.BaoziExchange;
|
|
|
62
68
|
exports.Myriad = myriad_1.MyriadExchange;
|
|
63
69
|
exports.Opinion = opinion_1.OpinionExchange;
|
|
64
70
|
exports.Metaculus = metaculus_1.MetaculusExchange;
|
|
71
|
+
exports.Smarkets = smarkets_1.SmarketsExchange;
|
|
72
|
+
exports.PolymarketUS = polymarket_us_1.PolymarketUSExchange;
|
|
65
73
|
exports.default = pmxt;
|
package/dist/server/app.js
CHANGED
|
@@ -15,6 +15,8 @@ const baozi_1 = require("../exchanges/baozi");
|
|
|
15
15
|
const myriad_1 = require("../exchanges/myriad");
|
|
16
16
|
const opinion_1 = require("../exchanges/opinion");
|
|
17
17
|
const metaculus_1 = require("../exchanges/metaculus");
|
|
18
|
+
const smarkets_1 = require("../exchanges/smarkets");
|
|
19
|
+
const polymarket_us_1 = require("../exchanges/polymarket_us");
|
|
18
20
|
const errors_1 = require("../errors");
|
|
19
21
|
// Singleton instances for local usage (when no credentials provided)
|
|
20
22
|
const defaultExchanges = {
|
|
@@ -27,6 +29,7 @@ const defaultExchanges = {
|
|
|
27
29
|
myriad: null,
|
|
28
30
|
opinion: null,
|
|
29
31
|
metaculus: null,
|
|
32
|
+
smarkets: null,
|
|
30
33
|
};
|
|
31
34
|
async function startServer(port, accessToken) {
|
|
32
35
|
const app = (0, express_1.default)();
|
|
@@ -148,8 +151,11 @@ function createExchange(name, credentials) {
|
|
|
148
151
|
apiKey: credentials?.apiKey || process.env.POLYMARKET_API_KEY,
|
|
149
152
|
apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
|
|
150
153
|
passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE,
|
|
151
|
-
funderAddress: credentials?.funderAddress
|
|
152
|
-
|
|
154
|
+
funderAddress: credentials?.funderAddress ||
|
|
155
|
+
process.env.POLYMARKET_FUNDER_ADDRESS ||
|
|
156
|
+
process.env.POLYMARKET_PROXY_ADDRESS,
|
|
157
|
+
signatureType: credentials?.signatureType ||
|
|
158
|
+
process.env.POLYMARKET_SIGNATURE_TYPE,
|
|
153
159
|
});
|
|
154
160
|
case "limitless":
|
|
155
161
|
return new limitless_1.LimitlessExchange({
|
|
@@ -202,6 +208,16 @@ function createExchange(name, credentials) {
|
|
|
202
208
|
return new metaculus_1.MetaculusExchange({
|
|
203
209
|
apiToken: credentials?.apiToken || process.env.METACULUS_API_TOKEN,
|
|
204
210
|
});
|
|
211
|
+
case "smarkets":
|
|
212
|
+
return new smarkets_1.SmarketsExchange({
|
|
213
|
+
apiKey: credentials?.apiKey || process.env.SMARKETS_EMAIL,
|
|
214
|
+
privateKey: credentials?.privateKey || process.env.SMARKETS_PASSWORD,
|
|
215
|
+
});
|
|
216
|
+
case "polymarket_us":
|
|
217
|
+
return new polymarket_us_1.PolymarketUSExchange({
|
|
218
|
+
apiKey: credentials?.apiKey || process.env.POLYMARKET_US_KEY_ID,
|
|
219
|
+
privateKey: credentials?.privateKey || process.env.POLYMARKET_US_SECRET_KEY,
|
|
220
|
+
});
|
|
205
221
|
default:
|
|
206
222
|
throw new Error(`Unknown exchange: ${name}`);
|
|
207
223
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.0",
|
|
4
4
|
"description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test": "jest -c jest.config.js",
|
|
30
30
|
"server": "tsx watch src/server/index.ts",
|
|
31
31
|
"server:prod": "node dist/server/index.js",
|
|
32
|
-
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.
|
|
33
|
-
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.
|
|
32
|
+
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.25.0,library=urllib3",
|
|
33
|
+
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.25.0,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
34
|
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
35
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
36
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"express": "^5.2.1",
|
|
59
59
|
"isows": "^1.0.6",
|
|
60
60
|
"jest": "^30.2.0",
|
|
61
|
+
"polymarket-us": "0.1.1",
|
|
61
62
|
"tsx": "^4.21.0",
|
|
62
63
|
"ws": "^8.18.0"
|
|
63
64
|
},
|