Skip to content
Closed
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
13 changes: 2 additions & 11 deletions sdks/typescript/pmxt/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2894,17 +2894,8 @@ export abstract class Exchange {
* @returns The volume-weighted average price, or 0 if insufficient liquidity
*/
getExecutionPrice(orderBook: OrderBook, side: 'buy' | 'sell', amount: number): number {
const levels = side === 'buy' ? orderBook.asks : orderBook.bids;
let remaining = amount;
let totalCost = 0;
for (const level of levels) {
const fill = Math.min(remaining, level.size);
totalCost += fill * level.price;
remaining -= fill;
if (remaining <= 0) break;
}
if (remaining > 0) return 0;
return totalCost / amount;
const result = this.getExecutionPriceDetailed(orderBook, side, amount);
return result.fullyFilled ? result.price : 0;
}

/**
Expand Down
80 changes: 80 additions & 0 deletions sdks/typescript/tests/execution-price-detailed-local.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,83 @@ describe('getExecutionPriceDetailed', () => {
});
});
});

describe('getExecutionPrice', () => {
it('requires full fill and sorts asks before averaging buys', () => {
const client = new Polymarket({ autoStartServer: false });
const price = client.getExecutionPrice(
{
bids: [],
asks: [
{ price: 0.52, size: 4 },
{ price: 0.5, size: 6 },
],
},
'buy',
8
);

expect(price).toBe(0.505);
});

it('requires full fill and sorts bids before averaging sells', () => {
const client = new Polymarket({ autoStartServer: false });
const price = client.getExecutionPrice(
{
bids: [
{ price: 0.41, size: 5 },
{ price: 0.43, size: 10 },
],
asks: [],
},
'sell',
8
);

expect(price).toBe(0.43);
});

it('returns 0 when order cannot be fully filled', () => {
const client = new Polymarket({ autoStartServer: false });
const price = client.getExecutionPrice(
{
bids: [{ price: 0.42, size: 2 }],
asks: [],
},
'sell',
5
);

expect(price).toBe(0);
});

it('matches detailed-price validation for non-positive amount', () => {
const client = new Polymarket({ autoStartServer: false });
const emptyBook = { bids: [], asks: [] };

expect(() => client.getExecutionPrice(emptyBook, 'buy', 0)).toThrow(
'Amount must be greater than 0'
);
expect(() => client.getExecutionPriceDetailed(emptyBook, 'buy', -1)).toThrow(
'Amount must be greater than 0'
);
});

it('ignores non-positive level sizes before computing execution price', () => {
const client = new Polymarket({ autoStartServer: false });
const price = client.getExecutionPrice(
{
bids: [],
asks: [
{ price: 0.52, size: -1 },
{ price: 0.5, size: 0 },
{ price: 0.48, size: 8 },
],
},
'buy',
8
);

expect(price).toBe(0.48);
});
});