Skip to content

Commit

Permalink
Merge pull request #58 from Polymarket/feat/tick-size
Browse files Browse the repository at this point in the history
feat/ adding support for all the possible tick sizes
  • Loading branch information
poly-rodr authored Apr 19, 2023
2 parents b8d9843 + 5b3c8da commit cf54d8a
Show file tree
Hide file tree
Showing 10 changed files with 1,222 additions and 60 deletions.
4 changes: 3 additions & 1 deletion examples/get_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def main():
chain_id = MUMBAI
client = ClobClient(host, key=key, chain_id=chain_id, creds=creds)

resp = client.get_order("0xf5667d8509bdc78ac43676fe2c980da1365c471ee92153820c89c488fc15d539")
resp = client.get_order(
"0xf5667d8509bdc78ac43676fe2c980da1365c471ee92153820c89c488fc15d539"
)
print(resp)
print("Done!")

Expand Down
6 changes: 3 additions & 3 deletions examples/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ def main():
chain_id = MUMBAI
client = ClobClient(host, key=key, chain_id=chain_id, creds=creds)

# Create and sign a limit order buying 100 YES tokens for 0.50c each
# Create and sign a limit order buying 100 YES tokens for 0.0005 each
order_args = OrderArgs(
price=0.50,
size=100.0,
price=0.0005,
size=20,
side=BUY,
token_id="16678291189211314787145083999015737376658799626183230671758641503291735614088",
)
Expand Down
34 changes: 32 additions & 2 deletions py_clob_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
DROP_TRADE_NOTIFICATIONS,
GET_BALANCE_ALLOWANCE,
IS_ORDER_SCORING,
GET_TICK_SIZE,
)
from .clob_types import (
ApiCreds,
Expand All @@ -38,6 +39,7 @@
OrderBookSummary,
BalanceAllowanceParams,
OrderScoringParams,
TickSize,
)
from .exceptions import PolyException
from .http_helpers.helpers import (
Expand All @@ -55,6 +57,7 @@
parse_raw_orderbook_summary,
generate_orderbook_summary_hash,
order_to_json,
is_tick_size_smaller,
)


