Taker (RFQ Submitter) Tutorial
This tutorial relies on context established in Prerequisites and Setup.
Pick Target Companies
Find the company ID of a specific counterparty you want to send an RFQ to:
companies = list(paginate(client.get_companies))
print(json.dumps(target_companies, indent=2))
# ...
target_companies = [
"1ebc7ece-093e-42aa-8cdf-028ccb1fc68a",
"ef7ec17a-c585-4239-b6bb-cd66c4022aee",
"0158cdf0-8b8d-4047-943f-74f6ae3cb45d",
]
Or trade with all the companies at once:
my_company_id = client.get_status().result["auth"]["company_id"]
target_companies = [c["id"] for c in paginate(client.get_companies)
if c["id"] != my_company_id]
Create an RFQ
Let's trade a BTC future expiring a week from now. The RFQ itself will expire in an hour.
from datetime import datetime, timezone, timedelta
new_rfq = client.create_rfq(
structure={"legs": [
{
"instrument": {
"instrument_type": InstrumentType.DATED_FUTURE,
"underlying": "BTC",
"settlement_asset": "USDC",
"expiry": (date.today() + timedelta(days=7)).isoformat()
},
"ratio": 1,
"side": TradeSide.BUY
}
]},
qty="1",
expires_at=(datetime.now(timezone.utc) + timedelta(hours=1)).isoformat(),
target_companies=target_companies
).result
Wait For Quotes
Poll your RFQ until you see some quote responses from the companies you targeted:
rfq = client.get_rfqs_sent(id=new_rfq["rfq_id"]).result[0]
print("BIDS:")
print(json.dumps(rfq["bids"], indent=2))
print("ASKS:")
print(json.dumps(rfq["asks"], indent=2))
Select the ID of the quote you wish to accept:
parent_quote_id = "dd898543-0752-421d-b321-6556873322a5"
Accept the Quote
accepted = client.accept_quote(
rfq_id=new_rfq["rfq_id"],
parent_quote_id=parent_quote_id,
side=TradeSide.SELL, # or BUY if you want to target a quote with the best ask
).result
print(json.dumps(accepted, indent=2))
Wait for the Clearing Status
Because pending_settlement_pool
is not null and new_clearing_status
is pending_pool_creation
in the above response, the maker chose to create a new settlement pool for this trade. Note that the pool already exists and has an ID but is in pending
state.
The pool and the quote will progress automatically, but it will take a few seconds. Use the helper to wait until then:
quote = poller.wait_for_clearing_status(
parent_quote_id=parent_quote_id,
status=ClearingStatus.PENDING_TAKER_DEPOSIT_APPROVAL,
)
print(quote['clearing_status'])
Note that if is poller returns successfully but quote['clearing_status']
is not pending_taker_deposit_approval
, it means that the deposit for this trade is covered by a previously issued approval or there is enough funds in the pool, so no further action is required from you.
Approve USDC Spending for the Deposit
If the current clearing status is pending_taker_deposit_approval
, you need to sign and submit a ERC-2612 spending approval for the deposit:
pool = client.get_settlement_pools(id=quote['pool_location']).result[0]
permits.sign_and_submit_decimal(
pool_address=pool['data']['address'],
allowance=accepted['pending_deposits_sum_qty']
)
Wait for Clearing Status to Progress
Use the helper to wait until your deposit is approved:
quote = poller.wait_for_clearing_status(
parent_quote_id=parent_quote_id,
status=ClearingStatus.PENDING_MAKER_LAST_LOOK,
)
The maker of the trade (the company that responded to your quote) is responsible for the remaining steps.
You can continue polling the quote until it reaches one of the final clearing statuses: success_trades_booked_into_pool
, or one starting with rejected_
.
Last updated