pmxt-core 2.5.0 → 2.7.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/BaseExchange.d.ts +20 -0
- package/dist/BaseExchange.js +52 -0
- package/dist/exchanges/baozi/index.d.ts +15 -0
- package/dist/exchanges/baozi/index.js +15 -0
- package/dist/exchanges/kalshi/fetchEvents.d.ts +2 -1
- package/dist/exchanges/kalshi/fetchEvents.js +6 -6
- package/dist/exchanges/kalshi/fetchMarkets.d.ts +2 -1
- package/dist/exchanges/kalshi/fetchMarkets.js +19 -21
- package/dist/exchanges/kalshi/fetchOHLCV.d.ts +2 -1
- package/dist/exchanges/kalshi/fetchOHLCV.js +2 -2
- package/dist/exchanges/kalshi/fetchOrderBook.d.ts +2 -1
- package/dist/exchanges/kalshi/fetchOrderBook.js +2 -2
- package/dist/exchanges/kalshi/fetchTrades.d.ts +2 -1
- package/dist/exchanges/kalshi/fetchTrades.js +2 -2
- package/dist/exchanges/kalshi/index.d.ts +15 -0
- package/dist/exchanges/kalshi/index.js +26 -15
- package/dist/exchanges/kalshi/kalshi.test.js +47 -18
- package/dist/exchanges/limitless/fetchEvents.d.ts +2 -1
- package/dist/exchanges/limitless/fetchEvents.js +6 -4
- package/dist/exchanges/limitless/fetchMarkets.d.ts +2 -1
- package/dist/exchanges/limitless/fetchMarkets.js +4 -4
- package/dist/exchanges/limitless/fetchOHLCV.d.ts +2 -1
- package/dist/exchanges/limitless/fetchOHLCV.js +2 -2
- package/dist/exchanges/limitless/fetchOrderBook.d.ts +2 -1
- package/dist/exchanges/limitless/fetchOrderBook.js +2 -2
- package/dist/exchanges/limitless/fetchTrades.d.ts +2 -1
- package/dist/exchanges/limitless/fetchTrades.js +5 -1
- package/dist/exchanges/limitless/index.d.ts +15 -0
- package/dist/exchanges/limitless/index.js +20 -5
- package/dist/exchanges/myriad/fetchEvents.d.ts +2 -1
- package/dist/exchanges/myriad/fetchEvents.js +6 -6
- package/dist/exchanges/myriad/fetchMarkets.d.ts +2 -1
- package/dist/exchanges/myriad/fetchMarkets.js +10 -10
- package/dist/exchanges/myriad/fetchOHLCV.d.ts +2 -1
- package/dist/exchanges/myriad/fetchOHLCV.js +2 -2
- package/dist/exchanges/myriad/fetchOrderBook.d.ts +2 -1
- package/dist/exchanges/myriad/fetchOrderBook.js +2 -2
- package/dist/exchanges/myriad/fetchTrades.d.ts +2 -1
- package/dist/exchanges/myriad/fetchTrades.js +2 -2
- package/dist/exchanges/myriad/index.d.ts +15 -0
- package/dist/exchanges/myriad/index.js +23 -12
- package/dist/exchanges/polymarket/fetchEvents.d.ts +2 -1
- package/dist/exchanges/polymarket/fetchEvents.js +8 -8
- package/dist/exchanges/polymarket/fetchMarkets.d.ts +2 -1
- package/dist/exchanges/polymarket/fetchMarkets.js +17 -17
- package/dist/exchanges/polymarket/fetchOHLCV.d.ts +2 -1
- package/dist/exchanges/polymarket/fetchOHLCV.js +2 -2
- package/dist/exchanges/polymarket/fetchOrderBook.d.ts +2 -1
- package/dist/exchanges/polymarket/fetchOrderBook.js +2 -2
- package/dist/exchanges/polymarket/fetchTrades.d.ts +2 -1
- package/dist/exchanges/polymarket/fetchTrades.js +2 -2
- package/dist/exchanges/polymarket/index.d.ts +15 -0
- package/dist/exchanges/polymarket/index.js +20 -5
- package/dist/exchanges/polymarket/utils.d.ts +2 -2
- package/dist/exchanges/polymarket/utils.js +7 -42
- package/dist/exchanges/probable/fetchEvents.d.ts +4 -3
- package/dist/exchanges/probable/fetchEvents.js +13 -13
- package/dist/exchanges/probable/fetchMarkets.d.ts +2 -1
- package/dist/exchanges/probable/fetchMarkets.js +16 -16
- package/dist/exchanges/probable/fetchOHLCV.d.ts +2 -1
- package/dist/exchanges/probable/fetchOHLCV.js +2 -2
- package/dist/exchanges/probable/fetchOrderBook.d.ts +2 -1
- package/dist/exchanges/probable/fetchOrderBook.js +2 -2
- package/dist/exchanges/probable/fetchTrades.d.ts +2 -2
- package/dist/exchanges/probable/fetchTrades.js +5 -1
- package/dist/exchanges/probable/index.d.ts +15 -0
- package/dist/exchanges/probable/index.js +22 -7
- package/dist/server/app.js +23 -0
- package/package.json +4 -4
package/dist/BaseExchange.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { UnifiedMarket, UnifiedEvent, PriceCandle, CandleInterval, OrderBook, Trade, Order, Position, Balance, CreateOrderParams } from './types';
|
|
2
2
|
import { ExecutionPriceResult } from './utils/math';
|
|
3
|
+
import { AxiosInstance } from 'axios';
|
|
3
4
|
export interface MarketFilterParams {
|
|
4
5
|
limit?: number;
|
|
5
6
|
offset?: number;
|
|
@@ -94,6 +95,22 @@ export type EventFilterCriteria = {
|
|
|
94
95
|
};
|
|
95
96
|
};
|
|
96
97
|
export type EventFilterFunction = (event: UnifiedEvent) => boolean;
|
|
98
|
+
export type ExchangeCapability = true | false | 'emulated';
|
|
99
|
+
export interface ExchangeHas {
|
|
100
|
+
fetchMarkets: ExchangeCapability;
|
|
101
|
+
fetchEvents: ExchangeCapability;
|
|
102
|
+
fetchOHLCV: ExchangeCapability;
|
|
103
|
+
fetchOrderBook: ExchangeCapability;
|
|
104
|
+
fetchTrades: ExchangeCapability;
|
|
105
|
+
createOrder: ExchangeCapability;
|
|
106
|
+
cancelOrder: ExchangeCapability;
|
|
107
|
+
fetchOrder: ExchangeCapability;
|
|
108
|
+
fetchOpenOrders: ExchangeCapability;
|
|
109
|
+
fetchPositions: ExchangeCapability;
|
|
110
|
+
fetchBalance: ExchangeCapability;
|
|
111
|
+
watchOrderBook: ExchangeCapability;
|
|
112
|
+
watchTrades: ExchangeCapability;
|
|
113
|
+
}
|
|
97
114
|
export interface ExchangeCredentials {
|
|
98
115
|
apiKey?: string;
|
|
99
116
|
apiSecret?: string;
|
|
@@ -104,6 +121,9 @@ export interface ExchangeCredentials {
|
|
|
104
121
|
}
|
|
105
122
|
export declare abstract class PredictionMarketExchange {
|
|
106
123
|
protected credentials?: ExchangeCredentials;
|
|
124
|
+
verbose: boolean;
|
|
125
|
+
http: AxiosInstance;
|
|
126
|
+
readonly has: ExchangeHas;
|
|
107
127
|
constructor(credentials?: ExchangeCredentials);
|
|
108
128
|
abstract get name(): string;
|
|
109
129
|
/**
|
package/dist/BaseExchange.js
CHANGED
|
@@ -1,15 +1,67 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.PredictionMarketExchange = void 0;
|
|
4
7
|
const math_1 = require("./utils/math");
|
|
5
8
|
const errors_1 = require("./errors");
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
6
10
|
// ----------------------------------------------------------------------------
|
|
7
11
|
// Base Exchange Class
|
|
8
12
|
// ----------------------------------------------------------------------------
|
|
9
13
|
class PredictionMarketExchange {
|
|
10
14
|
credentials;
|
|
15
|
+
verbose = false;
|
|
16
|
+
http;
|
|
17
|
+
has = {
|
|
18
|
+
fetchMarkets: false,
|
|
19
|
+
fetchEvents: false,
|
|
20
|
+
fetchOHLCV: false,
|
|
21
|
+
fetchOrderBook: false,
|
|
22
|
+
fetchTrades: false,
|
|
23
|
+
createOrder: false,
|
|
24
|
+
cancelOrder: false,
|
|
25
|
+
fetchOrder: false,
|
|
26
|
+
fetchOpenOrders: false,
|
|
27
|
+
fetchPositions: false,
|
|
28
|
+
fetchBalance: false,
|
|
29
|
+
watchOrderBook: false,
|
|
30
|
+
watchTrades: false,
|
|
31
|
+
};
|
|
11
32
|
constructor(credentials) {
|
|
12
33
|
this.credentials = credentials;
|
|
34
|
+
this.http = axios_1.default.create();
|
|
35
|
+
// Request Interceptor
|
|
36
|
+
this.http.interceptors.request.use((config) => {
|
|
37
|
+
if (this.verbose) {
|
|
38
|
+
console.log(`\n[pmxt] → ${config.method?.toUpperCase()} ${config.url}`);
|
|
39
|
+
if (config.params)
|
|
40
|
+
console.log('[pmxt] params:', config.params);
|
|
41
|
+
if (config.data)
|
|
42
|
+
console.log('[pmxt] body:', JSON.stringify(config.data, null, 2));
|
|
43
|
+
}
|
|
44
|
+
return config;
|
|
45
|
+
});
|
|
46
|
+
// Response Interceptor
|
|
47
|
+
this.http.interceptors.response.use((response) => {
|
|
48
|
+
if (this.verbose) {
|
|
49
|
+
console.log(`\n[pmxt] ← ${response.status} ${response.statusText} ${response.config.url}`);
|
|
50
|
+
// console.log('[pmxt] response:', JSON.stringify(response.data, null, 2));
|
|
51
|
+
// Commented out full body log to avoid spam, but headers might be useful
|
|
52
|
+
}
|
|
53
|
+
return response;
|
|
54
|
+
}, (error) => {
|
|
55
|
+
if (this.verbose) {
|
|
56
|
+
console.log(`\n[pmxt] ✖ REQUEST FAILED: ${error.config?.url}`);
|
|
57
|
+
console.log('[pmxt] error:', error.message);
|
|
58
|
+
if (error.response) {
|
|
59
|
+
console.log('[pmxt] status:', error.response.status);
|
|
60
|
+
console.log('[pmxt] data:', JSON.stringify(error.response.data, null, 2));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return Promise.reject(error);
|
|
64
|
+
});
|
|
13
65
|
}
|
|
14
66
|
/**
|
|
15
67
|
* Fetch markets with optional filtering, search, or slug lookup.
|
|
@@ -5,6 +5,21 @@ export interface BaoziExchangeOptions {
|
|
|
5
5
|
rpcUrl?: string;
|
|
6
6
|
}
|
|
7
7
|
export declare class BaoziExchange extends PredictionMarketExchange {
|
|
8
|
+
readonly has: {
|
|
9
|
+
fetchMarkets: true;
|
|
10
|
+
fetchEvents: true;
|
|
11
|
+
fetchOHLCV: "emulated";
|
|
12
|
+
fetchOrderBook: "emulated";
|
|
13
|
+
fetchTrades: "emulated";
|
|
14
|
+
createOrder: true;
|
|
15
|
+
cancelOrder: false;
|
|
16
|
+
fetchOrder: true;
|
|
17
|
+
fetchOpenOrders: "emulated";
|
|
18
|
+
fetchPositions: true;
|
|
19
|
+
fetchBalance: true;
|
|
20
|
+
watchOrderBook: true;
|
|
21
|
+
watchTrades: false;
|
|
22
|
+
};
|
|
8
23
|
private auth?;
|
|
9
24
|
private connection;
|
|
10
25
|
private ws?;
|
|
@@ -14,6 +14,21 @@ const websocket_1 = require("./websocket");
|
|
|
14
14
|
const errors_2 = require("./errors");
|
|
15
15
|
const utils_1 = require("./utils");
|
|
16
16
|
class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
17
|
+
has = {
|
|
18
|
+
fetchMarkets: true,
|
|
19
|
+
fetchEvents: true,
|
|
20
|
+
fetchOHLCV: 'emulated',
|
|
21
|
+
fetchOrderBook: 'emulated',
|
|
22
|
+
fetchTrades: 'emulated',
|
|
23
|
+
createOrder: true,
|
|
24
|
+
cancelOrder: false,
|
|
25
|
+
fetchOrder: true,
|
|
26
|
+
fetchOpenOrders: 'emulated',
|
|
27
|
+
fetchPositions: true,
|
|
28
|
+
fetchBalance: true,
|
|
29
|
+
watchOrderBook: true,
|
|
30
|
+
watchTrades: false,
|
|
31
|
+
};
|
|
17
32
|
auth;
|
|
18
33
|
connection;
|
|
19
34
|
ws;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { EventFetchParams } from '../../BaseExchange';
|
|
2
2
|
import { UnifiedEvent } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { AxiosInstance } from 'axios';
|
|
4
|
+
export declare function fetchEvents(params: EventFetchParams, http?: AxiosInstance): Promise<UnifiedEvent[]>;
|
|
@@ -7,10 +7,10 @@ exports.fetchEvents = fetchEvents;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const utils_1 = require("./utils");
|
|
9
9
|
const errors_1 = require("./errors");
|
|
10
|
-
async function fetchEventByTicker(eventTicker) {
|
|
10
|
+
async function fetchEventByTicker(eventTicker, http) {
|
|
11
11
|
const normalizedTicker = eventTicker.toUpperCase();
|
|
12
12
|
const url = `https://api.elections.kalshi.com/trade-api/v2/events/${normalizedTicker}`;
|
|
13
|
-
const response = await
|
|
13
|
+
const response = await http.get(url, {
|
|
14
14
|
params: { with_nested_markets: true }
|
|
15
15
|
});
|
|
16
16
|
const event = response.data.event;
|
|
@@ -38,15 +38,15 @@ async function fetchEventByTicker(eventTicker) {
|
|
|
38
38
|
};
|
|
39
39
|
return [unifiedEvent];
|
|
40
40
|
}
|
|
41
|
-
async function fetchEvents(params) {
|
|
41
|
+
async function fetchEvents(params, http = axios_1.default) {
|
|
42
42
|
try {
|
|
43
43
|
// Handle eventId lookup (direct API call)
|
|
44
44
|
if (params.eventId) {
|
|
45
|
-
return await fetchEventByTicker(params.eventId);
|
|
45
|
+
return await fetchEventByTicker(params.eventId, http);
|
|
46
46
|
}
|
|
47
47
|
// Handle slug lookup (slug IS the event ticker on Kalshi)
|
|
48
48
|
if (params.slug) {
|
|
49
|
-
return await fetchEventByTicker(params.slug);
|
|
49
|
+
return await fetchEventByTicker(params.slug, http);
|
|
50
50
|
}
|
|
51
51
|
const status = params?.status || 'active';
|
|
52
52
|
const limit = params?.limit || 10000;
|
|
@@ -65,7 +65,7 @@ async function fetchEvents(params) {
|
|
|
65
65
|
};
|
|
66
66
|
if (cursor)
|
|
67
67
|
queryParams.cursor = cursor;
|
|
68
|
-
const response = await
|
|
68
|
+
const response = await http.get(utils_1.KALSHI_API_URL, { params: queryParams });
|
|
69
69
|
const events = response.data.events || [];
|
|
70
70
|
if (events.length === 0)
|
|
71
71
|
break;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
1
2
|
import { MarketFetchParams } from '../../BaseExchange';
|
|
2
3
|
import { UnifiedMarket } from '../../types';
|
|
3
4
|
export declare function resetCache(): void;
|
|
4
|
-
export declare function fetchMarkets(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
|
|
5
|
+
export declare function fetchMarkets(params?: MarketFetchParams, http?: AxiosInstance): Promise<UnifiedMarket[]>;
|
|
@@ -8,7 +8,7 @@ exports.fetchMarkets = fetchMarkets;
|
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const utils_1 = require("./utils");
|
|
10
10
|
const errors_1 = require("./errors");
|
|
11
|
-
async function fetchActiveEvents(targetMarketCount, status = 'open') {
|
|
11
|
+
async function fetchActiveEvents(http, targetMarketCount, status = 'open') {
|
|
12
12
|
let allEvents = [];
|
|
13
13
|
let totalMarketCount = 0;
|
|
14
14
|
let cursor = null;
|
|
@@ -27,7 +27,7 @@ async function fetchActiveEvents(targetMarketCount, status = 'open') {
|
|
|
27
27
|
};
|
|
28
28
|
if (cursor)
|
|
29
29
|
queryParams.cursor = cursor;
|
|
30
|
-
const response = await
|
|
30
|
+
const response = await http.get(utils_1.KALSHI_API_URL, { params: queryParams });
|
|
31
31
|
const events = response.data.events || [];
|
|
32
32
|
if (events.length === 0)
|
|
33
33
|
break;
|
|
@@ -56,9 +56,9 @@ async function fetchActiveEvents(targetMarketCount, status = 'open') {
|
|
|
56
56
|
} while (cursor && page < MAX_PAGES);
|
|
57
57
|
return allEvents;
|
|
58
58
|
}
|
|
59
|
-
async function fetchSeriesMap() {
|
|
59
|
+
async function fetchSeriesMap(http) {
|
|
60
60
|
try {
|
|
61
|
-
const response = await
|
|
61
|
+
const response = await http.get(utils_1.KALSHI_SERIES_URL);
|
|
62
62
|
const seriesList = response.data.series || [];
|
|
63
63
|
const map = new Map();
|
|
64
64
|
for (const series of seriesList) {
|
|
@@ -83,41 +83,41 @@ function resetCache() {
|
|
|
83
83
|
cachedSeriesMap = null;
|
|
84
84
|
lastCacheTime = 0;
|
|
85
85
|
}
|
|
86
|
-
async function fetchMarkets(params) {
|
|
86
|
+
async function fetchMarkets(params, http = axios_1.default) {
|
|
87
87
|
try {
|
|
88
88
|
// Handle marketId lookup (Kalshi marketId is the ticker)
|
|
89
89
|
if (params?.marketId) {
|
|
90
|
-
return await fetchMarketsBySlug(params.marketId);
|
|
90
|
+
return await fetchMarketsBySlug(params.marketId, http);
|
|
91
91
|
}
|
|
92
92
|
// Handle slug-based lookup (event ticker)
|
|
93
93
|
if (params?.slug) {
|
|
94
|
-
return await fetchMarketsBySlug(params.slug);
|
|
94
|
+
return await fetchMarketsBySlug(params.slug, http);
|
|
95
95
|
}
|
|
96
96
|
// Handle outcomeId lookup (strip -NO suffix, use as ticker)
|
|
97
97
|
if (params?.outcomeId) {
|
|
98
98
|
const ticker = params.outcomeId.replace(/-NO$/, '');
|
|
99
|
-
return await fetchMarketsBySlug(ticker);
|
|
99
|
+
return await fetchMarketsBySlug(ticker, http);
|
|
100
100
|
}
|
|
101
101
|
// Handle eventId lookup (event ticker works the same way)
|
|
102
102
|
if (params?.eventId) {
|
|
103
|
-
return await fetchMarketsBySlug(params.eventId);
|
|
103
|
+
return await fetchMarketsBySlug(params.eventId, http);
|
|
104
104
|
}
|
|
105
105
|
// Handle query-based search
|
|
106
106
|
if (params?.query) {
|
|
107
|
-
return await searchMarkets(params.query, params);
|
|
107
|
+
return await searchMarkets(params.query, params, http);
|
|
108
108
|
}
|
|
109
109
|
// Default: fetch markets
|
|
110
|
-
return await fetchMarketsDefault(params);
|
|
110
|
+
return await fetchMarketsDefault(params, http);
|
|
111
111
|
}
|
|
112
112
|
catch (error) {
|
|
113
113
|
throw errors_1.kalshiErrorMapper.mapError(error);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
async function fetchMarketsBySlug(eventTicker) {
|
|
116
|
+
async function fetchMarketsBySlug(eventTicker, http) {
|
|
117
117
|
// Kalshi API expects uppercase tickers, but URLs use lowercase
|
|
118
118
|
const normalizedTicker = eventTicker.toUpperCase();
|
|
119
119
|
const url = `https://api.elections.kalshi.com/trade-api/v2/events/${normalizedTicker}`;
|
|
120
|
-
const response = await
|
|
120
|
+
const response = await http.get(url, {
|
|
121
121
|
params: { with_nested_markets: true }
|
|
122
122
|
});
|
|
123
123
|
const event = response.data.event;
|
|
@@ -127,7 +127,7 @@ async function fetchMarketsBySlug(eventTicker) {
|
|
|
127
127
|
if (event.series_ticker) {
|
|
128
128
|
try {
|
|
129
129
|
const seriesUrl = `${utils_1.KALSHI_SERIES_URL}/${event.series_ticker}`;
|
|
130
|
-
const seriesResponse = await
|
|
130
|
+
const seriesResponse = await http.get(seriesUrl);
|
|
131
131
|
const series = seriesResponse.data.series;
|
|
132
132
|
if (series && series.tags && series.tags.length > 0) {
|
|
133
133
|
if (!event.tags || event.tags.length === 0) {
|
|
@@ -149,10 +149,10 @@ async function fetchMarketsBySlug(eventTicker) {
|
|
|
149
149
|
}
|
|
150
150
|
return unifiedMarkets;
|
|
151
151
|
}
|
|
152
|
-
async function searchMarkets(query, params) {
|
|
152
|
+
async function searchMarkets(query, params, http) {
|
|
153
153
|
// We must fetch ALL markets to search them locally since we don't have server-side search
|
|
154
154
|
const searchLimit = 10000;
|
|
155
|
-
const markets = await fetchMarketsDefault({ ...params, limit: searchLimit });
|
|
155
|
+
const markets = await fetchMarketsDefault({ ...params, limit: searchLimit }, http);
|
|
156
156
|
const lowerQuery = query.toLowerCase();
|
|
157
157
|
const searchIn = params?.searchIn || 'title'; // Default to title-only search
|
|
158
158
|
const filtered = markets.filter(market => {
|
|
@@ -167,7 +167,7 @@ async function searchMarkets(query, params) {
|
|
|
167
167
|
const limit = params?.limit || 10000;
|
|
168
168
|
return filtered.slice(0, limit);
|
|
169
169
|
}
|
|
170
|
-
async function fetchMarketsDefault(params) {
|
|
170
|
+
async function fetchMarketsDefault(params, http) {
|
|
171
171
|
const limit = params?.limit || 10000;
|
|
172
172
|
const offset = params?.offset || 0;
|
|
173
173
|
const now = Date.now();
|
|
@@ -196,13 +196,11 @@ async function fetchMarketsDefault(params) {
|
|
|
196
196
|
const isSorted = params?.sort && (params.sort === 'volume' || params.sort === 'liquidity');
|
|
197
197
|
const fetchLimit = isSorted ? 1000 : limit;
|
|
198
198
|
const [allEvents, fetchedSeriesMap] = await Promise.all([
|
|
199
|
-
fetchActiveEvents(fetchLimit, apiStatus),
|
|
200
|
-
fetchSeriesMap()
|
|
199
|
+
fetchActiveEvents(http, fetchLimit, apiStatus),
|
|
200
|
+
fetchSeriesMap(http)
|
|
201
201
|
]);
|
|
202
202
|
events = allEvents;
|
|
203
203
|
seriesMap = fetchedSeriesMap;
|
|
204
|
-
events = allEvents;
|
|
205
|
-
seriesMap = fetchedSeriesMap;
|
|
206
204
|
// Cache the dataset ONLY if:
|
|
207
205
|
// 1. We fetched a comprehensive set (>= 1000)
|
|
208
206
|
// 2. It's the standard 'open' status query
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
1
2
|
import { HistoryFilterParams, OHLCVParams } from '../../BaseExchange';
|
|
2
3
|
import { PriceCandle } from '../../types';
|
|
3
|
-
export declare function fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams): Promise<PriceCandle[]>;
|
|
4
|
+
export declare function fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams, http?: AxiosInstance): Promise<PriceCandle[]>;
|
|
@@ -8,7 +8,7 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
8
8
|
const utils_1 = require("./utils");
|
|
9
9
|
const validation_1 = require("../../utils/validation");
|
|
10
10
|
const errors_1 = require("./errors");
|
|
11
|
-
async function fetchOHLCV(id, params) {
|
|
11
|
+
async function fetchOHLCV(id, params, http = axios_1.default) {
|
|
12
12
|
(0, validation_1.validateIdFormat)(id, 'OHLCV');
|
|
13
13
|
// Validate resolution is provided
|
|
14
14
|
if (!params.resolution) {
|
|
@@ -57,7 +57,7 @@ async function fetchOHLCV(id, params) {
|
|
|
57
57
|
}
|
|
58
58
|
queryParams.start_ts = startTs;
|
|
59
59
|
queryParams.end_ts = endTs;
|
|
60
|
-
const response = await
|
|
60
|
+
const response = await http.get(url, { params: queryParams });
|
|
61
61
|
const candles = response.data.candlesticks || [];
|
|
62
62
|
const mappedCandles = candles.map((c) => {
|
|
63
63
|
// Priority:
|
|
@@ -7,14 +7,14 @@ exports.fetchOrderBook = fetchOrderBook;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const validation_1 = require("../../utils/validation");
|
|
9
9
|
const errors_1 = require("./errors");
|
|
10
|
-
async function fetchOrderBook(id) {
|
|
10
|
+
async function fetchOrderBook(id, http = axios_1.default) {
|
|
11
11
|
(0, validation_1.validateIdFormat)(id, 'OrderBook');
|
|
12
12
|
try {
|
|
13
13
|
// Check if this is a NO outcome request
|
|
14
14
|
const isNoOutcome = id.endsWith('-NO');
|
|
15
15
|
const ticker = id.replace(/-NO$/, '');
|
|
16
16
|
const url = `https://api.elections.kalshi.com/trade-api/v2/markets/${ticker}/orderbook`;
|
|
17
|
-
const response = await
|
|
17
|
+
const response = await http.get(url);
|
|
18
18
|
const data = response.data.orderbook;
|
|
19
19
|
// Structure: { yes: [[price, qty], ...], no: [[price, qty], ...] }
|
|
20
20
|
// Kalshi returns bids at their actual prices (not inverted)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
1
2
|
import { HistoryFilterParams, TradesParams } from '../../BaseExchange';
|
|
2
3
|
import { Trade } from '../../types';
|
|
3
|
-
export declare function fetchTrades(id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
|
|
4
|
+
export declare function fetchTrades(id: string, params: TradesParams | HistoryFilterParams, http?: AxiosInstance): Promise<Trade[]>;
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.fetchTrades = fetchTrades;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const errors_1 = require("./errors");
|
|
9
|
-
async function fetchTrades(id, params) {
|
|
9
|
+
async function fetchTrades(id, params, http = axios_1.default) {
|
|
10
10
|
try {
|
|
11
11
|
const ticker = id.replace(/-NO$/, '');
|
|
12
12
|
const url = `https://api.elections.kalshi.com/trade-api/v2/markets/trades`;
|
|
13
|
-
const response = await
|
|
13
|
+
const response = await http.get(url, {
|
|
14
14
|
params: {
|
|
15
15
|
ticker: ticker,
|
|
16
16
|
limit: params.limit || 100
|
|
@@ -7,6 +7,21 @@ export interface KalshiExchangeOptions {
|
|
|
7
7
|
websocket?: KalshiWebSocketConfig;
|
|
8
8
|
}
|
|
9
9
|
export declare class KalshiExchange extends PredictionMarketExchange {
|
|
10
|
+
readonly has: {
|
|
11
|
+
fetchMarkets: true;
|
|
12
|
+
fetchEvents: true;
|
|
13
|
+
fetchOHLCV: true;
|
|
14
|
+
fetchOrderBook: true;
|
|
15
|
+
fetchTrades: true;
|
|
16
|
+
createOrder: true;
|
|
17
|
+
cancelOrder: true;
|
|
18
|
+
fetchOrder: true;
|
|
19
|
+
fetchOpenOrders: true;
|
|
20
|
+
fetchPositions: true;
|
|
21
|
+
fetchBalance: true;
|
|
22
|
+
watchOrderBook: true;
|
|
23
|
+
watchTrades: true;
|
|
24
|
+
};
|
|
10
25
|
private auth?;
|
|
11
26
|
private wsConfig?;
|
|
12
27
|
constructor(options?: ExchangeCredentials | KalshiExchangeOptions);
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.KalshiExchange = void 0;
|
|
7
|
-
const axios_1 = __importDefault(require("axios"));
|
|
8
4
|
const BaseExchange_1 = require("../../BaseExchange");
|
|
9
5
|
const fetchMarkets_1 = require("./fetchMarkets");
|
|
10
6
|
const fetchEvents_1 = require("./fetchEvents");
|
|
@@ -16,6 +12,21 @@ const websocket_1 = require("./websocket");
|
|
|
16
12
|
const errors_1 = require("./errors");
|
|
17
13
|
const errors_2 = require("../../errors");
|
|
18
14
|
class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
15
|
+
has = {
|
|
16
|
+
fetchMarkets: true,
|
|
17
|
+
fetchEvents: true,
|
|
18
|
+
fetchOHLCV: true,
|
|
19
|
+
fetchOrderBook: true,
|
|
20
|
+
fetchTrades: true,
|
|
21
|
+
createOrder: true,
|
|
22
|
+
cancelOrder: true,
|
|
23
|
+
fetchOrder: true,
|
|
24
|
+
fetchOpenOrders: true,
|
|
25
|
+
fetchPositions: true,
|
|
26
|
+
fetchBalance: true,
|
|
27
|
+
watchOrderBook: true,
|
|
28
|
+
watchTrades: true,
|
|
29
|
+
};
|
|
19
30
|
auth;
|
|
20
31
|
wsConfig;
|
|
21
32
|
constructor(options) {
|
|
@@ -57,16 +68,16 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
57
68
|
// Market Data Methods - Implementation for CCXT-style API
|
|
58
69
|
// ----------------------------------------------------------------------------
|
|
59
70
|
async fetchMarketsImpl(params) {
|
|
60
|
-
return (0, fetchMarkets_1.fetchMarkets)(params);
|
|
71
|
+
return (0, fetchMarkets_1.fetchMarkets)(params, this.http);
|
|
61
72
|
}
|
|
62
73
|
async fetchEventsImpl(params) {
|
|
63
|
-
return (0, fetchEvents_1.fetchEvents)(params);
|
|
74
|
+
return (0, fetchEvents_1.fetchEvents)(params, this.http);
|
|
64
75
|
}
|
|
65
76
|
async fetchOHLCV(id, params) {
|
|
66
|
-
return (0, fetchOHLCV_1.fetchOHLCV)(id, params);
|
|
77
|
+
return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.http);
|
|
67
78
|
}
|
|
68
79
|
async fetchOrderBook(id) {
|
|
69
|
-
return (0, fetchOrderBook_1.fetchOrderBook)(id);
|
|
80
|
+
return (0, fetchOrderBook_1.fetchOrderBook)(id, this.http);
|
|
70
81
|
}
|
|
71
82
|
async fetchTrades(id, params) {
|
|
72
83
|
// Deprecation warning
|
|
@@ -74,7 +85,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
74
85
|
console.warn('[pmxt] Warning: The "resolution" parameter is deprecated for fetchTrades() and will be ignored. ' +
|
|
75
86
|
'It will be removed in v3.0.0. Please remove it from your code.');
|
|
76
87
|
}
|
|
77
|
-
return (0, fetchTrades_1.fetchTrades)(id, params);
|
|
88
|
+
return (0, fetchTrades_1.fetchTrades)(id, params, this.http);
|
|
78
89
|
}
|
|
79
90
|
// ----------------------------------------------------------------------------
|
|
80
91
|
// User Data Methods
|
|
@@ -88,7 +99,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
88
99
|
// TODO: Make base URL configurable in credentials
|
|
89
100
|
const baseUrl = this.getBaseUrl();
|
|
90
101
|
const headers = auth.getHeaders('GET', path);
|
|
91
|
-
const response = await
|
|
102
|
+
const response = await this.http.get(`${baseUrl}${path}`, { headers });
|
|
92
103
|
// Kalshi response structure:
|
|
93
104
|
// - balance: Available balance in cents (for trading)
|
|
94
105
|
// - portfolio_value: Total portfolio value in cents (includes positions)
|
|
@@ -139,7 +150,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
139
150
|
kalshiOrder.no_price = priceInCents;
|
|
140
151
|
}
|
|
141
152
|
}
|
|
142
|
-
const response = await
|
|
153
|
+
const response = await this.http.post(`${baseUrl}${path}`, kalshiOrder, { headers });
|
|
143
154
|
const order = response.data.order;
|
|
144
155
|
return {
|
|
145
156
|
id: order.order_id,
|
|
@@ -165,7 +176,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
165
176
|
const path = `/trade-api/v2/portfolio/orders/${orderId}`;
|
|
166
177
|
const baseUrl = this.getBaseUrl();
|
|
167
178
|
const headers = auth.getHeaders('DELETE', path);
|
|
168
|
-
const response = await
|
|
179
|
+
const response = await this.http.delete(`${baseUrl}${path}`, { headers });
|
|
169
180
|
const order = response.data.order;
|
|
170
181
|
return {
|
|
171
182
|
id: order.order_id,
|
|
@@ -190,7 +201,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
190
201
|
const path = `/trade-api/v2/portfolio/orders/${orderId}`;
|
|
191
202
|
const baseUrl = this.getBaseUrl();
|
|
192
203
|
const headers = auth.getHeaders('GET', path);
|
|
193
|
-
const response = await
|
|
204
|
+
const response = await this.http.get(`${baseUrl}${path}`, { headers });
|
|
194
205
|
const order = response.data.order;
|
|
195
206
|
return {
|
|
196
207
|
id: order.order_id,
|
|
@@ -222,7 +233,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
222
233
|
const baseUrl = this.getBaseUrl();
|
|
223
234
|
// Sign only the base path, not the query parameters
|
|
224
235
|
const headers = auth.getHeaders('GET', basePath);
|
|
225
|
-
const response = await
|
|
236
|
+
const response = await this.http.get(`${baseUrl}${basePath}${queryParams}`, { headers });
|
|
226
237
|
const orders = response.data.orders || [];
|
|
227
238
|
return orders.map((order) => ({
|
|
228
239
|
id: order.order_id,
|
|
@@ -248,7 +259,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
248
259
|
const path = '/trade-api/v2/portfolio/positions';
|
|
249
260
|
const baseUrl = this.getBaseUrl();
|
|
250
261
|
const headers = auth.getHeaders('GET', path);
|
|
251
|
-
const response = await
|
|
262
|
+
const response = await this.http.get(`${baseUrl}${path}`, { headers });
|
|
252
263
|
const positions = response.data.market_positions || [];
|
|
253
264
|
return positions.map((pos) => {
|
|
254
265
|
const absPosition = Math.abs(pos.position);
|