From e809d28a45f21e193ae0f993e06c14592f7b1ac4 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Fri, 17 May 2024 16:55:23 -0300 Subject: [PATCH 1/4] Fixing market orders args --- src/order-builder/helpers.ts | 2 +- src/types.ts | 5 --- tests/order-builder/helpers.test.ts | 48 ++++++++++------------------- 3 files changed, 17 insertions(+), 38 deletions(-) diff --git a/src/order-builder/helpers.ts b/src/order-builder/helpers.ts index 7d01698..081e04b 100644 --- a/src/order-builder/helpers.ts +++ b/src/order-builder/helpers.ts @@ -268,7 +268,7 @@ export const buildMarketBuyOrderCreationArgs = async ( feeRateBps, nonce, signer, - expiration: (userMarketOrder.expiration || 0).toString(), + expiration: "0", signatureType, } as OrderData; }; diff --git a/src/types.ts b/src/types.ts index c4fa537..15043bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -138,11 +138,6 @@ export interface UserMarketOrder { */ nonce?: number; - /** - * Timestamp after which the order is expired. - */ - expiration?: number; - /** * Address of the order taker. The zero address is used to indicate a public order */ diff --git a/tests/order-builder/helpers.test.ts b/tests/order-builder/helpers.test.ts index ce0be73..da14efe 100644 --- a/tests/order-builder/helpers.test.ts +++ b/tests/order-builder/helpers.test.ts @@ -2475,7 +2475,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2494,7 +2493,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2506,7 +2505,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2525,7 +2523,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2537,7 +2535,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2556,7 +2553,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2568,7 +2565,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2587,7 +2583,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2602,7 +2598,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2621,7 +2616,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2788,7 +2783,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2807,7 +2801,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -2974,7 +2968,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -2993,7 +2986,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -3160,7 +3153,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const orderData: OrderData = await buildMarketBuyOrderCreationArgs( "0x0000000000000000000000000000000000000001", @@ -3179,7 +3171,7 @@ describe("helpers", () => { feeRateBps: "111", nonce: "123", signer: "0x0000000000000000000000000000000000000001", - expiration: "50000", + expiration: "0", signatureType: SignatureType.EOA, }); }); @@ -3350,7 +3342,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3372,7 +3363,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("200000000"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3386,7 +3377,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3408,7 +3398,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("178571400"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3422,7 +3412,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3444,7 +3433,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("1785714280"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3458,7 +3447,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3480,7 +3468,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("17857142857"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3498,7 +3486,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3520,7 +3507,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("200000000"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3534,7 +3521,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3556,7 +3542,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("178571400"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3570,7 +3556,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3592,7 +3577,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("1785714280"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); @@ -3606,7 +3591,6 @@ describe("helpers", () => { amount: 100, feeRateBps: 111, nonce: 123, - expiration: 50000, }; const signedOrder = await createMarketBuyOrder( @@ -3628,7 +3612,7 @@ describe("helpers", () => { expect(signedOrder.makerAmount).equal("100000000"); expect(signedOrder.takerAmount).equal("17857142857"); expect(signedOrder.side).equal(UtilsSide.BUY); - expect(signedOrder.expiration).equal("50000"); + expect(signedOrder.expiration).equal("0"); expect(signedOrder.nonce).equal("123"); expect(signedOrder.feeRateBps).equal("111"); expect(signedOrder.signatureType).equal(SignatureType.EOA); From 9bc9d5ae00ec9545caedc7b4601796ebf4a64cb1 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Fri, 17 May 2024 16:58:17 -0300 Subject: [PATCH 2/4] version pump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f030ca..f8b8462 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@polymarket/clob-client", "description": "Typescript client for Polymarket's CLOB", - "version": "4.5.3", + "version": "4.5.5", "contributors": [ { "name": "Jonathan Amenechi", From 63656f13e2ba38ef04a02a84d537cc9480b6c190 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Fri, 17 May 2024 19:19:16 -0300 Subject: [PATCH 3/4] fix --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index c13ccb7..2a8ee3c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -507,7 +507,7 @@ export class ClobClient { const negRisk = options?.negRisk ?? false; if (!userMarketOrder.price) { - const marketPrice = await this.getPrice(tokenID, Side.BUY); + const marketPrice = await this.getPrice(tokenID, Side.SELL); userMarketOrder.price = parseFloat(marketPrice); } From cd6f24f64e08bedcd1367c6b4307f5f9939a48a0 Mon Sep 17 00:00:00 2001 From: Rodrigo <95635797+poly-rodr@users.noreply.github.com> Date: Tue, 21 May 2024 12:17:01 -0300 Subject: [PATCH 4/4] market price calculations --- src/client.ts | 30 ++++++++- src/order-builder/helpers.ts | 13 ++++ tests/order-builder/helpers.test.ts | 97 ++++++++++++++++++++++++++++- 3 files changed, 136 insertions(+), 4 deletions(-) diff --git a/src/client.ts b/src/client.ts index 2a8ee3c..df8abcb 100644 --- a/src/client.ts +++ b/src/client.ts @@ -103,6 +103,7 @@ import { } from "./endpoints"; import { OrderBuilder } from "./order-builder/builder"; import { END_CURSOR, INITIAL_CURSOR } from "./constants"; +import { calculateMarketPrice } from "./order-builder/helpers"; export class ClobClient { readonly host: string; @@ -507,8 +508,11 @@ export class ClobClient { const negRisk = options?.negRisk ?? false; if (!userMarketOrder.price) { - const marketPrice = await this.getPrice(tokenID, Side.SELL); - userMarketOrder.price = parseFloat(marketPrice); + userMarketOrder.price = await this.calculateMarketPrice( + tokenID, + Side.BUY, + userMarketOrder.amount, + ); } if (!priceValid(userMarketOrder.price, tickSize)) { @@ -824,6 +828,28 @@ export class ClobClient { return this.get(`${this.host}${GET_MARKET_TRADES_EVENTS}${conditionID}`); } + public async calculateMarketPrice( + tokenID: string, + side: Side, + amount: number, + ): Promise { + const book = await this.getOrderBook(tokenID); + if (!book) { + throw new Error("no orderbook"); + } + if (side === Side.BUY) { + if (!book.asks) { + throw new Error("no match"); + } + return calculateMarketPrice(book.asks, amount); + } else { + if (!book.bids) { + throw new Error("no match"); + } + return calculateMarketPrice(book.bids, amount); + } + } + private canL1Auth(): void { if (this.signer === undefined) { throw L1_AUTH_UNAVAILABLE_ERROR; diff --git a/src/order-builder/helpers.ts b/src/order-builder/helpers.ts index 081e04b..ad0143a 100644 --- a/src/order-builder/helpers.ts +++ b/src/order-builder/helpers.ts @@ -16,6 +16,7 @@ import { TickSize, RoundConfig, CreateOrderOptions, + OrderSummary, } from "../types"; import { decimalPlaces, roundDown, roundNormal, roundUp } from "../utilities"; import { @@ -301,3 +302,15 @@ export const createMarketBuyOrder = async ( return buildOrder(eoaSigner, exchangeContract, chainId, orderData); }; + +export const calculateMarketPrice = (positions: OrderSummary[], amountToMatch: number) => { + let sum = 0; + for (let i = 0; i < positions.length; i++) { + const p = positions[i]; + sum += parseFloat(p.size) * parseFloat(p.price); + if (sum >= amountToMatch) { + return parseFloat(p.price); + } + } + throw new Error("no match"); +}; diff --git a/tests/order-builder/helpers.test.ts b/tests/order-builder/helpers.test.ts index da14efe..925b2e5 100644 --- a/tests/order-builder/helpers.test.ts +++ b/tests/order-builder/helpers.test.ts @@ -1,6 +1,6 @@ import "mocha"; import { expect } from "chai"; -import { UserOrder, Side, Chain, UserMarketOrder } from "../../src/types"; +import { UserOrder, Side, Chain, UserMarketOrder, OrderSummary } from "../../src/types"; import { buildOrderCreationArgs, buildOrder, @@ -10,6 +10,7 @@ import { getOrderRawAmounts, getMarketBuyOrderRawAmounts, ROUNDING_CONFIG, + calculateMarketPrice, } from "../../src/order-builder/helpers"; import { OrderData, SignatureType, Side as UtilsSide } from "@polymarket/order-utils"; import { Wallet } from "@ethersproject/wallet"; @@ -3477,7 +3478,7 @@ describe("helpers", () => { }); }); - describe("CTF Exchange", () => { + describe("Neg Risk CTF Exchange", () => { describe("buy order", async () => { it("0.1", async () => { const order: UserMarketOrder = { @@ -3621,4 +3622,96 @@ describe("helpers", () => { }); }); }); + + describe.only("calculateMarketPrice", () => { + describe("BUY", () => { + it("empty orderbook", () => { + expect(() => calculateMarketPrice([], 100)).to.throw("no match"); + }); + it("not enough", () => { + const positions = [ + { price: "0.5", size: "100" }, + { price: "0.4", size: "100" }, + ] as OrderSummary[]; + expect(() => calculateMarketPrice(positions, 100)).to.throw("no match"); + }); + it("ok", () => { + let positions = [ + { price: "0.5", size: "100" }, + { price: "0.4", size: "100" }, + { price: "0.3", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.3); + + positions = [ + { price: "0.5", size: "100" }, + { price: "0.4", size: "200" }, + { price: "0.3", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.4); + + positions = [ + { price: "0.5", size: "120" }, + { price: "0.4", size: "100" }, + { price: "0.3", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.4); + + positions = [ + { price: "0.5", size: "200" }, + { price: "0.4", size: "100" }, + { price: "0.3", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.5); + }); + }); + describe("SELL", () => { + it("empty orderbook", () => { + expect(() => calculateMarketPrice([], 100)).to.throw("no match"); + }); + it("not enough", () => { + const positions = [ + { price: "0.4", size: "100" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(() => calculateMarketPrice(positions, 100)).to.throw("no match"); + }); + it("ok", () => { + let positions = [ + { price: "0.3", size: "100" }, + { price: "0.4", size: "100" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.5); + + positions = [ + { price: "0.3", size: "100" }, + { price: "0.4", size: "300" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.4); + + positions = [ + { price: "0.3", size: "100" }, + { price: "0.4", size: "200" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.4); + + positions = [ + { price: "0.3", size: "300" }, + { price: "0.4", size: "100" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.4); + + positions = [ + { price: "0.3", size: "334" }, + { price: "0.4", size: "100" }, + { price: "0.5", size: "100" }, + ] as OrderSummary[]; + expect(calculateMarketPrice(positions, 100)).equal(0.3); + }); + }); + }); });