From dfb583289a0856f7bfa0fd4a986e2d7876a7b840 Mon Sep 17 00:00:00 2001 From: Purin1410 Date: Wed, 12 Aug 2026 02:11:55 +0700 Subject: [PATCH] fix(ts-sdk): align execution price calculation --- sdks/typescript/pmxt/client.ts | 13 +-- .../execution-price-detailed-local.test.ts | 80 +++++++++++++++++++ 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/sdks/typescript/pmxt/client.ts b/sdks/typescript/pmxt/client.ts index 04ddc27f..690d7262 100644 --- a/sdks/typescript/pmxt/client.ts +++ b/sdks/typescript/pmxt/client.ts @@ -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; } /** diff --git a/sdks/typescript/tests/execution-price-detailed-local.test.ts b/sdks/typescript/tests/execution-price-detailed-local.test.ts index 423e46f8..16c37101 100644 --- a/sdks/typescript/tests/execution-price-detailed-local.test.ts +++ b/sdks/typescript/tests/execution-price-detailed-local.test.ts @@ -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); + }); +});