The Opinion CLOB implements two order execution types (Market, Limit) and two position directions (Buy, Sell). These primitives enable participation in binary prediction markets through standardized order mechanics.
Order Sides
BUY (Long Position)
Definition: Acquisition of outcome tokens representing a prediction that the specified event will occur.
Example - Binary Market: "Will BTC reach $100k in 2025?"
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide# Buy YES tokens (betting it will happen)side = OrderSide.BUY
Payoff Structure:
Position
Purchase Cost
Resolution
Settlement
Net P&L
Long 100 YES @ $0.60
$60
YES
$100
+$40 (66.7% ROI)
Long 100 YES @ $0.60
$60
NO
$0
-$60 (100% loss)
Risk Parameters:
Maximum Loss: Premium paid (position cost)
Maximum Gain: $1.00 per share minus premium
Breakeven: Event resolution matches position direction
SELL (Short Position or Position Exit)
Definition: Transfer of outcome tokens, either closing an existing long position or establishing a synthetic short position.
# You previously bought 100 YES @ $0.50
# Now YES price is $0.75
# Sell to lock in profit
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide
side = OrderSide.SELL # Sell your YES tokens
# Thesis: YES tokens overpriced at $0.80 (implied 80% probability)
# Strategy: Create position exposed to NO outcome
# Step 1: Convert 100 USDT β 100 YES + 100 NO (via splitPosition)
client.split(market_id=123, amount=100_000000) # 100 USDT
# Step 2: Sell YES tokens
from opinion_clob_sdk.chain.py_order_utils.model.order import PlaceOrderDataInput
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide
from opinion_clob_sdk.chain.py_order_utils.model.order_type import LIMIT_ORDER
order = PlaceOrderDataInput(
marketId=123,
tokenId='token_yes',
side=OrderSide.SELL,
orderType=LIMIT_ORDER,
price='0.80',
makerAmountInBaseToken=100 # Sell 100 YES
)
client.place_order(order)
# Position Analysis:
# - Received: $80 USDT (from YES sale)
# - Holdings: 100 NO tokens
# - Net cost: $100 - $80 = $20
#
# Payoff scenarios:
# - If NO resolves: 100 NO β $100 USDT, P&L = $100 - $20 = +$80 (400% ROI)
# - If YES resolves: 100 NO β $0, P&L = $0 - $20 = -$20 (100% loss)
from opinion_clob_sdk.chain.py_order_utils.model.order import PlaceOrderDataInput
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide
from opinion_clob_sdk.chain.py_order_utils.model.order_type import MARKET_ORDER
# Market order: buy with specified USDT allocation
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.BUY,
orderType=MARKET_ORDER,
price='0', # Ignored for market orders (accepts market price)
makerAmountInQuoteToken=50 # Allocate 50 USDT for purchase
)
result = client.place_order(order)
from opinion_clob_sdk.chain.py_order_utils.model.order import PlaceOrderDataInput
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide
from opinion_clob_sdk.chain.py_order_utils.model.order_type import LIMIT_ORDER
# Limit buy - only buy if price drops to $0.55 or lower
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.BUY,
orderType=LIMIT_ORDER,
price='0.55',
makerAmountInQuoteToken=100 # Willing to spend $100 USDT
)
result = client.place_order(order)
Orderbook before your order:
Buy: 20 YES @ $0.58
Buy: 30 YES @ $0.57
Sell: 40 YES @ $0.60
Sell: 50 YES @ $0.61
You place: Limit BUY 100 YES @ $0.59
Orderbook after:
Buy: 100 YES @ $0.59 β Your order (waiting)
Buy: 20 YES @ $0.58
Buy: 30 YES @ $0.57
Sell: 40 YES @ $0.60
Sell: 50 YES @ $0.61
Later, someone places: Limit SELL 60 YES @ $0.59
Result: You buy 60 YES @ $0.59, your order now shows 40 YES remaining
price='0.00' # β Too low
price='1.00' # β Too high
price='1.05' # β Greater than 1.00
price='0.5' # Valid: 50%
price='0.511' # Valid: 51.10%
price='0.55555' # Invalid: too many decimals
# Given: price and one amount type, calculate the other
price = 0.60
quote_amount = 50 # USDT
# Calculate base tokens
base_tokens = quote_amount / price # 83.33 YES
# Reverse calculation
quote_amount = base_tokens * price # $50 USDT
from opinion_clob_sdk import Client
from opinion_clob_sdk.chain.py_order_utils.model.order import PlaceOrderDataInput
from opinion_clob_sdk.chain.py_order_utils.model.sides import OrderSide
from opinion_clob_sdk.chain.py_order_utils.model.order_type import MARKET_ORDER
client = Client(...)
# "Buy YES tokens with $100 USDT immediately"
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.BUY,
orderType=MARKET_ORDER,
price='0', # Ignored for market orders
makerAmountInQuoteToken=100
)
result = client.place_order(order)
# "Buy 50 YES tokens, but only if price drops to $0.45 or lower"
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.BUY,
orderType=LIMIT_ORDER,
price='0.45',
makerAmountInBaseToken=50
)
result = client.place_order(order)
print(f"Order placed, waiting for $0.45 or better")
# You own 200 YES, current price is $0.80, you want to sell
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.SELL,
orderType=MARKET_ORDER,
price='0',
makerAmountInBaseToken=200 # Sell all 200 YES
)
result = client.place_order(order)
# You receive ~$160 USDT (200 Γ $0.80)
# "Sell 100 YES tokens, but only at $0.85 or higher"
order = PlaceOrderDataInput(
marketId=813,
tokenId='84286908393008806294032747949016601113812276485362312899677525031544985576186',
side=OrderSide.SELL,
orderType=LIMIT_ORDER,
price='0.85',
makerAmountInBaseToken=100
)
result = client.place_order(order)
print(f"Order on book at $0.85")
result = client.place_order(order)
# Get all your orders for a market
orders = client.get_my_orders(market_id=813, limit=50)
for order in orders['result']['data']:
print(f"Order {order['orderId']}: {order['status']}")
# Cancel single order
client.cancel_order(orderId='________')
# Cancel all orders for a market
cancelled = client.cancel_all_orders(market_id=813)
print(f"Cancelled {len(cancelled['result'])} orders")
# Always check current prices before placing orders
orderbook = client.get_orderbook(token_id='84286908393008806294032747949016601113812276485362312899677525031544985576186')
best_bid = orderbook['result']['bids'][0]['price'] if orderbook['result']['bids'] else None
best_ask = orderbook['result']['asks'][0]['price'] if orderbook['result']['asks'] else None
print(f"Best bid: {best_bid}, Best ask: {best_ask}")
# Place limit order between bid and ask for better fill chances
if best_bid and best_ask:
mid_price = (float(best_bid) + float(best_ask)) / 2
# Place buy slightly above bid, sell slightly below ask
# β Bad: Large market order causes slippage
order = PlaceOrderDataInput(
side=OrderSide.BUY,
orderType=MARKET_ORDER,
makerAmountInQuoteToken=10000 # $10,000 - will move market!
)
# β Good: Break into smaller limit orders
for i in range(10):
order = PlaceOrderDataInput(
side=OrderSide.BUY,
orderType=LIMIT_ORDER,
price=f'{0.60 + i * 0.001}', # Incrementing prices
makerAmountInQuoteToken=1000 # $1,000 each
)
client.place_order(order)
def validate_price(price: str) -> bool:
try:
p = float(price)
return 0.01 <= p <= 0.99
except ValueError:
return False
price = '0.75'
if validate_price(price):
order = PlaceOrderDataInput(price=price, ...)
else:
raise ValueError("Invalid price")
# β Using quote amount for SELL orders often confusing
order = PlaceOrderDataInput(
side=OrderSide.SELL,
makerAmountInQuoteToken=50 # "Sell $50 worth" - hard to calculate
)
# β Better: Specify exact tokens to sell
order = PlaceOrderDataInput(
side=OrderSide.SELL,
makerAmountInBaseToken=100 # "Sell 100 tokens" - clear
)
# β Missing price
order = PlaceOrderDataInput(
orderType=LIMIT_ORDER,
# price missing!
makerAmountInQuoteToken=50
)
# β Always specify price for limit orders
order = PlaceOrderDataInput(
orderType=LIMIT_ORDER,
price='0.65',
makerAmountInQuoteToken=50
)