Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/api-doc-config.generated.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_generated": "Auto-generated by extract-jsdoc.js on 2026-06-08T09:58:54.515Z. Do not edit manually.",
"_generated": "Auto-generated by extract-jsdoc.js on 2026-06-08T11:11:42.806Z. Do not edit manually.",
"methods": {
"has": {
"summary": "HTTP verb for the endpoint (e.g. GET, POST). */",
Expand Down
15 changes: 7 additions & 8 deletions core/specs/kalshi/Kalshi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4096,8 +4096,7 @@ components:
format: int64
description: Unix timestamp of the last update to the balance.
balance_dollars:
type: number
format: double
$ref: '#/components/schemas/FixedPointDollars'
description: Member's available balance in USD dollars.

CreateSubaccountResponse:
Expand Down Expand Up @@ -4853,8 +4852,8 @@ components:
- price
- yes_price
- no_price
- yes_price_fixed
- no_price_fixed
- yes_price_dollars
- no_price_dollars
- is_taker
- fee_cost
properties:
Expand Down Expand Up @@ -4896,11 +4895,11 @@ components:
no_price:
type: integer
description: Fill price for the no side in cents
yes_price_fixed:
type: string
yes_price_dollars:
$ref: '#/components/schemas/FixedPointDollars'
description: Fill price for the yes side in fixed point dollars
no_price_fixed:
type: string
no_price_dollars:
$ref: '#/components/schemas/FixedPointDollars'
description: Fill price for the no side in fixed point dollars
is_taker:
type: boolean
Expand Down
4 changes: 2 additions & 2 deletions core/specs/metaculus/Metaculus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ components:
title:
type: string
example: "Binary Post title"
url_title:
short_title:
type: string
example: "Binary Post url title"
example: "Binary Post short title"
slug:
type: string
example: "numeric-post"
Expand Down
2 changes: 1 addition & 1 deletion core/specs/polymarket/PolymarketClobAPI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ paths:
- L2Auth: []
parameters:
- $ref: '#/components/parameters/L2Headers'
- name: orderId
- name: order_id
in: query
required: true
schema:
Expand Down
26 changes: 23 additions & 3 deletions core/specs/polymarket/Polymarket_Data_API.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -372,22 +372,42 @@ paths:
name: user
schema:
$ref: '#/components/schemas/Address'
- in: query
name: maker_address
schema:
$ref: '#/components/schemas/Address'
description: Maker address filter for trade lookups.
- in: query
name: side
schema:
type: string
enum:
- BUY
- SELL
- in: query
name: next_cursor
schema:
type: string
description: Cursor for fetching the next page of trades.
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Trade'
type: object
properties:
limit:
type: integer
next_cursor:
type: string
nullable: true
count:
type: integer
data:
type: array
items:
$ref: '#/components/schemas/Trade'
'400':
description: Bad Request
content:
Expand Down
8 changes: 4 additions & 4 deletions core/src/exchanges/hyperliquid/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ export function fromCoinEncoding(encoding: number): { outcomeId: number; side: '
/**
* Convert an outcome ID to the allMids lookup key.
*
* The allMids endpoint keys prediction-market outcomes as "@{outcomeId}"
* (e.g. "@8"), which is distinct from the "#encoding" coin notation used
* for orders and positions.
* The allMids endpoint keys HIP-4 prediction-market outcomes using the same
* "#encoding" form as coin notation. For the Yes side, encoding is
* 10 * outcomeId + 0 (e.g. outcome 8 -> "#80").
*/
export function toMidKey(outcomeId: number): string {
return `@${outcomeId}`;
return toCoinNotation(outcomeId, 'yes');
}

/**
Expand Down
7 changes: 4 additions & 3 deletions core/src/exchanges/metaculus/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { buildSourceMetadata } from "../../utils/metadata";
// — excluded from sourceMetadata so we capture only what the unified shape drops.
const METACULUS_PROMOTED_MARKET_KEYS = [
// identity / slug
'id', 'slug', 'url_title',
'id', 'slug', 'short_title', 'url_title',
// title
'title',
// description lives inside question / group_of_questions — those are excluded below
Expand All @@ -24,7 +24,7 @@ const METACULUS_PROMOTED_MARKET_KEYS = [

// Raw Metaculus Post fields already promoted to first-class UnifiedEvent columns.
export const METACULUS_PROMOTED_EVENT_KEYS = [
'id', 'slug', 'url_title',
'id', 'slug', 'short_title', 'url_title',
'title',
'question', 'group_of_questions',
'projects',
Expand Down Expand Up @@ -282,7 +282,7 @@ export function mapMarketToUnified(post: any, eventId?: string, groupPostId?: nu
question.description ??
question.resolution_criteria ??
"",
slug: post.slug ?? post.url_title ?? undefined,
slug: post.slug ?? post.short_title ?? post.url_title ?? undefined,
outcomes,
resolutionDate,
volume24h: 0, // Metaculus has no monetary volume
Expand Down Expand Up @@ -334,6 +334,7 @@ function mapGroupPostToMarkets(post: any, eventId?: string): UnifiedMarket[] {
question: subQuestion,
// Inherit metadata from the parent post
slug: post.slug,
short_title: post.short_title,
url_title: post.url_title,
projects: post.projects,
nr_forecasters: subQuestion.nr_forecasters ?? post.nr_forecasters,
Expand Down
2 changes: 1 addition & 1 deletion core/src/exchanges/polymarket/api-clob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export const polymarketClobSpec = {
"$ref": "#/components/parameters/L2Headers"
},
{
"name": "orderId",
"name": "order_id",
"in": "query",
"required": true,
"schema": {
Expand Down
14 changes: 14 additions & 0 deletions core/src/exchanges/polymarket/api-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ export const polymarketDataSpec = {
"$ref": "#/components/schemas/Address"
}
},
{
"in": "query",
"name": "maker_address",
"schema": {
"$ref": "#/components/schemas/Address"
}
},
{
"in": "query",
"name": "side",
Expand All @@ -339,6 +346,13 @@ export const polymarketDataSpec = {
"SELL"
]
}
},
{
"in": "query",
"name": "next_cursor",
"schema": {
"type": "string"
}
}
]
}
Expand Down
6 changes: 4 additions & 2 deletions core/src/exchanges/polymarket/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export interface PolymarketRawOrderBook {
bids?: PolymarketRawOrderBookLevel[];
asks?: PolymarketRawOrderBookLevel[];
timestamp?: string | number;
tick_size?: string;
min_order_size?: string;
}

export interface PolymarketRawTrade {
Expand Down Expand Up @@ -278,8 +280,8 @@ export class PolymarketFetcher implements IExchangeFetcher<PolymarketRawEvent, P
queryParams.before = Math.floor(ensureDate(params.end).getTime() / 1000);
}

const trades = await this.ctx.callApi('getTrades', queryParams) || [];
return trades;
const data = await this.ctx.callApi('getTrades', queryParams);
return Array.isArray(data) ? data : (data?.data ?? []);
} catch (error: any) {
throw polymarketErrorMapper.mapError(error);
}
Expand Down
2 changes: 2 additions & 0 deletions core/src/exchanges/polymarket/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ export class PolymarketNormalizer implements IExchangeNormalizer<PolymarketRawEv
bids,
asks,
timestamp: raw.timestamp ? (typeof raw.timestamp === 'string' ? (isFinite(Number(raw.timestamp)) ? Number(raw.timestamp) : new Date(raw.timestamp).getTime()) : Number(raw.timestamp)) : Date.now(),
tickSize: raw.tick_size != null ? parseFloat(raw.tick_size) : undefined,
minOrderSize: raw.min_order_size != null ? parseFloat(raw.min_order_size) : undefined,
};
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/exchanges/polymarket_us/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class PolymarketUSExchange extends PredictionMarketExchange {

constructor(credentials?: ExchangeCredentials) {
super(credentials);
this.rateLimit = 100;
this.rateLimit = 20;
this.config = getPolymarketUSConfig(credentials?.baseUrl);
this.normalizer = new PolymarketUSNormalizer();
this.client = new PolymarketUSClient({
Expand Down
10 changes: 8 additions & 2 deletions core/src/exchanges/polymarket_us/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ const POLYMARKET_US_PROMOTED_SERIES_KEYS = [
] as const;

// marketSides and outcomePrices feed the outcomes array and are therefore
// treated as promoted. orderPriceMinTickSize maps to tickSize.
// treated as promoted. orderPriceMinTickSize maps to tickSize and
// minimumTradeQty maps to minOrderSize.
const POLYMARKET_US_PROMOTED_MARKET_KEYS = [
'slug', 'question', 'title', 'description', 'category', 'tags',
'endDate', 'marketSides', 'outcomePrices', 'orderPriceMinTickSize',
'eventSlug', 'volume', 'liquidity',
'minimumTradeQty', 'eventSlug', 'volume', 'liquidity',
] as const;

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -84,6 +85,8 @@ interface RealMarket {
// `UnifiedMarket.tickSize` so price-sensitive helpers can honour the
// real tick rather than falling back to the hard-coded default.
orderPriceMinTickSize?: number;
// Per-market minimum tradeable quantity for partial-contract markets.
minimumTradeQty?: number;
eventSlug?: string;
volume?: number;
liquidity?: number;
Expand Down Expand Up @@ -427,6 +430,9 @@ export class PolymarketUSNormalizer {
tickSize: typeof market.orderPriceMinTickSize === 'number'
? market.orderPriceMinTickSize
: undefined,
minOrderSize: typeof market.minimumTradeQty === 'number'
? market.minimumTradeQty
: undefined,
sourceMetadata: buildSourceMetadata(
market as unknown as Record<string, unknown>,
POLYMARKET_US_PROMOTED_MARKET_KEYS,
Expand Down
9 changes: 9 additions & 0 deletions core/src/server/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2953,6 +2953,9 @@ components:
tickSize:
type: number
description: 'Minimum price increment (e.g., 0.01, 0.001)'
minOrderSize:
type: number
description: 'Minimum tradeable quantity/contracts for this market, when venue-provided'
status:
type: string
description: 'Venue-native lifecycle status (e.g. ''active'', ''closed'', ''archived'').'
Expand Down Expand Up @@ -3187,6 +3190,12 @@ components:
datetime:
type: string
description: ISO 8601 datetime string of the snapshot (CCXT-compatible).
tickSize:
type: number
description: Venue-provided minimum price increment for orders against this book.
minOrderSize:
type: number
description: Venue-provided minimum order size/contracts for this book.
required:
- bids
- asks
Expand Down
5 changes: 5 additions & 0 deletions core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export interface UnifiedMarket {
/** Optional list of tags. More granular than category — e.g. ["Crypto", "Crypto Prices", "Bitcoin"] or ["Politics", "Elections", "Trump"]. Tags vary by venue: Polymarket markets carry several, Kalshi typically one. */
tags?: string[];
tickSize?: number; // Minimum price increment (e.g., 0.01, 0.001)
minOrderSize?: number; // Minimum tradeable quantity/contracts for this market, when venue-provided

/** Venue-native lifecycle status (e.g. 'active', 'closed', 'archived'). */
status?: string;
Expand Down Expand Up @@ -183,6 +184,10 @@ export interface OrderBook {
timestamp?: number;
/** ISO 8601 datetime string of the snapshot (CCXT-compatible). */
datetime?: string;
/** Venue-provided minimum price increment for orders against this book. */
tickSize?: number;
/** Venue-provided minimum order size/contracts for this book. */
minOrderSize?: number;
}

export interface Trade {
Expand Down
12 changes: 12 additions & 0 deletions docs/api-reference/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -9466,6 +9466,10 @@
"type": "number",
"description": "Minimum price increment (e.g., 0.01, 0.001)"
},
"minOrderSize": {
"type": "number",
"description": "Minimum tradeable quantity/contracts for this market, when venue-provided"
},
"status": {
"type": "string",
"description": "Venue-native lifecycle status (e.g. 'active', 'closed', 'archived')."
Expand Down Expand Up @@ -9773,6 +9777,14 @@
"datetime": {
"type": "string",
"description": "ISO 8601 datetime string of the snapshot (CCXT-compatible)."
},
"tickSize": {
"type": "number",
"description": "Venue-provided minimum price increment for orders against this book."
},
"minOrderSize": {
"type": "number",
"description": "Venue-provided minimum order size/contracts for this book."
}
},
"required": [
Expand Down
7 changes: 6 additions & 1 deletion sdks/python/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,7 @@ image: str # Optional image URL for the market.
category: str # Optional category label. Venue-defined — common values include "Sports", "Politics", "Crypto", "Economics", "Science", "Culture". Polymarket uses finer-grained categories like "Bitcoin", "Soccer", "Economic Policy"; Kalshi uses broader ones like "Sports" or "Mentions".
tags: List[string] # Optional list of tags. More granular than category — e.g. ["Crypto", "Crypto Prices", "Bitcoin"] or ["Politics", "Elections", "Trump"]. Tags vary by venue: Polymarket markets carry several, Kalshi typically one.
tick_size: float # Minimum price increment (e.g., 0.01, 0.001)
min_order_size: float # Minimum tradeable quantity/contracts for this market, when venue-provided
status: str # Venue-native lifecycle status (e.g. 'active', 'closed', 'archived').
contract_address: str # On-chain contract / condition identifier where applicable (Polymarket conditionId, etc.).
source_metadata: object # Raw venue-specific metadata not captured by first-class fields (e.g. Kalshi series_ticker / series_title from the parent event, Polymarket series). Passed through verbatim so downstream consumers can recover anything the unified shape omits. Each venue populates what it has.
Expand Down Expand Up @@ -1564,6 +1565,8 @@ bids: List[OrderLevel] # Order book bid levels, sorted by price descending.
asks: List[OrderLevel] # Order book ask levels, sorted by price ascending.
timestamp: float # Unix timestamp in milliseconds when the snapshot was taken.
datetime: str # ISO 8601 datetime string of the snapshot (CCXT-compatible).
tick_size: float # Venue-provided minimum price increment for orders against this book.
min_order_size: float # Venue-provided minimum order size/contracts for this book.
```

---
Expand Down Expand Up @@ -2813,7 +2816,7 @@ Check Order Reward Scoring *(Auth required)*

**Parameters:**
- `` (, string)
- `orderId` (query, string) **required**
- `order_id` (query, string) **required**

---
##### `postOrdersScoring`
Expand Down Expand Up @@ -2927,7 +2930,9 @@ Get trades for a user or markets
- `market` (query, array) — Comma-separated list of condition IDs. Mutually exclusive with eventId.
- `eventId` (query, array) — Comma-separated list of event IDs. Mutually exclusive with market.
- `user` (query, string)
- `maker_address` (query, string) — Maker address filter for trade lookups.
- `side` (query, string) — enum: `BUY,SELL`
- `next_cursor` (query, string) — Cursor for fetching the next page of trades.

---
##### `getActivity`
Expand Down
Loading
Loading