Expand Down Expand Up @@ -90,6 +93,7 @@ def __init__(
self.builder = OrderBuilder(
self.signer, sig_type=signature_type, funder=funder
)
self.__tick_sizes = {}
self.logger = logging.getLogger(self.__class__.__name__)

def get_address(self):
Expand Down Expand Up @@ -225,14 +229,40 @@ def get_price(self, token_id, side):
"""
return get("{}{}?token_id={}&side={}".format(self.host, PRICE, token_id, side))

def create_order(self, order_args: OrderArgs):
def get_tick_size(self, token_id: str) -> TickSize:
if token_id in self.__tick_sizes:
return self.__tick_sizes[token_id]

result = get("{}{}?token_id={}".format(self.host, GET_TICK_SIZE, token_id))
self.__tick_sizes[token_id] = result["minimum_tick_size"]

return self.__tick_sizes[token_id]

def __resolve_tick_size(
self, token_id: str, tick_size: TickSize = None
) -> TickSize:
min_tick_size = self.get_tick_size(token_id)
if tick_size is not None:
if is_tick_size_smaller(tick_size, min_tick_size):
raise Exception(
"invalid tick size ("
+ tick_size
+ "), minimum for the market is "
+ min_tick_size,
)
else:
tick_size = min_tick_size
return tick_size

def create_order(self, order_args: OrderArgs, tick_size: TickSize = None):
"""
Creates and signs an order
Level 2 Auth required
"""
self.assert_level_2_auth()

return self.builder.create_order(order_args)
tick_size = self.__resolve_tick_size(order_args.token_id, tick_size)
return self.builder.create_order(order_args, tick_size)

def post_order(self, order, orderType: OrderType = OrderType.GTC):
"""
Expand Down
14 changes: 14 additions & 0 deletions py_clob_client/clob_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Any
from dataclasses import dataclass, asdict
from json import dumps
from typing import Literal

from .constants import ZERO_ADDRESS

Expand Down Expand Up @@ -132,3 +133,16 @@ class OrderType(enumerate):
@dataclass
class OrderScoringParams:
orderId: str


TickSize = Literal["0.1", "0.01", "0.001", "0.0001"]


@dataclass
class RoundConfig:
price: float
size: float
amount: float


TickSizes: dict[str, TickSize]
1 change: 1 addition & 0 deletions py_clob_client/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
DROP_TRADE_NOTIFICATIONS = "/drop-trade-notifications"
GET_BALANCE_ALLOWANCE = "/balance-allowance"
IS_ORDER_SCORING = "/order-scoring"
GET_TICK_SIZE = "/tick-size"
43 changes: 28 additions & 15 deletions py_clob_client/order_builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@
from .constants import BUY, SELL

from ..signer import Signer
from ..clob_types import OrderArgs
from ..clob_types import OrderArgs, TickSize, RoundConfig
from typing import Tuple

ROUNDING_CONFIG: Tuple[TickSize, RoundConfig] = {
"0.1": RoundConfig(price=1, size=2, amount=3),
"0.01": RoundConfig(price=2, size=2, amount=4),
"0.001": RoundConfig(price=3, size=2, amount=5),
"0.0001": RoundConfig(price=4, size=2, amount=6),
}


class OrderBuilder:
Expand All @@ -40,30 +48,32 @@ def __init__(self, signer: Signer, sig_type=None, funder=None):
def _get_contract_config(self, chain_id: int):
return get_contract_config(chain_id)

def get_order_amounts(self, side: str, size: float, price: float):
raw_price = round_normal(price, 2)
def get_order_amounts(
self, side: str, size: float, price: float, round_config: RoundConfig
):
raw_price = round_normal(price, round_config.price)

if side == BUY:
raw_taker_amt = round_down(size, 2)
raw_taker_amt = round_down(size, round_config.size)

raw_maker_amt = raw_taker_amt * raw_price
if decimal_places(raw_maker_amt) > 4:
raw_maker_amt = round_up(raw_maker_amt, 8)
if decimal_places(raw_maker_amt) > 4:
raw_maker_amt = round_down(raw_maker_amt, 4)
if decimal_places(raw_maker_amt) > round_config.amount:
raw_maker_amt = round_up(raw_maker_amt, round_config.amount + 4)
if decimal_places(raw_maker_amt) > round_config.amount:
raw_maker_amt = round_down(raw_maker_amt, round_config.amount)

maker_amount = to_token_decimals(raw_maker_amt)
taker_amount = to_token_decimals(raw_taker_amt)

return UtilsBuy, maker_amount, taker_amount
elif side == SELL:
raw_maker_amt = round_down(size, 2)
raw_maker_amt = round_down(size, round_config.size)

raw_taker_amt = raw_maker_amt * raw_price
if decimal_places(raw_taker_amt) > 4:
raw_taker_amt = round_up(raw_taker_amt, 8)
if decimal_places(raw_taker_amt) > 4:
raw_taker_amt = round_down(raw_taker_amt, 4)
if decimal_places(raw_taker_amt) > round_config.amount:
raw_taker_amt = round_up(raw_taker_amt, round_config.amount + 4)
if decimal_places(raw_taker_amt) > round_config.amount:
raw_taker_amt = round_down(raw_taker_amt, round_config.amount)

maker_amount = to_token_decimals(raw_maker_amt)
taker_amount = to_token_decimals(raw_taker_amt)
Expand All @@ -72,12 +82,15 @@ def get_order_amounts(self, side: str, size: float, price: float):
else:
raise ValueError(f"order_args.side must be '{BUY}' or '{SELL}'")

def create_order(self, order_args: OrderArgs) -> SignedOrder:
def create_order(self, order_args: OrderArgs, tick_size: TickSize) -> SignedOrder:
"""
Creates and signs an order
"""
side, maker_amount, taker_amount = self.get_order_amounts(
order_args.side, order_args.size, order_args.price
order_args.side,
order_args.size,
order_args.price,
ROUNDING_CONFIG[tick_size],
)

data = OrderData(
Expand Down
7 changes: 5 additions & 2 deletions py_clob_client/utilities.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import hashlib
import json

from .clob_types import OrderBookSummary, OrderSummary
from .clob_types import OrderBookSummary, OrderSummary, TickSize


def parse_raw_orderbook_summary(raw_obs: any) -> OrderBookSummary:
Expand Down Expand Up @@ -33,3 +32,7 @@ def generate_orderbook_summary_hash(orderbook: OrderBookSummary) -> str:

def order_to_json(order, owner, orderType) -> dict:
return {"order": order.dict(), "owner": owner, "orderType": orderType}


def is_tick_size_smaller(a: TickSize, b: TickSize) -> bool:
return float(a) < float(b)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="py_clob_client",
version="0.5.0",
version="0.6.0",
author="Polymarket Engineering",
author_email="[email protected]",
maintainer="Polymarket Engineering",
Expand Down
Loading

0 comments on commit cf54d8a

Please sign in to comment.