Skip to content

Commit

Permalink
calculating market price
Browse files Browse the repository at this point in the history
  • Loading branch information
poly-rodr committed May 21, 2024
1 parent e246c5b commit ebdbf8a
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 3 deletions.
21 changes: 19 additions & 2 deletions py_clob_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,9 @@ def create_market_order(
neg_risk = options.neg_risk if options else False

if order_args.price is None or order_args.price <= 0:
p = self.get_price(order_args.token_id, "SELL")
order_args.price = float(p["price"])
order_args.price = self.calculate_market_price(
order_args.token_id, "BUY", order_args.amount
)

if not price_valid(order_args.price, tick_size):
raise Exception(
Expand Down Expand Up @@ -673,3 +674,19 @@ def get_market_trades_events(self, condition_id):
Get the market's trades events by condition id
"""
return get("{}{}{}".format(self.host, GET_MARKET_TRADES_EVENTS, condition_id))

def calculate_market_price(self, token_id: str, side: str, amount: float) -> float:
"""
Calculates the matching price considering an amount and the current orderbook
"""
book = self.get_order_book(token_id)
if book is None:
raise Exception("no orderbook")
if side == "BUY":
if book.asks is None:
raise Exception("no match")
return self.builder.calculate_market_price(book.asks, amount)
else:
if book.bids is None:
raise Exception("no match")
return self.builder.calculate_market_price(book.bids, amount)
11 changes: 11 additions & 0 deletions py_clob_client/order_builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
TickSize,
RoundConfig,
MarketOrderArgs,
OrderSummary,
)

ROUNDING_CONFIG: dict[TickSize, RoundConfig] = {
Expand Down Expand Up @@ -173,3 +174,13 @@ def create_market_order(
)

return order_builder.build_signed_order(data)

def calculate_market_price(
self, positions: list[OrderSummary], amount_to_match: float
) -> float:
sum = 0
for p in positions:
sum += float(p.size) * float(p.price)
if sum >= amount_to_match:
return float(p.price)
raise Exception("no match")
111 changes: 110 additions & 1 deletion tests/order_builder/test_builder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from unittest import TestCase

from py_clob_client.clob_types import OrderArgs, MarketOrderArgs, CreateOrderOptions
from py_clob_client.clob_types import (
OrderArgs,
MarketOrderArgs,
CreateOrderOptions,
OrderSummary,
)
from py_clob_client.constants import AMOY
from py_clob_client.order_builder.constants import BUY, SELL

Expand All @@ -16,6 +21,110 @@


class TestOrderBuilder(TestCase):
def test_calculate_market_price_buy(self):
# empty
with self.assertRaises(Exception):
builder = OrderBuilder(signer)
builder.calculate_market_price([], 100)

# not enough
with self.assertRaises(Exception):
positions = [
OrderSummary(price="0.5", size="100"),
OrderSummary(price="0.4", size="100"),
]
builder = OrderBuilder(signer)
builder.calculate_market_price(positions, 100)

# OK
positions = [
OrderSummary(price="0.5", size="100"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.3", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.3)

positions = [
OrderSummary(price="0.5", size="100"),
OrderSummary(price="0.4", size="200"),
OrderSummary(price="0.3", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.4)

positions = [
OrderSummary(price="0.5", size="120"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.3", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.4)

positions = [
OrderSummary(price="0.5", size="200"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.3", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.5)

def test_calculate_market_price_sell(self):
# empty
with self.assertRaises(Exception):
builder = OrderBuilder(signer)
builder.calculate_market_price([], 100)

# not enough
with self.assertRaises(Exception):
positions = [
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
builder.calculate_market_price(positions, 100)

# OK
positions = [
OrderSummary(price="0.3", size="100"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.5)

positions = [
OrderSummary(price="0.3", size="100"),
OrderSummary(price="0.4", size="300"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.4)

positions = [
OrderSummary(price="0.3", size="100"),
OrderSummary(price="0.4", size="200"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.4)

positions = [
OrderSummary(price="0.3", size="300"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.4)

positions = [
OrderSummary(price="0.3", size="334"),
OrderSummary(price="0.4", size="100"),
OrderSummary(price="0.5", size="100"),
]
builder = OrderBuilder(signer)
self.assertEqual(builder.calculate_market_price(positions, 100), 0.3)

def test_get_market_order_amounts_0_1(self):
builder = OrderBuilder(signer)

Expand Down

0 comments on commit ebdbf8a

Please sign in to comment.