Skip to content

Commit a044cce

Browse files
committed
fix: forward fetchTrades limit param to upstream APIs and validate max 1000
Polymarket's fetchRawTrades never forwarded the user-provided `limit` to the CLOB API, so Polymarket defaulted to 100 results regardless of what the caller requested. Kalshi, Myriad, and Smarkets hardcoded `limit: 100` fallbacks instead of letting the upstream API decide. - Forward `params.limit` in Polymarket fetcher (the root cause) - Remove hardcoded `|| 100` defaults in Kalshi, Myriad fetchers - Fix Smarkets fetcher ignoring `params` entirely - Add `MAX_TRADES_LIMIT = 1000` constant and `validateTradesLimit()` - All 5 venues throw `ValidationError` on limit > 1000
1 parent 86ee2d2 commit a044cce

12 files changed

Lines changed: 43 additions & 11 deletions

File tree

changelog.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [2.43.12] - 2026-05-23
6+
7+
### Fixed
8+
9+
- **fetchTrades**: Polymarket fetcher now forwards the `limit` parameter to the CLOB API. Previously, `limit` was silently ignored and Polymarket's API defaulted to 100 results per request — making it impossible to fetch more than 100 trades in a single call.
10+
- **fetchTrades**: Removed hardcoded `limit: 100` defaults from Kalshi, Myriad, and Smarkets fetchers. When no limit is specified, the upstream API's own default is used instead of our arbitrary cap.
11+
- **fetchTrades**: Smarkets fetcher now respects the user-provided `limit` parameter instead of ignoring it entirely.
12+
- **fetchTrades**: Added `MAX_TRADES_LIMIT = 1000` validation across all venues (Polymarket, Kalshi, Smarkets, Myriad, Probable). Passing `limit > 1000` now throws a `ValidationError` instead of silently returning fewer results.
13+
514
## [2.43.11] - 2026-05-23
615

716
### Fixed

