Trading
Market makers place and adjust two-sided limit orders through the CLOB REST API. The Rust SDK takes care of EIP-712 signing, HMAC authentication, and batch submission so you can focus on pricing logic.
Two-Sided Quoting
Section titled “Two-Sided Quoting”The fundamental market-making action is placing a bid below your fair value estimate and an ask above it.
use openfish_client_sdk::clob::types::Side;use openfish_client_sdk::types::dec;
let token_id = "3409705850427531082723332342151729...".parse()?;
// Post a bid at 0.48let bid = client.limit_order() .token_id(token_id) .price(dec!(0.48)) .size(dec!(1000)) .side(Side::Buy) .build().await?;let signed_bid = client.sign(&signer, bid).await?;client.post_order(signed_bid).await?;
// Post an ask at 0.52let ask = client.limit_order() .token_id(token_id) .price(dec!(0.52)) .size(dec!(1000)) .side(Side::Sell) .build().await?;let signed_ask = client.sign(&signer, ask).await?;client.post_order(signed_ask).await?;Batch Orders
Section titled “Batch Orders”The post_orders endpoint accepts up to 15 orders in one request. Batching cuts down on round-trip latency and lets you refresh multiple price levels in a single atomic call.
let mut signed_orders = Vec::new();for (price, side) in [ (dec!(0.48), Side::Buy), (dec!(0.47), Side::Buy), (dec!(0.52), Side::Sell), (dec!(0.53), Side::Sell),] { let order = client.limit_order() .token_id(token_id) .price(price) .size(dec!(500)) .side(side) .build().await?; signed_orders.push(client.sign(&signer, order).await?);}let response = client.post_orders(signed_orders).await?;Always prefer post_orders over multiple individual post_order calls.
Order Types
Section titled “Order Types”| Type | Behaviour | When to Use |
|---|---|---|
| GTC | Rests on the book until filled or cancelled | Default for passive quoting |
| GTD | Automatically expires at a specified Unix timestamp | Expire quotes before known events or catalysts |
| FOK | Must fill entirely and immediately, otherwise the whole order is killed | Aggressive rebalancing — all or nothing |
| FAK | Fills whatever is immediately available, kills the remainder | Rebalancing where partial fills are acceptable |
GTC and GTD are the primary tools for passive market making. FOK and FAK are intended for taking liquidity when rebalancing inventory.
Time-Limited Quotes with GTD
Section titled “Time-Limited Quotes with GTD”use chrono::{TimeDelta, Utc};use openfish_client_sdk::clob::types::OrderType;
let order = client.limit_order() .token_id(token_id) .price(dec!(0.50)) .size(dec!(1000)) .side(Side::Buy) .order_type(OrderType::GTD) .expiration(Utc::now() + TimeDelta::hours(1)) .build().await?;let signed = client.sign(&signer, order).await?;client.post_order(signed).await?;Cancellation Strategies
Section titled “Cancellation Strategies”Several methods exist for pulling resting orders off the book.
// Cancel a single order by IDclient.cancel_order(order_id).await?;
// Cancel all orders in a specific marketclient.cancel_market_orders(&cancel_market_request).await?;
// Cancel every open order across all markets (kill switch)client.cancel_all_orders().await?;Wire cancel_all_orders into your emergency kill switch. Trigger it without hesitation when you observe abnormal fill patterns, position limit violations, or connectivity problems.
Tick Sizes
Section titled “Tick Sizes”Each market enforces a minimum tick size. Orders priced off-grid are rejected.
let resp = client.tick_size(token_id).await?;// resp.minimum_tick_size: TickSize::Tenth | Hundredth | Thousandth | TenThousandthCheck the tick size before quoting a new market.
Monitoring Open Orders
Section titled “Monitoring Open Orders”use openfish_client_sdk::clob::types::request::OrdersRequest;
// Fetch a single orderlet order = client.order(order_id).await?;
// List all open orders in a marketlet request = OrdersRequest::builder() .market("0xbd31dc8a...".parse()?) .build();let orders = client.orders(&request, None).await?;For real-time fill notifications, subscribe to the WebSocket user channel rather than polling.
Makers pay zero fees on Openfish. Taker fees vary by market category and fund the Maker Rebates program. Markets with fees enabled have fees_enabled: true in the market object.
Best Practices
Section titled “Best Practices”Quote Management
Section titled “Quote Management”- Quote both sides — Two-sided liquidity earns maximum rewards and rebates.
- Skew on inventory — Shift your quotes when inventory becomes unbalanced on one side.
- Cancel stale quotes — Pull orders immediately when market conditions change.
- Use GTD for events — Auto-expire quotes before known catalysts to prevent stale exposure.
Latency
Section titled “Latency”- Batch orders — Submit multiple quotes in a single
post_orderscall. - WebSocket for data — Subscribe to real-time feeds instead of polling REST endpoints.
Risk Controls
Section titled “Risk Controls”- Size limits — Never quote more than your available token balance.
- Price guards — Validate prices against the book midpoint; reject outliers.
- Kill switch — Call
cancel_all_orderson errors or position breaches. - Monitor fills — Use the WebSocket user channel for real-time fill notifications.
Next Steps
Section titled “Next Steps”- Inventory — Split, merge, and redeem outcome tokens.
- Liquidity Rewards — Earn rewards for providing two-sided liquidity.
- Maker Rebates — Volume-tiered daily USDC rebates.