core/src/BaseExchange.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,16 @@ export interface OHLCVParams {
145145
/**
146146
* Parameters for fetching trade history. No resolution parameter - trades are discrete events.
147147
*/
148+
/** Maximum allowed value for `TradesParams.limit`. */
149+
export const MAX_TRADES_LIMIT = 1000;
150+
148151
export interface TradesParams {
149152
// No resolution - trades are discrete events, not aggregated
150153
/** Start of the time range */
151154
start?: Date;
152155
/** End of the time range */
153156
end?: Date;
154-
/** Maximum number of results to return */
157+
/** Maximum number of results to return (max {@link MAX_TRADES_LIMIT}) */
155158
limit?: number;
156159
}
157160

core/src/exchanges/kalshi/fetcher.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,9 @@ export class KalshiFetcher implements IExchangeFetcher<KalshiRawEvent, KalshiRaw
300300

301301
async fetchRawTrades(id: string, params: TradesParams): Promise<KalshiRawTrade[]> {
302302
const ticker = id.replace(/-NO$/, '');
303-
const data = await this.ctx.callApi('GetTrades', {
304-
ticker,
305-
limit: params.limit || 100,
306-
});
303+
const query: Record<string, any> = { ticker };
304+
if (params.limit) query.limit = params.limit;
305+
const data = await this.ctx.callApi('GetTrades', query);
307306
return data.trades || [];
308307
}
309308

core/src/exchanges/kalshi/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TradesParams,
1111
} from '../../BaseExchange';
1212
import { AuthenticationError } from '../../errors';
13+
import { validateTradesLimit } from '../../utils/validation';
1314
import {
1415
Balance,
1516
BuiltOrder,
@@ -213,6 +214,7 @@ export class KalshiExchange extends PredictionMarketExchange {
213214
outcomeId: string,
214215
params: TradesParams | HistoryFilterParams,
215216
): Promise<Trade[]> {
217+
validateTradesLimit(params.limit);
216218
if ('resolution' in params && params.resolution !== undefined) {
217219
logger.warn(
218220
'The "resolution" parameter is deprecated for fetchTrades() and will be ignored. ' +

core/src/exchanges/myriad/fetcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ export class MyriadFetcher implements IExchangeFetcher<MyriadRawMarket, MyriadRa
241241
id: marketId,
242242
network_id: Number(networkId),
243243
page: 1,
244-
limit: params.limit || 100,
245244
};
245+
if (params.limit) queryParams.limit = params.limit;
246246

247247
if (params.start) queryParams.since = Math.floor(ensureDate(params.start).getTime() / 1000);
248248
if (params.end) queryParams.until = Math.floor(ensureDate(params.end).getTime() / 1000);

core/src/exchanges/myriad/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { MyriadAuth } from './auth';
44
import { MyriadWebSocket } from './websocket';
55
import { myriadErrorMapper } from './errors';
66
import { AuthenticationError } from '../../errors';
7+
import { validateTradesLimit } from '../../utils/validation';
78
import { DEFAULT_BASE_URL } from './utils';
89
import { parseOpenApiSpec } from '../../utils/openapi';
910
import { myriadApiSpec } from './api';
@@ -129,6 +130,7 @@ export class MyriadExchange extends PredictionMarketExchange {
129130
}
130131

131132
async fetchTrades(outcomeId: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]> {
133+
validateTradesLimit(params.limit);
132134
if ('resolution' in params && params.resolution !== undefined) {
133135
logger.warn(
134136
'The "resolution" parameter is deprecated for fetchTrades() and will be ignored. ' +

core/src/exchanges/polymarket/fetcher.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ export class PolymarketFetcher implements IExchangeFetcher<PolymarketRawEvent, P
270270
asset_id: id,
271271
};
272272

273+
if (params.limit) queryParams.limit = params.limit;
273274
if (params.start) {
274275
queryParams.after = Math.floor(ensureDate(params.start).getTime() / 1000);
275276
}

core/src/exchanges/polymarket/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
UserTrade,
3030
} from '../../types';
3131
import { parseOpenApiSpec } from '../../utils/openapi';
32-
import { validateIdFormat, validateOutcomeId } from '../../utils/validation';
32+
import { validateIdFormat, validateOutcomeId, validateTradesLimit } from '../../utils/validation';
3333
import { FetcherContext } from '../interfaces';
3434
import { polymarketClobSpec } from './api-clob';
3535
import { polymarketDataSpec } from './api-data';
@@ -185,6 +185,7 @@ export class PolymarketExchange extends PredictionMarketExchange {
185185
async fetchTrades(outcomeId: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]> {
186186
validateIdFormat(outcomeId, 'Trades');
187187
validateOutcomeId(outcomeId, 'Trades');
188+
validateTradesLimit(params.limit);
188189
if ('resolution' in params && params.resolution !== undefined) {
189190
logger.warn('The "resolution" parameter is deprecated for fetchTrades() and will be ignored. It will be removed in v3.0.0.');
190191
}

core/src/exchanges/probable/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { ProbableAuth } from './auth';
2424
import { ProbableWebSocket, ProbableWebSocketConfig } from './websocket';
2525
import { probableErrorMapper } from './errors';
2626
import { AuthenticationError } from '../../errors';
27+
import { validateTradesLimit } from '../../utils/validation';
2728
import { OrderSide } from '@prob/clob';
2829
import { parseOpenApiSpec } from '../../utils/openapi';
2930
import { probableApiSpec } from './api';
@@ -198,6 +199,7 @@ export class ProbableExchange extends PredictionMarketExchange {
198199
}
199200

200201
async fetchTrades(outcomeId: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]> {
202+
validateTradesLimit(params.limit);
201203
const auth = this.ensureAuth();
202204
const client = auth.getClobClient();
203205

core/src/exchanges/smarkets/fetcher.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,15 @@ export class SmarketsFetcher implements IExchangeFetcher<SmarketsRawEventWithMar
233233

234234
async fetchRawTradeActivity(
235235
marketId: string,
236-
_params: TradesParams,
236+
params: TradesParams,
237237
): Promise<SmarketsRawActivityRow[]> {
238-
const data = await this.ctx.callApi('get_activity', {
238+
const query: Record<string, any> = {
239239
market_id: [marketId],
240240
source: ['order.execute', 'order.execute.confirm'],
241-
limit: 100,
242241
sort: '-seq,-subseq',
243-
});
242+
};
243+
if (params.limit) query.limit = params.limit;
244+
const data = await this.ctx.callApi('get_activity', query);
244245

245246
return (data.account_activity || []) as SmarketsRawActivityRow[];
246247
}

0 commit comments

Comments
 (0)