Paradigm API v1
Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
Introduction
Paradigm's three major products are Unified Markets (UM), the Future Spread Dashboard (FSPD), and Vault Request for Quote (VRFQ).
Paradigm provides a GUI to access all products via a desktop application as well as your internet browser.
Paradigm provides RESToverHTTP and JSON-RPCoverWebSockets API interfaces for users with workflows consistent with the broader crypto space.
Feel free to reach out to our account management team or technical solutions team as we would love to help!
UM - Brief Overview
Unified Markets (UM) has two products, Directed Request for Quote (DRFQ) and Global Request for Quote (GRFQ), which make up the UM user interface.
DRFQ enables users to create short-lived private auction RFQ markets. Users must specify the structure of the market as well as the counterparties who are able to return prices. In DRFQ, only the creator of the market is able to see the returned prices from the Makers and is able to cross a Maker's order. Makers are unable to see eachother's prices or their order's relative priority. To note, there are two versions of DRFQ, DRFQv1 and DRFQv2. Users should use DRFQv2 as DRFQv1 will be deprecated in due course.
GRFQ enables users to create long-lived public auction Central Limit Order Book markets. Users must specify the structure of the market and anyone is able to participate. In GRFQ, all orders submitted are blind and are actionable by any user.
Deribit, BIT, and Bybit are available as venues.
FSPD - Brief Overview
The Future Spread Dashboard (FSPD) enables users to trade two-legged Spot/Future or Future/Future strategies in long-lived public auction Central Limit Order Book markets. Paradigm manages the availability of markets. In FSPD, all orders submitted are blind and are actionable by any user.
Deribit and Bybit are available as venues.
VRFQ - Brief Overview
Vault Request for Quote (VRFQ) enables vault providers to create short-lived private auction RFQ markets. In VRFQ, only the creator of the market is able to see the returned prices, the associated counterparty & is able to execute upon the market.
Ribbon is available as a venue.
Rate Limits
Desks cannot scale their rate limit capacity by using multiple Paradigm API Keys.
DRFQv2
RESToverHTTP requests are rate limited to 500 requests per second per desk across all API Keys. This applies to all types of requests and is not configurable per desk.
GRFQ
RESToverHTTP requests are rate limited to 500 requests per second per desk across all API Keys. This applies to all types of requests and is not configurable per desk.
FSPD
RESToverHTTP requests are rate limited per desk and type of request. [GET] requests are limited to 100 requests per second, while [POST] / [PATCH] / [DELETE] requests are limited to 10 requests per second. Paradigm is able to configure these limits upon request by the user.
Onboarding
Paradigm offers both test and production environments. We would love to create as many Paradigm test accounts as you would like.
Paradigm's servers are based in AWS eu-west-2
. You should ensure Paradigm's IPs have been added to your Settlement Venue API Credentials' IP whitelist.
We would love to create as many test environment accounts as you need. Please reach out to your account management representative or our technical solutions team with the following information:
- A unique email address in Paradigm's test environment with your First and Last Name.
- The "Firm" you would like the desk associated with (if you know).
API Connection URLs
Here are the base connection URLs for Paradigm's API interfaces & product suffixes to be concentated for requests.
Base URL | Live Environment
- RESToverHTTP:
https://api.prod.paradigm.trade
JSON-RPCoverWebSocket:
wss://ws.api.prod.paradigm.trade
FSPD only: RESToverHTTP:
https://api.fs.prod.paradigm.trade
FSPD only: JSON-RPCoverWebSocket:
wss://ws.api.fs.prod.paradigm.trade
Base URL | Test Environment
- RESToverHTTP:
https://api.testnet.paradigm.trade
JSON-RPCoverWebSocket:
wss://ws.api.testnet.paradigm.trade
FSPD only: RESToverHTTP:
https://api.fs.testnet.paradigm.trade
FSPD only: JSON-RPCoverWebSocket:
wss://ws.api.fs.testnet.paradigm.trade
Product & Version
- DRFQ:
/v2/drfq
- GRFQ:
/v1/grfq
- FSPD:
/v1/fs
- VRFQ:
/v1/vrfq
Test Environment Examples
- DRFQ - [GET]
/counterparties
- Example: [GET]https://api.testnet.paradigm.trade/v2/drfq/counterparties
DRFQ - WS Connection URL - Example:
wss://ws.api.testnet.paradigm.trade/v2/drfq?api-key=ABC123
GRFQ - [GET]
/rfqs/
- Example: [GET]https://api.testnet.paradigm.trade/v1/grfq/rfqs/
GRFQ - WS Connection URL - Example:
wss://ws.api.testnet.paradigm.trade/v1/grfq?api-key=ABC123
FSPD - [GET]
/instruments
- Example: [GET]https://api.fs.testnet.paradigm.trade/v1/fs/instruments
FSPD - WS Connection URL - Example:
wss://ws.api.fs.testnet.paradigm.trade/v1/fs?api-key=ABC123
VRFQ - [GET]
/rfqs/
- Example: [GET]https://api.testnet.paradigm.trade/v1/vrfq/rfqs/
VRFQ - WS Connection URL - Example:
wss://ws.api.testnet.paradigm.trade/v1/vrfq?api-key=ABC123
Helpful Reminders
- You CANNOT create RFQs, cross Orders, or trade against yourself on Paradigm.
- All instruments on Paradigm are the same instruments you trade on the underlying settlement venue. As such, this means that all instruments traded on Paradigm must conform to the contract specifications of the underlying settlement venue. Supported Venue & Instrument Contract Specifications
- You will need to use multiple desks associated with different settlement venue subaccounts if you wish to trade against yourself on Paradigm. You cannot use the same venue subaccount's venue API Credentials to trade against one's self even if use separate Paradigm desks.
Settlement Venue Testnet URLs
- Deribit's Testnet: test.deribit.com
- BIT's Testnet: beta.bitexch.dev
- Bybit's Testnet: testnet.bybit.com
High Level Implementation Notes
Your solution should
- Use the JSON-RPCoverWebSocket interface to receive real-time updates about events.
- For JSON-RPCoverWebSocket connections, ensure a
heartbeat
has been initiated and is being maintained. - Use the RESToverHTTP interface to interact with Paradigm.
- Wait for responses to RESToverHTTP requests to confirm successful or erroneous interactions.
- Ensure each request has the necessary authentication attributes as each request must be authenticated.
Your solution should not
- Use the RESToverHTTP interface to poll for event updates.
- Use the JSON-RPCoverWebSockets interface to send payload requests to Paradigm.
Taker Limits & Maker Protections
Paradigm enforces a number of limitations to ensure markets operate fairly and discourage negative practices. These limitations to specific user actions are at the sole discretion of Paradigm with changes communicated as they occur.
Taker Execution Limits
Taker Execution Limits limit the number of times Takers are able to execute upon markets in a rolling time window. Presently, this is one execution within a 2-second rolling window per product.
This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.
Taker Market Creation Limits
Taker Market Creation Limits limit the number of RFQs and Order Book markets users are able to create. Presently, users are able to create one market every three seconds on a rolling basis per product.
This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.
Market Maker Protection (MMP)
Market Maker Protection (MMP) protects Makers from rapid executions of orders in the market.
MMP is triggered when as a Maker two of your resting orders are executed upon within a one second rolling window.
When triggered:
- All of desks' existing Orders, for the product wherein the protection was triggered, are canceled by Paradigm.
- The desk is unable to create additional orders until the protection has been removed.
To remove this protection, users are able to immediately request the [PATCH] /v1/{product}/mmp/status/
endpoint. The protection is automatically removed within 10 seconds of triggered by Paradigm without any neccessary interaction by the user.
This feature is enabled for all Paradigm users and cannot be disabled. The conditions of MMP being triggered cannot be configured by the user.
This applies only to products apart of Unified Markets, specifically DRFQ & GRFQ.
Errors
All RESToverHTTP error responses follow the same basic format. An Error object is returned in response to an erroneous RESToverHTTP request, accompanied by an HTTP status code of 400.
Specific error codes are listed with each RESToverHTTP endpoint.
Error Object
An example of an erroneous Response message
{
"code": 1002,
"message": "Invalid enumeration set value",
"data": {
"member": "side",
"value": "CROSS"
}
}
The Error object is expressed as a single JSON Object, with the following members:
Member | Type | Req | Description |
---|---|---|---|
code | number | Y | The type of error that occurred. |
message | string | Y | A short description of the error. |
data | object | N | Additional structured information about the error. The value is determined by the specific member invoked and may not be present if the error does not require it. |
Error Codes
The following general error codes are supported by Paradigm:
Code | Message | Meaning |
---|---|---|
-32700 | Parse error | Invalid JSON received by the server. |
-32600 | Invalid Request | The JSON sent is not a valid Request object. |
-32601 | Method not found | The method does not exist / is not available. |
-32602 | Invalid params | Invalid method parameter(s). |
-32603 | Internal error | Internal JSON-RPC error. |
429 | Desk's ratelimit reached. Expected available in 1 second. | Refer to Rate Limit section above. |
1001 | Insufficient permissions | The user does not have sufficient permissions to execute the method. |
1002 | Invalid enumeration set value | The enumeration set value is invalid for the specified field. |
Authentication
All Paradigm API endpoints are considered private and require authentication.
Paradigm uses token-based authentication for API access to both the RESToverHTTP and JSON-RPCoverWebSocket API endpoints.
As an additional protection measure against replay attacks in environments where SSL trust is not properly configured, Paradigm requires all RESToverHTTP requests to be signed using your Paradigm API Key's <secret-key>
.
Important Notes:
- Paradigm does not currently provide fine-grained token scopes or permissions. Please ensure your API credentials are stored securely.
- If you have an IP whitelist set for your Venue API Keys, on the Venue, you will need to include Paradigm's IP addresses in your Venue API Key whitelists.
There are a number of Authentication methods available across both the RESToverHTTP and JSON-RPCoverWebSocket interfaces, these include:
- Token-based Authentication
- HTTP Header
- Cookie
- Query String Parameter (JSON-RPCoverWebSocket only)
Error Codes
The following error codes relate to Authentication Errors:
Code | Message | Meaning |
---|---|---|
401 | API Key is not enabled or has been revoked. | Paradigm API Key is Inactive or has been Deleted. |
401 | Invalid API Access Key. | Paradigm API Access Key is invalid or incorrect. |
403 | Request signature verification failed. | Paradigm API Secret Key is invalid, incorrect or you have not properly created the signature. |
Generating a Paradigm API Key
Before accessing any RESToverHTTP or JSON-RPCoverWebSocket API endpoints, you must generate the necessary Paradigm API credentials. This can be accomplished via the Paradigm Admin Dashboard.
You use the same Paradigm API <access-key>
& <secret-key>
to authenticate requests for all Paradigm products.
Live Environment
Paradigm Admin Dashboard URL: https://admin.paradigm.trade/
Test Environment
Paradigm Admin Dashboard URL: https://admin.testnet.paradigm.trade/
Once Created
When you have generated Paradigm API credentials, you will be presented with two keys:
- Access Key: used to authenticate the API.
- Secret Key: used to sign requests against the API.
Be sure to save these two keys somewhere secure as both the Access Key and the Secret Key will only be visible once during creation.
If you lose either the <access-key>
or the <secret-key>
, you will need to generate a new Paradigm API Key via the Admin Dashboard.
Token-based Authentication
Only the <access-key>
is needed for authenticating requests. The different methods are presented below in order of our preference.
HTTP Header
Authorization example with an HTTP Header
{
"Authorization": "Bearer SXDlhLKYX6GH6InhBxcCzoW4"
}
When possible, authentication should be performed using the Authorization HTTP header. The header should supply the Paradigm API <access-key>
in plain text, preceded by the text "Bearer ".
Authorization: Bearer <access-key>
Cookie
In some cases, providing custom HTTP headers may not be possible. This is particularly true when connecting to JSON-RPCoverWebSockets via browser APIs.
In these cases, the Paradigm API Key Access Key may be provided by a special HTTP cookie. The cookie should be defined as follows:
Paradigm-API-Key = <access-key>
Query String Parameter (for JSON-RPCoverWebSocket connections only)
In the unlikely scenario that you are unable to use HTTP headers or Cookies for authentication against the JSON-RPCoverWebSocket API, Paradigm supports a special HTTP query parameter.
The query parameter can be provided as part of the WebSocket connection URL.
Live Environment | URL Examples
DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.prod.paradigm.trade/v2/drfq/?api-key=<access-key>
GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.prod.paradigm.trade/v1/grfq/?api-key=<access-key>
VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.prod.paradigm.trade/v1/vrfq/?api-key=<access-key>
FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.prod.paradigm.trade/v1/fs/?api-key=<access-key>
Test Environment | URL Examples
DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v2/drfq/?api-key=<access-key>
GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/grfq/?api-key=<access-key>
VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/vrfq/?api-key=<access-key>
FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.testnet.paradigm.trade/v1/fs/?api-key=<access-key>
Signing Requests
Paradigm requires all RESToverHTTP requests to be signed.
GET RESToverHTTP example demonstrating signing of requests
# A GET RESToverHTTP sample demonstrating the generation of signatures and signing of requests.
import base64
import hmac
import time
from urllib.parse import urljoin
import requests
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
access_key = '<access-key>'
secret_key = '<secret-key>'
host = 'https://api.testnet.paradigm.trade'
# GET example
method = b'GET'
path = b'/v1/drfq/instruments/?venue=DBT&asset=BTC'
body = b''
timestamp, signature = sign_request(secret_key, method, path, body)
headers = {
'Authorization': 'Bearer {}'.format(access_key),
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
}
url = urljoin(host, path.decode())
response = requests.get(url, headers=headers)
print(response.status_code)
print(response.text)
POST RESToverHTTP example demonstrating signing of requests
# A POST RESToverHTTP sample demonstrating the generation of signatures and signing of requests.
import base64
import hmac
import json
import time
from urllib.parse import urljoin
import requests
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
access_key = '<access-key>'
secret_key = '<secret-key>'
host = 'https://api.testnet.paradigm.trade'
# POST example
method = b'POST'
path = b'/v1/echo/'
data = {'message': 'hello'}
body = json.dumps(data).encode('utf-8')
timestamp, signature = sign_request(secret_key, method, path, body)
headers = {
'Authorization': 'Bearer {}'.format(access_key),
'Paradigm-API-Signature': signature,
'Paradigm-API-Timestamp': timestamp,
'Accept': 'application/json',
}
url = urljoin(host, path.decode())
response = requests.post(url, headers=headers, json=data)
print(response.status_code)
print(response.text)
Important Note: Signing is not currently supported for JSON-RPCoverWebSocket API endpoints.
Request signatures are generated by applying the HMAC-SHA256 function to your Paradigm API <secret-key>
and a concatenated message consisting of the request timestamp, request method, request path, query parameters, and body. The key provided to the HMAC function must be the base64-decoded version of the <secret-key>
. The signature must then be base64-encoded and passed via a special header value.
Some important considerations are:
- The timestamp must be a UNIX timestamp (milliseconds since epoch in UTC).
- The request method must be capitalized (e.g.
GET
). - The request path must include the entire base path of the request (e.g.
/rfq/
). - The request parameters must include
?
(e.g.?cursor=a2Ed&venue=DBT
) unless none are used. - The request body should be substituted with an empty string for
GET
requests.
Once the signature is generated, the timestamp and signature should be provided as HTTP headers:
Header Name | Header Value |
---|---|
Paradigm-API-Signature | The generated signature |
Paradigm-API-Timestamp | The timestamp used when generating the signature |
Note: Signed requests are only valid for 30 seconds from when the timestamp is captured. Requests received after the 30-second window are rejected.
JSON-RPC over WebSocket
JSON-RPC
JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. It uses JSON (RFC 4627) as the data format.
All member names exchanged between the Client and the Server that are considered for matching of any kind should be considered to be case-sensitive. The Client is defined as the origin of Request objects and the handler of Response objects. The Server is defined as the origin of Response objects and the handler of Request objects. A trader using the API can fill both the role of the Client and the Server depending on the Request.
Error Codes
The following error codes relate to establishing a JSON-RPCoverWebSocket connection:
Code | Meaning |
---|---|
HTTP 403 | An invalid or incorrect Paradigm API Access Key was used to authenticate the JSON-RPCoverWebSocket connection. |
HTTP 403 | Incorrect connection query string used. |
Cancel on Disconnect
Cancel on Disconnect mode is enabled on all JSON-RPCoverWebSocket connections by default and must be specifed as false
to disable.
In Unified Markets:
* Cancel on Disconnect will cancel all OPEN
created RFQ markets.
* Cancel on Disconnect will cancel all OPEN
created Orders in DRFQ, GRFQ, and VRFQ.
In FSPD:
* Cancel on Disconnect will cancel all OPEN
created Orders.
Cancel on Disconnect mode will cancel all created RFQs & Orders that have been requested with the same Paradigm API Key used to authenticate the WebSocket connection & will only trigger when all associated WebSocket connections disconnect.
Connection String Examples
To disable Cancel on Disconnect mode, specify cancel_on_disconnect=false
as a query string parameter in the connection URL to the JSON-RPCoverWebSocket interface.
DRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v2/drfq/?api-key=<access-key>&cancel_on_disconnect=false
GRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/grfq/?api-key=<access-key>&cancel_on_disconnect=false
VRFQ - JSON-RPCoverWebSocket Connection URL: wss://ws.api.testnet.paradigm.trade/v1/vrfq/?api-key=<access-key>&cancel_on_disconnect=false
FSPD - JSON-RPCoverWebSocket Connection URL: wss://ws.api.fs.testnet.paradigm.trade/v1/fs/?api-key=<access-key>&cancel_on_disconnect=false
Request Objects
An example of a JSON-RPCoverWebSocket Request message
{
"id": "1",
"jsonrpc": "2.0",
"method": "subscribe",
"params": {
"channel": "rfq"
}
}
An RPC call is represented by sending a Request object to a Server.
The Request object has the following members:
Member | Type | Req | Description |
---|---|---|---|
id | string or number | N | An identifier established by the Client. The id is omitted if the method is a Notification. |
jsonrpc | string | Y | The version of the JSON-RPC protocol. Always "2.0". |
method | string | Y | The name of the method to be invoked. |
params | object | N | The parameter values to be used during the invocation of the method. This field may be omitted if the method has no parameters. |
Response Objects
An example of a Successful Response message
{
"id": "1",
"jsonrpc": "2.0",
"result": [
"rfq",
"trade"
]
}
An example of an Erroneous Response message
{
"id": "1",
"jsonrpc": "2.0",
"error": {
"code": -32601,
"message": "method not found",
"data": {
"method": "unsubscribe-all",
"timestamp": 1597326842.415
}
}
}
When an RPC call is made, the Server replies with a Response, except for in the case of Notifications. The Response is expressed as a single JSON Object, with the following members:
Member | Type | Req | Description |
---|---|---|---|
id | string or number | N | The same value of the id field specified on the Request object. The value is null if there is an error parsing the Request object. The value is omitted in a Notification. |
jsonrpc | string | Y | The version of the JSON-RPC protocol. Always "2.0". |
result | object | N | The result of a successful request. The value is determined by the specific method invoked. Not present if there is an erroneous result. |
error | Error object | N | The result of an erroneous request. Not present if there is a successful result. |
> code | number | N | Error code. |
> message | string | N | Error message. |
> data | object | N | Array of information relating to error. |
>> method | string | N | Erroneous request method. |
>> timestamp | decimal | N | The time the error occurred as the number of unix milliseconds since epoch (January 1, 1970). |
Session Methods
heartbeat
An example of a JSON-RPCoverWebSocket heartbeat Request Object
{
"id": 1,
"jsonrpc": "2.0",
"method": "heartbeat"
}
An example of a JSON-RPCoverWebSocket heartbeat Response Object
{
"id": 1,
"jsonrpc": "2.0"
}
The client is required to regularly send heartbeat Requests to the user over a WebSocket connection at least once every 10 seconds.
If the user does not send a heartbeat in a given 10-second window, the WebSocket connection will be closed by Paradigm.
Paradigm will respond to a heartbeat Request with a heartbeat Response.
Note: The Request does not have a params object and the Response does not have a results object.
Error Codes
The following error code relates to maintaining a heartbeat:
Code | Meaning |
---|---|
4005 | Paradigm did not receive a heartbeat from the WebSocket connection within the past 10 seconds. |
Subscription Methods
Subscriptions work as Notifications, so users will automatically (after subscribing) receive messages from the server.
They are the primary means through which you should intend to receive updates regarding RFQs, Quotes, Orders (GRFQ+FSPD) and Trades.
Subscriptions are only available through WebSockets as these are sent asynchronously from Paradigm to the user as they happen.
Subscription Notification objects have the following members:
Member | Type | Req | Description |
---|---|---|---|
jsonrpc | string | Y | Always "2.0" . |
method | string | Y | Always subscription . |
params | object | Y | Array of returned data. |
> channel | string | Y | The name of the channel. |
> data | object | Y | Data specific to the channel. |
subscribe
An example of a
subscribe
Request Object
{
"id": 123,
"jsonrpc": "2.0",
"method": "subscribe",
"params": {
"channel": "rfq"
}
}
An example of a
subscribe
Response Object
{
"id": 123,
"jsonrpc": "2.0",
"result": [
"rfq",
"trade"
]
}
For DRFQ, there are four subscription channels you can subscribe to: rfq
, quote
, trade
, and trade_confirmation
.
For GRFQ, there are six subscription channels you can subscribe to: rfq
, quote_book
, order
, quote
, trade
, and trade_tape
.
For VRFQ, there are three subscription channels you can subscribe to: rfq
, quote
, and trade
.
For FSPD, there are six subscription channels you can subscribe to: strategy_state.{venue}.{kind}
, order_book.{strategy_id}.{level}
, orders.{venue}.{kind}.{strategy_id}
, trades.{venue}.{kind}.{strategy_id}
, trade_tape.{venue}.{kind}.{strategy_id}
, and venue_bbo.{strategy_id}
.
To subscribe to multiple channels, send a separate subscribe request for each channel.
Note: The Response result is a JSON array of all channels currently subscribed to (DRFQ+GRFQ).
The Request params object has the following members:
Member | Type | Req | Description |
---|---|---|---|
channel | string | Y | The channel to subscribe to. |
data | object | N | An channel-specific object that specifies parameters for the channel. |
unsubscribe
An example of an
unsubscribe
Request Object
{
"id": 123,
"jsonrpc": "2.0",
"method": "unsubscribe",
"params": {
"channel": "rfq"
}
}
An example of an
unsubscribe
Response Object
{
"id": 123,
"jsonrpc": "2.0",
"result": [
"trade"
]
}
To unsubscribe from multiple channels, send a separate unsubscribe request for each channel.
Note: The Response result is a JSON array of all channels currently subscribed to.
The Request params object has the following members:
Member | Type | Req | Description |
---|---|---|---|
channel | string | Y | The channel to unsubscribe from. |
Notification Channels
A Notification is a Request object without an id
member. A Request object that is a Notification signifies the Client's lack of interest in the corresponding Response object, and as such no Response object needs to be returned to the client. The Server must not reply to a Notification, including those that are within a batch request.
Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such, the Client would not be aware of any errors (like e.g. "Invalid params", "Internal error").
Key Note: DRFQ, GRFQ, VRFQ, and the FSPD are separate products with separate JSON-RPCoverWebSocket connection URLs & subscriptions required. You must subscribe to the specific channels of each product you would like to receive notifications for.
DRFQv2 WebSocket Notification Channels
DRFQ JSON-RPCoverWebSocket notification channels are:
rfqs
- Private Updates relating to the availability of the RFQ market.rfq_orders
- Private Updates relating to the available Orders upon RFQ markets.orders
- Private Updates relating to the creation, cancellation and interactions of the user's Orders.trades
- Private Updates relating to success or rejection of a the user's Trades.bbo.{rfq_id}
- Public Updates relating to the prices+amounts of the RFQ's composite instruments from the underlying settlement venue.market_maker_protection
- Private Updates relating to Market Maker Protection being triggered.
GRFQ WebSocket Notification Channels
GRFQ JSON-RPCoverWebSocket notification channels are:
rfq
- Public Updates relating to the creation and expiration of RFQs.quote_book
- Public Updates relating to the creation and availability of Quotes.order
- Private Updates relating to the creation and execution of Orders upon Quotes.quote
- Private Updates relating to creation, execution, and cancellation of Quotes upon RFQs.trade
- Private Updates relating to executions solely involving the Taker and Maker.trade_tape
- Public Updates relating to all completed Trades on Paradigm through GRFQ.market_maker_protection
- Private Updates relating to Market Maker Protection being triggered.
VRFQ WebSocket Notification Channels
VRFQ JSON-RPCoverWebSocket notification channels are:
rfq
- Public Updates relating to the creation and expiration of RFQs.quote
- Private Updates relating to creation, execution, and cancellation of Quotes upon RFQs.trade
- Private Updates relating to executions solely involving the Taker and Maker.
FSPD WebSocket Notification Channels
FSPD JSON-RPCoverWebSocket notification channels are:
strategy_state.{venue}.{kind}
- Public Updates relating to the creation, settlement, and expiration of Strategies.order_book.{strategy_id}.{level}
- Public Updates relating to delta of Orders being added and removed from the Order Book.orders.{venue}.{kind}.{strategy_id}
- Private Updates relating to the creation, cancellation and interactions of the user's Orders.trades.{venue}.{kind}.{strategy_id}
- Private Updates relating to success or rejection of a the user's Trades.trade_tape.{venue}.{kind}.{strategy_id}
- Public Updates relating to all completed Trades on Paradigm through FSPD.venue_bbo.{strategy_id}
- Public Updates relating to the prices+amounts of the Strategies' composite instruments from the underlying settlement venue.
Shared - REST Endpoints
The following REST Endpoints have no version or product identifier in the Connection URL as they are shared across the Paradigm API.
[POST] /echo/
/echo/ Request example
# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v1/echo/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
const inputBody = `{"message": "string"}`;
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer <access-key>'
};
fetch('https://api.testnet.paradigm.trade/v1/echo/',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
from urllib.parse import urljoin
import json
# installed
import requests
access_key = '<access-key>'
secret_key = '<secret-key>'
signing_key = base64.b64decode(secret_key)
print('Paradigm Account Access Key: {}'.format(access_key))
print('Paradigm Account Secret Key: {}'.format(signing_key))
# Request Body
host = 'https://api.testnet.paradigm.trade'
# POST /echo/
method = 'POST'
path = '/v1/echo/'
body = b''
payload = {
"message": "this is a test echo message"
}
json_payload = json.dumps(payload).encode('utf-8')
message = method.encode('utf-8') + b'\n'
message += path.encode('utf-8') + b'\n'
message += json_payload
timestamp = str(int(time.time() * 1000))
message = timestamp.encode('utf-8') + b'\n' + message
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.post(urljoin(host, path),
headers=headers,
json=payload)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Authorization": []string{"Bearer <acces-key>"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("POST", "https://api.testnet.paradigm.trade/v1/echo/", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
/echo/ Response example
{
"message": "this is a test echo message"
}
A [POST] /echo/
request returns the message specified in the request.
It is designed to allow users to test their authentication as well as connection to Paradigm's API.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | object | true | none |
message | body | string | false | none |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
message | string | true | Returns the string from the request. |
Shared - WebSocket Notification Channels
market_maker_protection
An example of MMP being triggered
{
"jsonrpc":"2.0",
"method":"subscription",
"params": {
"channel": "market_maker_protection",
"data": {
"kind": "TRIGGERED"
}
}
}
An update is sent to the market_maker_protection
WebSocket Notification Channel when MMP has been triggered. There is no message published when it has been reset by the user or the system.
You must subscribe to this channel using the Connection URL with the Version and Product URL suffix of the respective products below. For example: wss://ws.api.testnet.paradigm.trade/v1/grfq
.
If MMP is triggered from the DRFQ product, you will be notified on the market_maker_protection
channel even if you subscribed using the GRFQ Version and Product URL.
The response "params" data object has the following members:
Member | Type | Req | Description |
---|---|---|---|
channel | string | Y | The notification channel the message was delivered upon. |
data | array | Y | |
> kind | string | Y | Status of MMP. Valid values include TRIGGERED . |
DRFQv2 - API Workflows
In our test environment, Paradigm runs "Auto Market Makers". These desks, when included as counterparties in RFQs, will return + update prices and you are able to cross. This allows RFQ Creators to experience the end to end workflow.
Their desk names are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2". They are a part of the LP
counterparty list returned from [GET] /counterparties
.
DRFQv2: High Level
RFQ Creators are referred to as Taker's and receivers of RFQs are referred to as Maker's throughout the documentation.
DRFQv2 is centred around the concepts of "RFQs", "Orders" and "Trades":
- RFQs are created by a single desk, the Taker, and are composed of one or more legs with attributes defined by the creator.
- Makers, who are included as counterparties in the RFQ, are able to submit Orders with leg pricing.
- Takers are able to submit an order with a LIMIT price to cross an existing Maker order.
- Trades occur when a Taker submits a crossing Order and the trade is sent to the underlying settlement venue for clearing.
At a high level, the DRFQv2 workflow is:
- Taker creates an RFQ and chooses which counterparties to send it too.
- Maker(s) submits an order to the RFQ.
- Taker receives the order(s).
- Taker submits an order with a crossing price and the trade is sent for clearing on the underlying settlement venue.
- Taker & Maker receive confirmation that the trade has been successfully cleared or rejected at clearing by the underlying settlement venue.
Notes:
- Users who create the RFQ are regarded as the Taker in the trade by Paradigm and the underlying settlement venue.
- RFQ Markets have "Price" then "Time" matching prioritization. Meaning two Orders with the same price, but different
created_at
time attributes will result in the Order with the earliercreated_at
attribute having priority. - Paradigm expires RFQs which do not trade after 5 minutes from creation.
Key DRFQv2 Concepts
In DRFQv2,
- Specific counterparties must be selected by the Taker to participate in the RFQ.
- There are NO partial fills. Makers must submit orders with corresponding order sizes that match the RFQ's
quantity
attribute. - There is NO concept of a Order Book or a public auction. Only the RFQ creator is able to see all of the Makers' returned orders.
- Takers can choose to create an RFQ on a disclosed or an anonymous basis.
- Makers can NOT choose to submit Orders on an anonymous basis.
- It is possible for a Trade to be rejected at clearing by the underlying settlement venue.
DRFQv2: Taker's Perspective
- Taker creates an RFQ using [POST]
/rfqs
. You can pull available instruments from [GET]/instruments
and counterparties from [GET]/counterparties
. - Taker is able to cancel an RFQ if they wish to do so with [DELETE]
/rfqs/{rfq_id}
. - Maker, who is a requested counterparty to the RFQ, and is notified over the
rfqs
JSON-RPCoverWebSockets Notification channel, is then able to submit an order to the RFQ. - Taker, who will be notified of RFQ Orders on the
rfq_orders
JSON-RPCoverWebSockets Notification channel, is able to attempt to cross by submiting an order using [POST]/orders
. - Taker will receive updates about the state of their order via the
orders
JSON-RPCoverWebSockets Notification channel. - Taker will receive clearing finality via the
trades
JSON-RPCoverWebSockets Notification channel where the result can either be success or rejection.
DRFQv2: Maker's Perspective
- Taker will create an RFQ and the Maker will be notified on the
rfqs
JSON-RPCoverWebSockets Notification channel. - Maker is able to create an order using [POST]
/orders
. - Maker is able to cancel an existing order with [DELETE]
/orders
or [DELETE]/orders/{order_id}
. - Taker submits a crossing Order that matches with the Maker's existing order.
- Maker will receive updates about the state of their order via the
orders
JSON-RPCoverWebSockets Notification channel. - Maker will receive clearing finality via the
trades
JSON-RPCoverWebSockets Notification channel where the result can either be success or rejection.
DRFQv2: Maker managing Orders
- Each RFQ has a
side_layering_limit
attribute which communicates to Makers how many orders per side they are able to have with astate
==OPEN
at any one time. By default, and Takers are not able to configure this, all RFQs for the moment will have aside_layering_limit
==1
. Therefore, Makers are only able to have 1xstate
==OPEN
order per side per RFQ at any point in time. - Users are able to create Orders via [POST]
/orders
. - Users are able to replace existing Orders via [PUT]
/orders/{order_id}
. - Users are able to cancel an Order via [DELETE]
/orders/{order_id}
. - Users are able to cancel all Orders via [DELETE]
/orders
. - Creating and replacing Orders will always return with a
state
==PENDING
in response to the RESToverHTTP request. This indicates the Order is being processed by the matching engine. The Order only becomes actionable by any user when it'sstate
value changes toOPEN
. This is communicated via theorders
JSON-RPCoverWebSockets Notification channel. - Replacing an Order is an atomic Cancel & Create request in the system. This means the original Order will lose it's time priority.
DRFQv2: Taker managing an RFQ's Orders
As a Taker, the desk who has created the RFQ, you will receive Orders from the Makers associated with the RFQ.
This pattern describes how as a Taker to build/store/manage Orders from Makers in relation to your RFQ:
- Subscribe to the
rfq_orders
JSON-RPCoverWebSockets WebSockets Notifications channel. Store all of the received events. - Request the [GET]
/rfqs/{rfq_id}/orders
endpoint for the specific RFQ to return allOPEN
associated Orders. - Apply the received events for the associated
{rfq_id}
to associated group of Orders from the previous step. - From the
rfq_orders
JSON-RPCoverWebSockets WebSockets Notifications channel, when you receive anevent
==ADDED
, add this order to your storage of RFQ Orders. - From the
rfq_orders
JSON-RPCoverWebSockets WebSockets Notifications channel, when you receive anevent
==REMOVED
, add this order to your storage of RFQ Orders.
Updates about an RFQ's Orders are communicated via the rfq_orders
JSON-RPCoverWebSockets WebSockets Notifications channel. They are communicated in a manner most similar to that of an Order Book with a depth of L3
. As such, you will find your system adding and removing specific associated orders. At the present moment, partial fills are not possible and your system will not receive any update messages.
DRFQv2: Consequences of a Trade Rejection
All trades on Paradigm are submitted as "Block Trades" to the underlying settlement venue. The two key characteristics of "Block Trades" are atomicity of clearing and either complete success or rejection at clearing. As such, when Paradigm submits a "Block Trade" to an underlying settlement venue, all legs must successfully clear or the entire "Block Trade" is rejected.
With this being said, when two orders cross on Paradigm, Paradigm submits a "Block Trade" to the underlying settlement venue for clearing. Two orders crossing in DRFQv2 will result in each Orders state
== CLOSED
and a Trade object with the state
== PENDING_SETTLEMENT
. If the trade successfully clears, both the Taker and the Maker will receive a Trade message with the state
== FILLED
, if not, state
== REJECTED
.
In the event of a successful trade, the positions will appear in your underlying settlement account. In the event of a rejected trade, the positions will NOT appear in your underlying settlement account.
DRFQv2: Enums & Explanations
There are six resources present through the DRFQv2 API. They are the Instrument, RFQ, Order, RFQ Orders, Trade, and Trade Tape resources.
Users are able to engage with Paradigm via the RESToverHTTP and JSON-RPCoverWebSockets interfaces.
Resources have a state
attribute which denotes the status or availability of the object.
The JSON-RPCoverWebSockets interface publishes messages which include an event
key to help communicate what update the message is referring too.
DRFQv2: Instrument
This information is available from the RESToverHTTP inferface, but not the JSON-RPCoverWebSockets interface.
Valid state
values include ACTIVE
, EXPIRED
.
There are no valid event
values as there is no corresponding WebSockets Notifications channel.
Instrument objects with the following state
values, mean the following things to users:
- An Instrument is instantiated as
ACTIVE
when made available to trade by Paradigm. - An Instrument becomes
EXPIRED
when it reaches settlement or is no longer available to trade upon Paradigm.
The Instrument state
enums can only transition from ACTIVE
-> EXPIRED
.
DRFQv2: RFQ
This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.
Valid state
values include OPEN
, CLOSED
.
Valid event
values include ADDED
, REMOVED
.
RFQ objects with the following state
values, mean the following things to users:
- An RFQ is instantiated as
OPEN
when it is available to be actioned by users. - An RFQ becomes
CLOSED
when it is no longer actionable by any user.
Published via the rfqs
JSON-RPCoverWebSockets notifications channel, event
values mean the following to users:
ADDED
indicates a new RFQ is available to be actioned.REMOVED
indicates an existing RFQ is no longer available to be actioned.
DRFQv2: Order
This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.
Users are strongly encouraged to use the quantity
, pending_fill_quantity
, canceled_quantity
, filled_quantity
attributes of an Order to be certain of the value at risk.
Valid state
values include PENDING
, OPEN
, CLOSED
.
Valid event
values include NEW
, CANCELED
, PENDING_FILL
, FILLED
.
Order objects with the following state
values, mean the following things to users:
- An Order is instantiated as
PENDING
when it is being processed by the Paradigm matching engine. - An Order becomes
OPEN
when it is available to be actioned by users. - An Order becomes
CLOSED
when it is no longer actionable by any user.
Published via the orders
JSON-RPCoverWebSockets notifications channel, event
values mean the following to users:
NEW
indicates a new order is available to be actioned by the user.CANCELED
indicates an existing order has been canceled by the user or is apart of a trade rejection.PENDING_FILL
indicates an order is in the process of being cleared as apart of a trade by the underlying settlement venue.FILLED
indicates an order's quantity has been completed filled and there is no more available amount to trade.
DRFQv2: RFQ Orders
This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.
There are no valid state
values as the RFQ Orders resource solely communicates actionable Maker Orders to the Taker.
Valid event
values include ADDED
, REMOVED
, UPDATED
.
Published via the rfq_orders
JSON-RPCoverWebSockets notifications channel, event
values mean the following to users:
ADDED
indicates a new Order upon an RFQ is available to be actioned.REMOVED
indicates an existing Order upon an RFQ is no longer available to be actioned.UPDATED
indicates an existing Order upon an RFQ has had an attribute updated.
DRFQv2: Trade
This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.
Valid state
values include PENDING_SETTLEMENT
, FILLED
, REJECTED
.
Valid event
values include PENDING_SETTLEMENT
, FILLED
, REJECTED
.
Trade objects with the following state
values, mean the following things to users:
- A Trade is instantiated as
PENDING_SETTLEMENT
when it is being cleared by the underlying settlement venue. - A Trade becomes as
FILLED
when it is has reached settlement finality and has been successfully cleared by underlying settlement venue. - A Trade becomes
REJECTED
when it is has reached settlement finality and has been rejected at clearing by underlying settlement venue.
Published via the trades
JSON-RPCoverWebSockets notifications channel, event
values mean the following to users:
PENDING_SETTLEMENT
indicates a trade is being cleared by the underlying settlement venue.FILLED
indicates a trade has reached settlement finality and has been successfully cleared by the underlying settlement venue.REJECTED
indicates a trade has reached settlement finality and has been rejected at clearing by the underlying settlement venue.
DRFQv2: Trade Tape
This information is available from both the RESToverHTTP and the JSON-RPCoverWebSockets interfaces.
Valid state
values include FILLED
.
Valid event
values include FILLED
.
Trade Tape objects with the following state
values, mean the following things to users:
- A Trade Tape is instantiated as
FILLED
given it has reached settlement finality and been successfully cleared by the underlying settlement venue.
Published via the trade_tape
JSON-RPCoverWebSockets notifications channel, event
values mean the following to users:
FILLED
indicates a trade has reached settlement finality and been successfully cleared by the underlying settlement venue.
DRFQv2: Differences to DRFQv1
DRFQv1 was released at the beginnning of 2021 when both Paradigm & crypto were in very different places to where they are today. DRFQv1 was built in response to direct user feedback and was an iteration upon our first product; "Chat". "Chat" required users to bilaterally negotiate with multiple counterparties the same structure for each trade. As such, DRFQv1 (or MDRFQ), was created to solve this user problem.
With time, DRFQv1 has becoming increasingly slow, but has also become increasingly challenging to extend & to deliver the functionality requested by users today. As such, DRFQv2 has been created to address the existing performance & feature challenges of DRFQv1, but to also enable rapid solutions to future user requests.
DRFQv2 includes many of the elements of other Paradigm products, such as FSPD & GRFQ, that users have expressed positive feedback about. The intentions of DRFQv2 are threefold:
- To remedy the decreasing performance of DRFQv1.
- To include product functionality missing, but frequently requested & required by users.
- To provide an experience more akin to that of FSPDs & GRFQ + crypto exchanges. The intention is to reduce the amount of integration work required for users stemming from critically different workflows and patterns between both Paradigm products as well as the broader space.
With that said, the DRFQv2 API workflow is incredibly similar to that of what users are used to interacting with in FSPDs & GRFQ and also crypto exchanges.
Some small notes:
- CME is only available for the DRFQv1 API and NOT the DRFQv2 API. CME is not available as a venue yet in the Unified Markets interface.
- It is no longer possible to customize the expiration period of RFQs as you could in DRFQv1. They are now set by default to be approximately five minutes.
- The DRFQv1 [POST]
/quote/create
expires_in
key now only accepts the following values30
,60
,90
. - RFQs' legs are denominated by a ratio. These values must have a precision or less of 12 values for Options and 17 values for Futures.
- It is no longer possible to create RFQs with a single
SELL
sided leg. Single-legged RFQs must have aside
==BUY
.
DRFQv2: DRFQv1 Support
DRFQv1 will continue to be supported for an extended period of time. A deprecation timeline will be communicated and the result of feedback & consensus of users.
Existing users of DRFQv1 will be able to continue until such a time without any disruption or changes required to existing systems.
The core motivations for existing DRFQv1 users to integrate with DRFQv2 are:
- Significantly improved relative performance.
- Access to newly supported Venues and Contract Types.
- Access to new product features and functionality.
If you have any questions, we strongly recommend you reach out to your account manager as we would greatly appreciate any feedback.
DRFQv2 - Code Examples
Reach out if you ever need any help! We are more than happy to help.
You will need to update the provided Code Examples with your own Paradigm Access Key and Secret Key.
You can find all existing examples on our GitHub: https://github.com/tradeparadigm/code-samples
Note: All examples in this section are in Python3.
DRFQv2: JSON-RPCoverWebSockets
DRFQv2: Authentication + Heartbeat + Subscribe to Notification Channel
Authenticate, establish & maintain a heartbeat and subscribe rfqs
JSON-RPCoverWebSockets Notification Channel.
DRFQv2: Auto Market Maker
We encourage you to RFQ all counterparties marked as an "LP" from the [GET] /counterparties
as this includes all of Paradigm's Auto Market Makers.
The desk names of some Auto Market Makers are "DSK2", "DSK3", "DSK4", "DSK5", and "MT2" on the Test environment.
To note, this is purely a QA tool and not in any way to be used as apart of a trading system.
You can download the Auto Market Maker from here.
DRFQv2: Auto Market Taker
The Auto Market Taker will create random RFQ structures and cross them. You will need to update the counterparties you wish to RFQ (ie your desk acting as a Maker).
To note, this is purely a QA tool and not in any way to be used as apart of a trading system.
You can download the Auto Market Taker from here.
DRFQv2 - WebSocket Notification Channels
DRFQv2: rfqs
An example, as the RFQ Creator,
role
==TAKER
, whenstate
==OPEN
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfqs",
"data":{
"account_name":"ParadigmTestNinetyFive",
"base_currency":"BTC",
"clearing_currency":"USD",
"closed_reason":"None",
"counterparties":[
"DSK3",
"DSK2"
],
"created_at":1670473243746.937,
"description":"Future 16 Dec 22",
"expires_at":1670473543747.062,
"id":"r_2IcG1WoqoCCtjA0C0EhJxotCSu2",
"is_taker_anonymous":true,
"kind":"FUTURE",
"label":"None",
"last_trade":"None",
"last_updated_at":1670473243747.062,
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"quantity":"200000",
"quote_currency":"USD",
"role":"TAKER",
"side_layering_limit":1,
"state":"OPEN",
"strategy_code": "FT",
"strategy_description":"CF_BTC-16DEC22",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"DSK95",
"venue":"DBT"
},
"event":"ADDED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, as the RFQ Creator,
role
==TAKER
, whenstate
==CLOSED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfqs",
"data":{
"account_name":"ParadigmTestNinetyFive",
"base_currency":"BTC",
"clearing_currency":"USD",
"closed_reason":"CANCELED_BY_CREATOR",
"counterparties":[
"DSK3",
"DSK2"
],
"created_at":1670473243746.937,
"description":"Future 16 Dec 22",
"expires_at":1670473581046.396,
"id":"r_2IcG1WoqoCCtjA0C0EhJxotCSu2",
"is_taker_anonymous":true,
"kind":"FUTURE",
"label":"None",
"last_trade":"None",
"last_updated_at":1670473281046.396,
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"quantity":"200000",
"quote_currency":"USD",
"role":"TAKER",
"side_layering_limit":1,
"state":"CLOSED",
"strategy_code":"FT",
"strategy_description":"CF_BTC-16DEC22",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"DSK95",
"venue":"DBT"
},
"event":"REMOVED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, as an RFQ receiver,
role
==MAKER
, whenstate
==OPEN
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfqs",
"data":{
"account_name":null,
"base_currency":"BTC",
"clearing_currency":"USD",
"closed_reason":"None",
"counterparties": [],
"created_at":1670473348810.261,
"description":"Future 16 Dec 22",
"expires_at":1670473648810.403,
"id":"r_2IcGEiv9eQEA1CU4H1hfe9ZogAJ",
"is_taker_anonymous":true,
"kind":"FUTURE",
"label":"None",
"last_trade":"None",
"last_updated_at":1670473348810.403,
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"quantity":"200000",
"quote_currency":"USD",
"role":"MAKER",
"side_layering_limit":1,
"state":"OPEN",
"strategy_code":"FT",
"strategy_description":"CF_BTC-16DEC22",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"None",
"venue":"DBT"
},
"event":"ADDED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, as an RFQ receiver,
role
==MAKER
, whenstate
==CLOSED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfqs",
"data":{
"account_name":null,
"base_currency":"BTC",
"clearing_currency":"USD",
"closed_reason":"CANCELED_BY_CREATOR",
"counterparties": [],
"created_at":1670473348810.261,
"description":"Future 16 Dec 22",
"expires_at":1670473663770.951,
"id":"r_2IcGEiv9eQEA1CU4H1hfe9ZogAJ",
"is_taker_anonymous":true,
"kind":"FUTURE",
"label":"None",
"last_trade":"None",
"last_updated_at":1670473363770.951,
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"quantity":"200000",
"quote_currency":"USD",
"role":"MAKER",
"side_layering_limit":1,
"state":"CLOSED",
"strategy_code":"FT",
"strategy_description":"CF_BTC-16DEC22",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"None",
"venue":"DBT"
},
"event":"REMOVED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to RFQs are sent through the rfqs
WebSocket Notification channel.
This is a private channel and consumable by only those aparty to the RFQ. Those counterparties include the RFQ's creator as well as the specified counterparties
to the RFQ.
Updates received through the rfqs
WebSocket Notification channel can include RFQs being created, canceled, expired, filled and traded away.
The availability of an RFQ to be actioned by any user is denoted by the state
key of the object. When an RFQ has a state
== OPEN
, it is actionable by both the RFQ creator and those specified as counterparties. When an RFQ has a state
== CLOSED
it is no longer actionable by either the RFQ creator or the specified counterparties.
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include rfqs . |
> event | string | true | The change associated with the message. Valid values include ADDED , REMOVED . |
> data | object | true | An object containing the update’s information. |
>> id | string | true | The Paradigm created unique identifier of the RFQ. |
>> account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER . |
>> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was created. |
>> expires_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ expires. |
>> last_updated_at | integer | true | The time in UNIX milliseconds since the epoch when the RFQ was last updated. |
>> strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
>> strategy_description | string | true | The standardized description of the RFQ’s composite Instruments. |
>> description | string | true | The verbose description of the RFQ’s composite Instruments. |
>> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
>> kind | string | true | The composite Instrument kinds of the RFQ. Valid values include FUTURE , OPTION , OPTION_FUTURE . |
>> base_currency | string | true | The currency the RFQ is exposed to. Valid values include BTC , ETH , SOL . |
>> quote_currency | string | true | The currency of the price of the RFQ. Valid values include BTC , ETH , SOL , USD , USDC . |
>> clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
>> counterparties | Array of strings | true | The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER . |
>> role | string | true | The role of the user to the RFQ. Valid values include TAKER , MAKER . |
>> group_signature | string | true | A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such. |
>> taker_desk_name | string | true | The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True . |
>> legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
>>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>>> instrument_name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
>>> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
>>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places. |
>>> side | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
>>> quantity | string | true | The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument. |
>>> price | string | false | The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE . |
>> product_codes | Array of strings | true | The Paradigm created Product Codes of the composite Instruments to the RFQ. |
>> quantity | string | true | The total size of the composite Instrument legs, denominated in the clearing_currency . |
>> is_taker_anonymous | boolean | true | If the Taker Desk Name is to be revealed to the counterparties to the RFQ. |
>> label | string | true | RFQ creator label of the RFQ. |
>> side_layering_limit | integer | true | The maximum number of Orders a Maker is able to have either side of an RFQ. |
>> state | string | true | The availability of the RFQ to trade. Valid values include OPEN , CLOSED . |
>> closed_reason | string | true | The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR , EXPIRED , EXECUTION_LIMIT . null if the RFQ’s state == OPEN . |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
DRFQv2: rfq_orders
An example, as the RFQ Creator, RFQ
role
==TAKER
, whenevent
==ADDED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfq_orders",
"data":{
"id":"o_2IcGsBLQIwl09jdflpb1iRnUT9B",
"price":"16795",
"quantity":"200000",
"desk":"DSK94",
"rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
"side":"SELL"
},
"event":"ADDED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, as the RFQ Creator, RFQ
role
==TAKER
, whenevent
==REMOVED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfq_orders",
"data":{
"id":"o_2IcGsBLQIwl09jdflpb1iRnUT9B",
"price":"16795",
"quantity":"200000",
"desk":"DSK94",
"rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
"side":"SELL"
},
"event":"REMOVED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to an RFQ's Orders are sent through the rfq_orders
WebSocket Notifications channel.
This is a private channel and only available to the creator of the RFQ who has the role
== TAKER
in the RFQ.
Updates received through the rfq_orders
WebSocket Notification channel represent events relating to specific related orders. In terms of thinking, it's extremely similar to processing event updates to that of an Order Book with an L3
depth.
- An RFQ Orders
event
==ADDED
message indicates that an order is available and actionable by both the creater & the creator of the RFQ. - An RFQ Orders
event
==REMOVED
message indicates that an order is no longer available and actionable by any user.
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include rfq_orders . |
> event | string | true | The change associated with the message. Valid values include ADDED , REMOVED , UPDATED . |
> data | object | true | An object containing the update’s information. |
>> rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
>> side | string | true | The side of the RFQ. Valid values include BUY , SELL . |
>> price | string | true | The price of the Order, denominated in the quote_currency of the RFQ. |
>> quantity | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
>> desk | string | true | The Paradigm Desk Name of the counterparty who created the Order. |
>> id | string | true | The Paradigm created unique identifier of the Order. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
DRFQv2: orders
An example, when Order has a
state
==OPEN
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"orders",
"data":{
"account_name":"ParadigmTestNinetyFour",
"canceled_quantity":"0",
"created_at":1670539033867.91,
"filled_quantity":"0",
"id":"o_2IePNBE9NPXk0xJnPmUNZSrri2G",
"label":"just for me",
"last_updated_at":1670539033868.4849,
"pending_fill_quantity":"0",
"price":"16800",
"quantity":"200000",
"rfq_id":"r_2IePMAohwEdvzcTT2SchQWSC7Wf",
"role":"MAKER",
"side":"SELL",
"state":"OPEN",
"time_in_force":"GOOD_TILL_CANCELED",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 12312312312,
"price": "16800"
}
]
},
"event":"NEW",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, when Order has a
state
==CLOSED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"orders",
"data":{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670473741899.189,
"filled_quantity":"0",
"id":"o_2IcH26wODa1OAPgyCnwcFrJ6EGK",
"label":"just for me",
"last_updated_at":1670473741966.041,
"pending_fill_quantity":"200000",
"price":"16795",
"quantity":"200000",
"rfq_id":"r_2IcGerUAbHtEyTxzCiupnEgxk9Z",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": []
},
"event":"PENDING_FILL",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to a desks' Orders are sent through the orders
WebSocket Notifications channel.
This is a private channel and provides updates solely about the desks' Orders.
- An Orders
state
==OPEN
message indicates that the order is actionable by any user. - An Orders
state
==CLOSED
indicates that the order is no longer actionable by any user.
When the RFQ creator, role
== TAKER
, submits an order, the first published orders
WebSocket Notification channel message will always indicate state
== CLOSED
due to the Order either successfully crossing or being canceled due it's time_in_force
attribute being FILL_OR_KILL
.
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include orders . |
> event | string | true | The change associated with the message. Valid values include NEW , CANCELED , PENDING_FILL , FILLED . |
> data | object | true | An object containing the update’s information. |
>> id | string | true | The Paradigm created unique identifier of the Order. |
>> rfq_id | string | true | The Paradigm created unique identifier of the associated RFQ. |
>> state | string | true | The availability of the Order for the user to action. Valid values include OPEN , CLOSED . |
>> side | string | true | The direction of the Order. Valid values include BUY , SELL . |
>> type | string | true | The type of Order. Valid values include LIMIT . |
>> time_in_force | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
>> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was created. |
>> last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was last updated. |
>> venue | string | true | The underlying settlement venue associated with the Order & RFQ. Valid values include DBT , BIT , BYB . |
>> quantity | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
>> legs | Array of Objects | false | The composite Instrument legs of the Order. |
>> price | string | true | The price of the Order, denominated in the quote_currency of the RFQ. |
>> label | string | true | The user created label for the order. |
>> pending_fill_quantity | string | true | The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
>> filled_quantity | string | true | The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
>> canceled_quantity | string | true | The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ. |
>> account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
>> role | string | true | The role of the user in the RFQ. Valid values include TAKER , MAKER . |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
DRFQv2: trades
An example, when a trade has a
state
==PENDING_SETTLEMENT
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trades",
"data":{
"id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
"exec_id":"None",
"order_id":"o_2IeNvhjR6zW0iCrkh6Q3T5lOyTn",
"rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
"venue":"DBT",
"kind":"FUTURE",
"state":"PENDING_SETTLEMENT",
"role":"TAKER",
"executed_at":1670538321612.0579,
"filled_at":"None",
"side":"BUY",
"price":"17204",
"quantity":"200000",
"filled_quantity":"0",
"rejected_quantity":"0",
"rejected_party":"None",
"rejected_reason":"None",
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"price":"17204",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"None",
"fee_quantity":"None",
"fee_currency":"BTC"
}
],
"strategy_description":"CF_BTC-16DEC22",
"description":"Future 16 Dec 22",
"quote_currency":"USD",
"mark_price":"17203.49"
},
"event":"PENDING_SETTLEMENT",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, when a trade has a
state
==FILLED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trades",
"data":{
"id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
"exec_id":"366192",
"order_id":"o_2IeNvhjR6zW0iCrkh6Q3T5lOyTn",
"rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
"venue":"DBT",
"kind":"FUTURE",
"state":"FILLED",
"role":"TAKER",
"executed_at":1670538321612.0579,
"filled_at":1670538322000.0,
"side":"BUY",
"price":"17204",
"quantity":"200000",
"filled_quantity":"200000",
"rejected_quantity":"0",
"rejected_party":"None",
"rejected_reason":"None",
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"price":"17204",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141327736",
"fee_quantity":"0.0116252",
"fee_currency":"BTC"
}
],
"strategy_description":"CF_BTC-16DEC22",
"description":"Future 16 Dec 22",
"quote_currency":"USD",
"mark_price":"17203.49"
},
"event":"FILLED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example, when a trade has a
state
==REJECTED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trades",
"data":{
"id":"bt_2IeOL5d0Bvh32XgJQMFSu7XMyPc",
"exec_id":"None",
"order_id":"o_2IeOL5cYl8HoJHBIAlb1mLWbo13",
"rfq_id":"r_2IeOIha69NSwfkGG1qjJd7U3jEF",
"venue":"DBT",
"kind":"FUTURE",
"state":"REJECTED",
"role":"TAKER",
"executed_at":1670538523874.681,
"filled_at":"None",
"side":"BUY",
"price":"16800",
"quantity":"200000",
"filled_quantity":"0",
"rejected_quantity":"200000",
"rejected_party":"None",
"rejected_reason":"Deribit error: Price for trade is lower than min sell price. Your Ask for Future 16 Dec 22 was CANCELED",
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"price":"16800",
"product_code":"CF",
"quantity":"200000",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"None",
"fee_quantity":"None",
"fee_currency":"BTC"
}
],
"strategy_description":"CF_BTC-16DEC22",
"description":"Future 16 Dec 22",
"quote_currency":"USD",
"mark_price":"17189.22"
},
"event":"REJECTED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to a desks' Trades are sent through the trades
WebSocket Notifications channel.
This is a private channel and provides updates solely about the desks' Trades.
- A Trades
state
==PENDING_SETTLEMENT
message indicates that a desks' order has been successfully matched and is being cleared by the underlying settlement venue. - A Trades
state
==FILLED
message indicates that the trade has reached finality and be successfully cleared on the underlying settlement venue. - A Trades
state
==REJECTED
message indicates that the trade has reached finality and has been rejected at clearing by the underlying settlement venue.
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include trades . |
> event | string | true | The change associated with the message. Valid values include PENDING_SETTLEMENT , FILLED , REJECTED . |
> data | object | true | An object containing the update’s information. |
>> id | string | true | The Paradigm created unique identifier of the Trade. |
>> exec_id | string | true | The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue. |
>> order_id | string | true | The Paradigm created unique Order identifier associated with the Trade. |
>> rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
>> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
>> kind | string | true | The nature of the strategy traded. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
>> state | string | true | The indication if the trade has reached settlement finality. Valid values include PENDING_SETTTLEMENT , FILLED , REJECTED |
>> role | string | true | The role of the user in the Trade. Valid values include TAKER , MAKER . |
>> executed_at | decimal | true | The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm. |
>> filled_at | decimal | true | The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle. |
>> side | string | true | The direction of the user in the trade. Valid values include BUY , SELL . |
>> price | string | true | The strategy price of the trade, denominated the quote_currency of the RFQ. |
>> quantity | string | true | The amount of the trade, denominated in the clearing_currency of the RFQ. |
>> filled_quantity | string | true | The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ. |
>> rejected_quantity | string | true | The rejected amount of the trade, denominated in the clearing_currency of the RFQ. |
>> rejected_party | string | true | The counterparty responsible for the Trade Rejection. Valid values include USER , COUNTERPARTY . null If Trade successfully settled. |
>> rejected_reason | string | true | The reason for the Trade Rejection. null if Trade successfully settled. |
>> legs | Array of Objects | true | The composite Instrument legs of the Trade. |
>>> intrument_id | integer | true | The Paradigm created unique identifier of the Instrument., |
>>> instrument_name | string | true | The Paradigm normalized name of the Instrument used across Paradigm’s API. |
>>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. |
>>> side | string | true | The direction of the composite Instrument to the Trade. Valid values include BUY , SELL . |
>>> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
>>> quantity | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
>>> venue_trade_id | string | true | The corresponding unique trade identifier present on the underlying settlement venue. |
>>> fee_quantity | string | true | The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency . |
>>> fee_currency | string | true | The currency the fee_amount is denominated in. |
>> strategy_description | string | true | The standardized description of the Trade’s composite Instruments. |
>> description | string | true | The verbose description of the Trade’s composite Instruments. |
>> quote_currency | string | true | The currency in the price is denominated in, denominated in the quote_currency of the RFQ. |
>> mark_price | string | true | The strategy mark price from the underlying settlement venue of the composite Instruments to the trade. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
DRFQv2: trade_tape
An example, when a trade has the
state
==FILLED
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trade_tape",
"data":{
"id":"bt_2IeNvhjvSS7NanFGaalF2yZWSXm",
"rfq_id":"r_2IeNtwelJ18OKY88ltCjPFg4NVb",
"venue":"DBT",
"kind":"FUTURE",
"state":"FILLED",
"executed_at":1670538321612.0579,
"filled_at":1670538322000.0,
"side":"SELL",
"price":"17204",
"quantity":"200000",
"legs":[
{
"instrument_id":184255,
"instrument_name":"BTC-16DEC22",
"ratio":"1",
"side":"BUY",
"price":"17204",
"product_code":"CF",
"quantity":"200000"
}
],
"strategy_description":"CF_BTC-16DEC22",
"description":"Future 16 Dec 22",
"quote_currency":"USD",
"mark_price":"17203.49"
},
"event":"FILLED",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All successfully cleared Trades on Paradigm are sent through the trade_tape
WebSocket Notifications channel.
This is a public channel and consumable by all.
As such, no identifiable information is apart of any messages and only successfully cleared trades upon the underlying settlement venue are published.
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include trade_tape . |
> event | string | true | The change associated with the message. Valid values include FILLED . |
> data | object | true | An object containing the update’s information. |
>> id | string | true | The Paradigm created unique identifier of the Trade. |
>> rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
>> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
>> kind | string | true | The nature of the strategy traded. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
>> state | string | true | The indication if the trade has reached settlement finality. Valid values include FILLED . |
>> executed_at | decimal | true | The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm. |
>> filled_at | decimal | true | The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. |
>> side | string | true | The direction of the user in the trade. Valid values include BUY , SELL . |
>> price | string | true | The strategy price of the trade, denominated the quote_currency of the RFQ. |
>> quantity | string | true | The amount of the trade, denominated in the clearing_currency of the RFQ. |
>> legs | string | true | The composite Instrument legs of the Trade. |
>>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>>> instrument_name | string | true | The composite Instrument legs of the Trade. |
>>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. |
>>> side | string | true | The direction of the composite Instrument to the Trade. Valid values include BUY , SELL . |
>>> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
>>> quantity | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
>> strategy_description | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
>> description | string | true | The verbose description of the Trade’s composite Instruments. |
>> quote_currency | string | true | The verbose description of the Trade’s composite Instruments. |
>> mark_price | string | true | The strategy mark price from the underlying settlement venue of the composite Instruments to the trade. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
DRFQv2: bbo.{rfq_id}
An example, of an update message
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"data":{
"rfq_id":"r_2LA8TjDOjWAHtRJ7CeLWzQXf4Ah",
"min_price":"23658.58",
"max_price":"24379.14",
"mark_price":"24019.18",
"best_bid_price":"24017.50",
"best_ask_price":"24018.00",
"best_bid_amount":"342090.0",
"best_ask_amount":"42500.0",
"created_at":1675302554270,
"legs":[
{
"best_bid_price":"24017.50",
"best_ask_price":"24018.00",
"best_bid_amount":"342090.0",
"best_ask_amount":"42500.0",
"instrument_id":26707,
"instrument_name":"BTC-PERPETUAL",
"mark_price":"24019.18"
}
]
},
"channel":"bbo",
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to an RFQ's composite instrument & structure market data are sent via the bbo.{rfq_id}
WebSocket Notification Channel.
This is a public channel and consumable by all.
This channel publishes real-time updates of the underlying market data from the composite instruments' settlement venue.
Parameters
Member | Type | Required | Enums | Description |
---|---|---|---|---|
rfq_id | string | true | rfq_id |
The Paradigm created rfq_id of the RFQ which has a state == OPEN . |
Response Schema
Member | Type | Required | Description |
---|---|---|---|
jsonrpc | string | true | Always 2.0. |
method | string | true | The value will always be subscription to indicate message type. |
params | object | true | |
> channel | string | true | The Websocket channel the message was delivered upon. Valid values include bbo.{rfq_id} . |
> event | string | true | The change associated with the message. Valid values include NEW . |
> data | object | true | An object containing the update’s information. |
>> id | string | true | The Paradigm created unique identifier of the RFQ. |
>> min_price | string | true | The minimum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ. |
>> max_price | string | true | The maximum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ. |
>> mark_price | string | true | The strategy mark price of the RFQ’s composite Instruments from the underlying settlement venue. Denominated in the quote_currency of the RFQ. |
>> best_bid_price | string | true | The RFQ’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
>> best_ask_price | string | true | The RFQ’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
>> best_bid_amount | string | true | The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
>> best_ask_amount | string | true | The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
>> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the message was created by Paradigm. |
>> legs | Array of Objects | true | The composite Instruments of the RFQ. |
>>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>>> instrument_name | string | true | The Paradigm normalized name of the Instrument. |
>>> mark_price | string | true | The Instrument’s mark price from the underlying settlement venue, denominated in the quote_currency of the RFQ. |
>>> best_bid_price | string | true | The Instrument’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
>>> best_ask_price | string | true | The Instrument’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
>>> best_bid_amount | string | true | The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
>>> best_ask_amount | string | true | The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group. |
Message Structure with Sequence Numbers
WebSocket messages now include an additional meta
field that contains the following properties:
Member | Type | Description |
---|---|---|
seq_group | number | Unique identifier for the group of messages |
seq_num | number | Sequence number of the message within the group |
Here's an example of a WebSocket message with sequence numbers:
{
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "rfq",
"data": {
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
Handling Sequence Numbers
Clients should monitor the sequence numbers of the incoming messages to ensure they have not missed any messages. If a client detects a gap in the sequence numbers, it may have missed one or more messages and should take appropriate action, such as refreshing data from REST.
Sequences increase monotonically within the context of a sequence group. Sequences are only relevant within a sequence group, which represents a subscribed channel. Sequences may be re-used between sequence groups.
While messages are sent ordered according to their sequences, sequences are not guaranteed not to repeat.
DRFQv2 - REST Endpoints
DRFQv2: [GET] /instruments
/instruments Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/instruments \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/instruments',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/instruments
method = 'GET'
path = '/v2/drfq/instruments?venue=DBT&kind=FUTURE&base_currency=BTC'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/instruments", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /instruments
request returns all instruments that are or were tradeable on Paradigm.
- When
state
==ACTIVE
users are able to create markets using the instrument. - When
state
==EXPIRED
users are NOT able to create markets using the instrument.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
state | query | string | false | The present availability of the Instrument. Valid values include ACTIVE , EXPIRED . |
venue | query | string | false | The underlying settlement venue to return Instruments for. Valid values include DBT , BIT , BYB . |
kind | query | string | false | The type of contract. Valid values include FUTURE , OPTION . |
base_currency | query | string | false | The currency the Instrument is exposed to. Valid values include BTC , ETH , SOL , BCH . |
venue_instrument_name | query | string | false | The name of the Instrument on the underlying settlement venue. |
margin_kind | query | string | false | The nature of how the contract is margined. Valid values include LINEAR , INVERSE . |
include_greeks | query | string | false | To include greeks if available for the Instrument from the underlying settlement venue. Valid values include True and False. |
/instruments Response example
{
"count":2424,
"next":"cD0xODUyNzc=",
"results":[
{
"id": 3614,
"name": "ETH-7APR23",
"created_at": 1679644802000,
"expires_at": 1680854400000,
"kind": "FUTURE",
"venue": "DBT",
"option_kind": null,
"strike": null,
"margin_kind": "INVERSE",
"base_currency": "ETH",
"quote_currency": "USD",
"clearing_currency": "USD",
"settlement_currency": "ETH",
"mark_price": "1714.76",
"min_block_size": "100000",
"min_order_size_increment": "1",
"min_tick_size": "0.01",
"product_code": "AZ",
"venue_instrument_name": "ETH-7APR23",
"state": "ACTIVE",
"greeks": null
},
{
"id": 3613,
"name": "BTC-7APR23",
"created_at": 1679644802000,
"expires_at": 1680854400000,
"kind": "FUTURE",
"venue": "DBT",
"option_kind": null,
"strike": null,
"margin_kind": "INVERSE",
"base_currency": "BTC",
"quote_currency": "USD",
"clearing_currency": "USD",
"settlement_currency": "BTC",
"mark_price": "27091.94",
"min_block_size": "200000",
"min_order_size_increment": "10",
"min_tick_size": "0.01",
"product_code": "CF",
"venue_instrument_name": "BTC-7APR23",
"state": "ACTIVE",
"greeks": null
},
{
"id": 3358,
"name": "ETH-29DEC23-9000-P",
"created_at": 1679101560000,
"expires_at": 1703836800000,
"kind": "OPTION",
"venue": "DBT",
"option_kind": "PUT",
"strike": "9000",
"margin_kind": "INVERSE",
"base_currency": "ETH",
"quote_currency": "ETH",
"clearing_currency": "ETH",
"settlement_currency": "ETH",
"mark_price": "4.1669",
"min_block_size": "250",
"min_order_size_increment": "1",
"min_tick_size": "0.0001",
"product_code": "EH",
"venue_instrument_name": "ETH-29DEC23-9000-P",
"state": "ACTIVE",
"greeks": {
"delta": "-0.99534",
"gamma": "1e-05",
"mark_price": "4.1669",
"theta": "-0.02436",
"vega": "0.206",
"last_updated_at": 1679944965844
}
},
{
"id": 3357,
"name": "ETH-29DEC23-9000-C",
"created_at": 1679101560000,
"expires_at": 1703836800000,
"kind": "OPTION",
"venue": "DBT",
"option_kind": "CALL",
"strike": "9000",
"margin_kind": "INVERSE",
"base_currency": "ETH",
"quote_currency": "ETH",
"clearing_currency": "ETH",
"settlement_currency": "ETH",
"mark_price": "0.0007",
"min_block_size": "250",
"min_order_size_increment": "1",
"min_tick_size": "0.0001",
"product_code": "EH",
"venue_instrument_name": "ETH-29DEC23-9000-C",
"state": "ACTIVE",
"greeks": {
"delta": "0.00466",
"gamma": "1e-05",
"mark_price": "0.0007",
"theta": "-0.02436",
"vega": "0.20599",
"last_updated_at": 1679944965848
}
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Instruments. |
> id | integer | true | The Paradigm created unique identifier of the Instrument. |
> name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Instrument was created on the underlying settlement venue. |
> expires_at | decimal | true | The time in UNIX nanoseconds since the epoch when the Instrument settles or is expired on the underlying settlement venue. |
> kind | string | true | The type of contract. Valid values include OPTION , FUTURE . |
> venue | string | true | The underlying settlement venue of the Instrument. Valid values include DBT , BIT , BYB . |
> option_kind | string | true | The kind of Option contract. Valid values include CALL and PUT . null if kind ≠ OPTION . |
> strike | string | true | The strike of the Option contract. null if kind ≠ OPTION . |
> margin_kind | string | true | The nature of how the contract is margined. Valid values include LINEAR , INVERSE . |
> base_currency | string | true | The currency the Instrument is exposed to. Valid values include BTC , ETH , SOL . |
> quote_currency | string | true | The currency of the price of the Instrument. Valid values include BTC , ETH , SOL , USD , USDC . |
> clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
> settlement_currency | string | true | The currency the Instrument is settled in on the underlying settlement venue. Valid values include BTC , ETH , SOL , USD , USDC . |
> min_tick_size | string | true | The minimum price increment step the Instrument can be traded in, denominated in the quote_currency . |
> min_order_size_increment | string | true | The minimum order increment size/quantity can be traded in, denominated in the clearing_currency . |
> min_block_size | string | true | The minimum order size/quantity the Instrument can be traded in, denominated in the clearing_currency . |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> venue_instrument_name | string | true | The name of the Instrument on the underlying settlement venue. |
> state | string | true | The availability of the Instrument to be used in RFQs. Valid values include ACTIVE , EXPIRED . |
> mark_price | string | true | The “Mark Price” from the underlying settlement venue at the time when the data was pulled. |
> greeks | string | true | An array of variables used to assess the risk & exposure of a derivatives contract. |
>> last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the information was last updated. |
>> delta | string | false | The delta value of the Instrument. |
>> theta | string | false | The theta value of the Instrument. |
>> vega | string | false | The vega value of the Instrument. |
>> gamma | string | false | The gamma value of the Instrument. |
>> mark_price | string | false | The “Mark Price” from the underlying settlement venue at the time when the greeks were pulled. Deprecated: please use the top level mark_price |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3005 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [GET] /instruments/{instrument_id}
/instruments/{instrument_id} Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/instruments/123 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/instruments/123',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/instruments/{instrument_id}
method = 'GET'
path = '/v2/drfq/instruments/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/isntruments/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /instruments/{instrument_id}
request returns the specific instrument requested in the endpoint.
- When
state
==ACTIVE
users are able to create markets using the instrument. - When
state
==EXPIRED
users are NOT able to create markets using the instrument.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
instrument_id | endpoint | string | true | The Paradigm created unique instrument identifier. |
/instruments/{instrument_id} Response example
200 Response
{
"id": 123,
"name": "ETH-29DEC23-9000-C",
"created_at": 1679101560000,
"expires_at": 1703836800000,
"kind": "OPTION",
"venue": "DBT",
"option_kind": "CALL",
"strike": "9000",
"margin_kind": "INVERSE",
"base_currency": "ETH",
"quote_currency": "ETH",
"clearing_currency": "ETH",
"settlement_currency": "ETH",
"mark_price": "0.0007",
"min_block_size": "250",
"min_order_size_increment": "1",
"min_tick_size": "0.0001",
"product_code": "EH",
"venue_instrument_name": "ETH-29DEC23-9000-C",
"state": "ACTIVE",
"greeks": {
"delta": "0.00466",
"gamma": "1e-05",
"mark_price": "0.0007",
"theta": "-0.02436",
"vega": "0.20599",
"last_updated_at": 1679944965848
}
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
id | integer | true | The Paradigm created unique identifier of the Instrument. |
name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Instrument was created on the underlying settlement venue. |
expires_at | decimal | true | The time in UNIX milliseconds since the epoch when the Instrument settles or is expired on the underlying settlement venue. |
kind | string | true | The type of contract. Valid values include OPTION , FUTURE . |
venue | string | true | The underlying settlement venue of the Instrument. Valid values include DBT , BIT , BYB . |
option_kind | string | true | The kind of Option contract. Valid values include CALL and PUT . null if kind ≠ OPTION . |
strike | string | true | The strike of the Option contract. null if kind ≠ OPTION . |
margin_kind | string | true | The nature of how the contract is margined. Valid values include LINEAR , INVERSE . |
base_currency | string | true | The currency the Instrument is exposed to. Valid values include BTC , ETH , SOL . |
quote_currency | string | true | The currency of the price of the Instrument. Valid values include BTC , ETH , SOL , USD , USDC . |
clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
settlement_currency | string | true | The currency the Instrument is settled in on the underlying settlement venue. Valid values include BTC , ETH , SOL , USD , USDC . |
min_tick_size | string | true | The minimum price increment step the Instrument can be traded in, denominated in the quote_currency . |
min_order_size_increment | string | true | The minimum order increment size/quantity can be traded in, denominated in the clearing_currency . |
min_block_size | string | true | The minimum order size/quantity the Instrument can be traded in, denominated in the clearing_currency . |
product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
venue_instrument_name | string | true | The name of the Instrument on the underlying settlement venue. |
state | string | true | The availability of the Instrument to be used in RFQs. Valid values include ACTIVE , EXPIRED . |
mark_price | string | true | The “Mark Price” from the underlying settlement venue at the time when the data was pulled. |
greeks | string | true | An array of variables used to assess the risk & exposure of a derivatives contract. |
> last_updated_at | decimal | false | The time in UNIX milliseconds since the epoch when the information was last updated. |
> delta | string | false | The delta value of the Instrument. |
> theta | string | false | The theta value of the Instrument. |
> vega | string | false | The vega value of the Instrument. |
> gamma | string | false | The gamma value of the Instrument. |
> mark_price | string | false | The “Mark Price” from the underlying settlement venue at the time when the greeks were pulled. Deprecated: please use the top level mark_price |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | 3100 | "Unavailable instrument" | Unavailable/invalid instrument id provided in request. |
DRFQv2: [GET] /counterparties
/counterparties Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/counterparties \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/counterparties',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/counterparties
method = 'GET'
path = '/v2/drfq/counterparties?group=LP'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/counterparties", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /counterparties
request returns all counterparties the desk is able add as counterparty to an RFQ.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
group | query | string | false | The Paradigm created list of the counterparties to return. Valid values include LP . |
venues | query | string | false | The venues to return counterparties for. You can include multiple venues in a single request by ?venues=DBT,BYB . |
/counterparties Response example
{
"count":548,
"next":"cD0xMjM0",
"results":[
{
"desk_name":"05J2",
"firm_name":"062020",
"groups":[
],
"venues":[
"DBT"
]
},
{
"desk_name":"05J3",
"firm_name":"062020",
"groups":[
],
"venues":[
"DBT"
]
},
{
"desk_name":"0729",
"firm_name":"ParadigmShift",
"groups":[
],
"venues":[
"DBT"
]
},
{
"desk_name":"0817",
"firm_name":"ParadigmShift",
"groups":[
],
"venues":[
"DBT"
]
},
{
"desk_name":"1234",
"firm_name":"ParadigmShift",
"groups":[
],
"venues":[
"DBT"
]
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Counterparties. |
> firm_name | string | true | The Paradigm created name of the firm of the counterparty. |
> desk_name | string | true | The Paradigm created name of the desk of the counterparty. |
> venues | Array of strings | true | The venues the counterparty participates in and you can send RFQs to on Paradigm. |
> groups | Array of strings | true | The groups the counterparty is a part of. Currently, the only supported group are Liquidity Providers (LP ). |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3005 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [GET] /rfqs
/rfqs Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/rfqs
method = 'GET'
path = '/v2/drfq/rfqs?venue=DBT&state=OPEN'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v1/drfq/instruments/", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /rfqs
request returns all RFQs that are or were actionable.
- When
state
==OPEN
both the RFQ creator and the specified counterparties are able to action the RFQ. - When
state
==CLOSED
both the RFQ creator and the specified counterparties are NOT able to action the RFQ.
The RFQ creator, denoted by role
== TAKER
, is able to cancel the RFQ if state
== OPEN
.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
role | query | string | false | The role of the desk in the created RFQ. Valid values include TAKER , MAKER . |
state | query | string | false | The availability of the RFQ. Valid values include OPEN , CLOSED . |
venue | query | string | false | The underlying settlement venue to return Instruments for. Valid values include DBT , BIT , BYB . |
base_currency | query | string | false | The currency the Instrument is exposed to. Valid values include BTC , ETH , SOL . |
product_codes | query | string | false | The Paradigm created Product Codes of the composite Instruments. The request can contain multiple codes such as ?product_codes=DO,CF . |
/rfqs Response example
{
"count":12239,
"next":"cD0yMDIyLTEyLTA4KzAwJTNBNTglM0EwMC40NDE1MDclMkIwMCUzQTAw",
"results":[
{
"account_name":"ParadigmTestNinetyFive",
"base_currency":"BTC",
"clearing_currency":"BTC",
"closed_reason":"EXPIRED",
"counterparties":[
"DSK94",
"AAT42",
"AAT43",
"AAT44"
],
"created_at":1670461091765.508,
"description":"Call 31 Mar 23 24000",
"expires_at":1670461696044.232,
"id":"r_2IbrOQ3zGMVrOb7RLRKAizy3lgK",
"is_taker_anonymous":true,
"kind":"OPTION",
"label":null,
"last_trade":null,
"last_updated_at":1670461396044.232,
"legs":[
{
"instrument_id":154406,
"instrument_name":"BTC-31MAR23-24000-C",
"product_code":"DO",
"quantity":"25.0000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"quantity":"25.0000",
"quote_currency":"BTC",
"role":"TAKER",
"side_layering_limit":1,
"state":"CLOSED",
"strategy_code":"CL",
"strategy_description":"DO_BTC-31MAR23-24000-C",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"DSK95",
"venue":"DBT"
},
{
"account_name":"ParadigmTestNinetyFive",
"base_currency":"BTC",
"clearing_currency":"BTC",
"closed_reason":"EXPIRED",
"counterparties":[
"DSK94",
"AAT42",
"AAT43",
"AAT44"
],
"created_at":1670461080441.507,
"description":"Cstm +1 Call 30 Jun 23 28000\n +2 Call 8 Dec 22 14000",
"expires_at":1670461681005.817,
"id":"r_2IbrN2Jt8tM8HQG0SHz6JTXaUz0",
"is_taker_anonymous":true,
"kind":"OPTION",
"label":null,
"last_trade":null,
"last_updated_at":1670461381005.817,
"legs":[
{
"instrument_id":154716,
"instrument_name":"BTC-30JUN23-28000-C",
"product_code":"DO",
"quantity":"25.0000",
"ratio":"1",
"side":"BUY"
},
{
"instrument_id":185066,
"instrument_name":"BTC-8DEC22-14000-C",
"product_code":"DO",
"quantity":"50.0000",
"ratio":"2",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"quantity":"25.0000",
"quote_currency":"BTC",
"role":"TAKER",
"side_layering_limit":1,
"state":"CLOSED",
"strategy_code":"CL",
"strategy_description":"DO_BTC-30JUN23-28000-C_BTC-8DEC22-14000-C",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"DSK95",
"venue":"DBT"
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Instruments. |
> id | string | true | The Paradigm created unique identifier of the RFQ. |
> account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER . |
> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was created. |
> expires_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ expires. |
> last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was last updated. |
> strategy_description | string | true | The standardized description of the RFQ’s composite Instruments. |
> strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
> description | string | true | The verbose description of the RFQ’s composite Instruments. |
> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
> kind | string | true | The composite Instrument kinds of the RFQ. Valid values include FUTURE , OPTION , OPTION_FUTURE . |
> base_currency | string | true | The currency the RFQ is exposed to. Valid values include BTC , ETH , SOL . |
> quote_currency | string | true | The currency of the price of the RFQ. Valid values include BTC , ETH , SOL , USD , USDC . |
> clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
> counterparties | Array of strings | true | The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER . |
> role | string | true | The role of the user to the RFQ. Valid values include TAKER , MAKER . |
> group_signature | string | true | A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such. |
> taker_desk_name | string | true | The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True . |
> legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>> instrument_name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
>> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places. |
>> side | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
>> quantity | string | true | The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument. |
>> price | string | false | The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE . |
> product_codes | Array of strings | true | The Paradigm created Product Codes of the composite Instruments to the RFQ. |
> quantity | string | true | The total size of the composite Instrument legs, denominated in the clearing_currency . |
> is_taker_anonymous | boolean | true | If the Taker Desk Name is to be revealed to the counterparties to the RFQ. |
> label | string | true | RFQ creator label of the RFQ. |
> side_layering_limit | integer | true | The maximum number of Orders a Maker is able to have either side of an RFQ. |
> state | string | true | The availability of the RFQ to trade. Valid values include OPEN , CLOSED . |
> closed_reason | string | true | The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR , EXPIRED , EXECUTION_LIMIT . null if the RFQ’s state == OPEN . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3005 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [GET] /rfqs/{rfq_id}
/rfqs/{rfq_id} Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/rfqs/{rfq_id}
method = 'GET'
path = '/v2/drfq/rfqs/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v1/drfq//rfqs/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /rfqs/{rfq_id}
request returns the specific RFQ requested in the endpoint.
- When
state
==OPEN
both the RFQ creator and the specified counterparties are able to action the RFQ. - When
state
==CLOSED
both the RFQ creator and the specified counterparties are NOT able to action the RFQ.
The RFQ creator, denoted by role
== TAKER
, is able to cancel the RFQ if state
== OPEN
.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | endpoint | string | true | The Paradigm created unique RFQ identifier. |
/rfqs/{rfq_id} Response example
{
"account_name":"ParadigmTestNinetyFive",
"base_currency":"BTC",
"clearing_currency":"BTC",
"closed_reason":"EXPIRED",
"counterparties":[
"DSK94",
"AAT42",
"AAT43",
"AAT44"
],
"created_at":1670461091765.508,
"description":"Call 31 Mar 23 24000",
"expires_at":1670461696044.232,
"id":"r_2IbrOQ3zGMVrOb7RLRKAizy3lgK",
"is_taker_anonymous":true,
"kind":"OPTION",
"label":null,
"last_trade":null,
"last_updated_at":1670461396044.232,
"legs":[
{
"instrument_id":154406,
"instrument_name":"BTC-31MAR23-24000-C",
"product_code":"DO",
"quantity":"25.0000",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"quantity":"25.0000",
"quote_currency":"BTC",
"role":"TAKER",
"side_layering_limit":1,
"state":"CLOSED",
"strategy_code": "CL",
"strategy_description":"DO_BTC-31MAR23-24000-C",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name":"DSK95",
"venue":"DBT"
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the RFQ. |
account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. A null value is returned if role == MAKER . |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was created. |
expires_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ expires. |
last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was last updated. |
strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
strategy_description | string | true | The standardized description of the RFQ’s composite Instruments. |
description | string | true | The verbose description of the RFQ’s composite Instruments. |
venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
kind | string | true | The composite Instrument kinds of the RFQ. Valid values include FUTURE , OPTION , OPTION_FUTURE . |
base_currency | string | true | The currency the RFQ is exposed to. Valid values include BTC , ETH , SOL . |
quote_currency | string | true | The currency of the price of the RFQ. Valid values include BTC , ETH , SOL , USD , USDC . |
clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
counterparties | Array of strings | true | The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER . |
role | string | true | The role of the user to the RFQ. Valid values include TAKER , MAKER . |
group_signature | string | true | A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such. |
taker_desk_name | string | true | The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True . |
legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
> instrument_name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places. |
> side | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
> quantity | string | true | The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument. |
> price | string | false | The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE . |
product_codes | Array of strings | true | The Paradigm created Product Codes of the composite Instruments to the RFQ. |
quantity | string | true | The total size of the composite Instrument legs, denominated in the clearing_currency . |
is_taker_anonymous | boolean | true | If the Taker Desk Name is to be revealed to the counterparties to the RFQ. |
label | string | true | RFQ creator label of the RFQ. |
side_layering_limit | integer | true | The maximum number of Orders a Maker is able to have either side of an RFQ. |
state | string | true | The availability of the RFQ to trade. Valid values include OPEN , CLOSED . |
closed_reason | string | true | The reason the RFQ is no longer available. Valid values include CANCELED_BY_CREATOR , EXPIRED , EXECUTION_LIMIT . null if the RFQ’s state == OPEN . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
DRFQv2: [POST] /rfqs
/rfqs Request example
# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/rfqs \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const inputBody = `{
"account_name": "ParadigmTestNinetyFive",
"venue": "DBT",
"quantity": "100",
"is_taker_anonymous": true,
"counterparties": ["DSK2", "DSK3"],
"legs": [
{
"instrument_id": 12314,
"ratio": "1",
"side": "SELL"
}
]
}`;
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
import json
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# POST /v2/drfq/rfqs
method = 'POST'
path = '/v2/drfq/rfqs'
payload = {
"account_name": "ParadigmTestNinetyFive",
"venue": "DBT",
"quantity": "100",
"is_taker_anonymous": True,
"counterparties": ["DSK2", "DSK3"],
"legs": [
{
"instrument_id": 12314,
"ratio": "1",
"side": "SELL"
}
]
}
json_payload = json.dumps(payload)
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=json_payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.post(
host+path,
headers=headers,
json=payload
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("POST", "https://api.testnet.paradigm.trade/v2/drfq/rfqs", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [POST] /rfqs
request attempts to create an RFQ.
The creator of the RFQ will have the role
== TAKER
.
Only desks specified as counterparties
in the request are able receive the RFQ & return prices. The desks aparty to the RFQ must price the full size requested in the RFQ as no partial fills are possible.
/rfqs Body parameter example
{
"account_name":"ParadigmTestNinetyFive",
"venue": "DBT",
"quantity": "100",
"is_taker_anonymous": true,
"counterparties": ["DSK2", "DSK3"],
"legs": [
{
"instrument_id": 12314,
"ratio": "1",
"side": "SELL"
}
]
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
account_name | body | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
venue | body | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
quantity | body | string | true | The total size of the composite Instrument legs, denominated in the clearing_currency . |
is_taker_anonymous | body | boolean | true | If the Taker Desk Name is to be revealed to the counterparties to the RFQ. |
counterparties | body | Array of strings | true | The Paradigm Desk Names or groups aparty to the RFQ. |
label | body | string | false | User defined label for the RFQ. |
legs | body | Array of Objects | true | The composite Instruments of the RFQ. |
> instrument_id | body | integer | true | The Paradigm unique identifier of the Instrument. |
> ratio | body | string | true | The relative multiplier applied to the quantity of the Instrument’s quantity relative to the quantity of the RFQ. Maximum of 2 decimal places. |
> side | body | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
> price | body | string | false | The price of the leg, for hedge legs only, in the quote_currency of the Instrument. |
/rfqs Response example
201 Response
{
"id": "12312441241",
"account_name": "ParadigmTestNinetyFive",
"created_at": 1656095317329249937.1,
"expires_at": 1656095317329249938.1,
"last_updated_at": 1656095317329249939.1,
"strategy_code": "PT",
"strategy_description": "DO_BTC-9JUL21-32000-P",
"description": "Put 9 Jul 21 32000",
"venue": "DBT",
"base_currency": "BTC",
"quote_currency": "BTC",
"clearing_currency": "BTC",
"counterparties": ["DSK2", "DSK3"],
"role": "TAKER",
"group_signature":"891e9830b2dcd30747caea878323e30d52356f0c1b50449ccb666e0e530b296a",
"taker_desk_name": "DSK95",
"legs": [
{
"instrument_id": 123213213,
"instrument_name": "BTC-9PUT21-32000-C",
"product_code": "DO"
"ratio": "1",
"side": "SELL",
"amount": "100"
}
],
"product_codes": ["DO"],
"amount": "100",
"is_taker_anonymous": false,
"side_layering_limit": 1,
"state": "ACTIVE"
}
Response Schema
Status Code: 201
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the RFQ. |
account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was created. |
expires_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ expires. |
last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the RFQ was last updated. |
strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
strategy_description | string | true | The standardized description of the RFQ’s composite Instruments. |
description | string | true | The verbose description of the RFQ’s composite Instruments. |
venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
base_currency | string | true | The currency the RFQ is exposed to. Valid values include BTC , ETH , SOL . |
quote_currency | string | true | The currency of the price of the RFQ. Valid values include BTC , ETH , SOL , USD , USDC . |
clearing_currency | string | true | The currency order sizes/quantities are submitted in. Valid values include BTC , ETH , SOL , USD . |
counterparties | Array of strings | true | The Paradigm Desk Names the RFQ was directed towards. An empty array is returned if role == MAKER . |
role | string | true | The role of the user to the RFQ. Valid values include TAKER , MAKER . |
group_signature | string | true | A hash representing the RFQ structure and its creator. It keeps the taker desk anonymous if the RFQ is defined as such. |
taker_desk_name | string | true | The Paradigm Desk Name who created the RFQ. null if role == MAKER and is_taker_anonymous == True . |
legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
> instrument_name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places. |
> side | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
> quantity | string | true | The size of the Instrument leg to the RFQ, denominated in the clearing_currency of the Instrument. |
> price | string | false | The price of the Instrument leg to the RFQ, denominated in the quote_currency of the Instrument. null if the Instrument is not a hedge leg. Hedge legs must be kind == FUTURE . |
product_codes | Array of strings | true | The Paradigm created Product Codes of the composite Instruments to the RFQ. |
quantity | string | true | The total size of the composite Instrument legs, denominated in the clearing_currency . |
is_taker_anonymous | boolean | true | If the Taker Desk Name is to be revealed to the counterparties to the RFQ. |
label | string | true | RFQ creator label of the RFQ. |
side_layering_limit | integer | true | The maximum number of Orders a Maker is able to have either side of an RFQ. |
state | string | true | The availability of the RFQ to trade. Valid values include OPEN and CLOSED . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
400 | 100 | "Invalid parameters" | You provided invalid value to one or more parameters. |
400 | 1302 | "Invalid account information" | The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard. |
400 | 1306 | "Invalid instrument" | You provided invalid instrument for one or more legs. |
400 | 3001 | "Venue is not currently supported for this product" | Provided venue is not supported. |
400 | 3002 | "Invalid leg pricing parameters" | You provided invalid price value for one or more legs. |
400 | 3200 | "Invalid RFQ leg configuration" | You provided invalid configuration of legs. |
400 | 3203 | "Invalid leg parameters" | You provided invalid value to one or more leg parameters. |
400 | 3206 | "An open RFQ for this strategy already exists. Please close that rfq before submitting a new one." | There already exist an open RFQ for the same strategy. |
400 | 3401 | "Price is outside bands." | You provided price that is outside of venue's price bands. |
DRFQv2: [DELETE] /rfqs/{rfq_id}
/rfqs/{rfq_id} Request example
# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/rfqs/123 \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const inputBody = ``;
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123',
{
method: 'DELETE',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# DELETE /v2/drfq/rfqs/{rfq_id}
method = 'DELETE'
path = '/v2/drfq/rfqs/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.delete(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [DELETE] /rfqs/{rfq_id}
request attempts to cancel a desks' RFQ.
An RFQ's state
must equal OPEN
for it to be canceled.
Response Schema
Status Code: 204
There is no response payload.
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
400 | 3207 | "Too late to cancel RFQ" | RFQ has already expired or been filled. |
404 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
DRFQv2: [GET] /rfqs/{rfq_id}/orders
/rfqs/{rfq_id}/orders Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/rfqs/{rfq_id}/orders
method = 'GET'
path = '/v2/drfq/rfqs/123/orders'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/orders", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /rfqs/{rfq_id}/orders
request allows you to return all state
== OPEN
orders upon an RFQ.
Only the desk who created the RFQ, role
== TAKER
, is able to request this endpoint for the RFQ.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | endpoint | string | true | The Paradigm created unique RFQ identifier. |
/rfqs/{rfq_id}/orders Example response
200 Response
{
"id": "12312441241",
"bids": [
{
"price": "0.001",
"quantity": "10.01",
"id": "12321321321",
"desk": "LDGR"
}
],
"asks": []
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the RFQ. |
bids | Array of Objects | true | An array of Order objects offering to BUY the RFQ . |
> price | string | true | The price of the bid, denominated in the quote_currency of the RFQ. |
> quantity | string | true | The amount of the bid, denominated in the clearing_currency of the RFQ. |
> id | string | true | The Paradigm created unique identifier of the Order. |
> desk | string | true | The Paradigm Desk Name of the creator of the Order. |
asks | string | true | An array of Order objects offering to SELL the RFQ. |
> price | string | true | The price of the ask, denominated in the quote_currency of the RFQ. |
> quantity | string | true | The amount of the ask, denominated in the clearing_currency of the RFQ. |
> id | string | true | The Paradigm created unique identifier of the Order. |
> desk | string | true | The Paradigm Desk Name of the creator of the Order. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
DRFQv2: [GET] /orders
/orders Request examples
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/orders \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
;
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
method: 'GET',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/orders
method = 'GET'
path = '/v2/drfq/orders?page_size=50&cursor=12331a'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /orders
request allows you to return all of your desks' Orders.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
rfq_id | query | string | false | The Paradigm created unique identifier of the associated RFQ. |
state | query | string | false | The availability of the Order for the user to action. Valid values include OPEN , CLOSED . |
venue | query | string | false | The underlying settlement venue to return Instruments for. Valid values include DBT , BIT , BYB . |
base_currency | query | string | false | The currency the Instrument is exposed to. Valid values include BTC , ETH , SOL . |
/orders Example response
200 Response
{
"count":8939,
"next":"cD0yMDIyLTEyLTA4KzAwJTNBNDAlM0E1MS40MDc3OTElMkIwMCUzQTAw",
"results":[
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670460131779.387,
"filled_quantity":"50",
"id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
"label":"mmh",
"last_updated_at":1670460132524.4802,
"pending_fill_quantity":"0",
"price":"0.2397",
"quantity":"50",
"rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 194874,
"price": "0.2"
}
]
},
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670460088632.3892,
"filled_quantity":"0",
"id":"o_2IbpMNIiq6dPAlikmKaMJRmkDpQ",
"label":"mmh",
"last_updated_at":1670460088700.561,
"pending_fill_quantity":"25",
"price":"-0.7927",
"quantity":"25",
"rfq_id":"r_2IbpH63lIEI9UCpHS8uBTEy7h75",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 194874,
"price": "0.2"
}
]
},
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670460086147.604,
"filled_quantity":"25",
"id":"o_2IbpM7f1EFwm4570NdZARA4IpL2",
"label":"mmh",
"last_updated_at":1670460086613.062,
"pending_fill_quantity":"0",
"price":"0.2724",
"quantity":"25",
"rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 194874,
"price": "0.2"
}
]
},
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"25",
"created_at":1670460083979.475,
"filled_quantity":"0",
"id":"o_2IbpLkNx8hRgOfRO9aj40WvbXzR",
"label":"mmh",
"last_updated_at":1670460084428.182,
"pending_fill_quantity":"0",
"price":"-0.7929",
"quantity":"25",
"rfq_id":"r_2IbpH63lIEI9UCpHS8uBTEy7h75",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 194874,
"price": "0.2"
}
]
},
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670460051407.791,
"filled_quantity":"0",
"id":"o_2IbpHizejRbn6OXzJmsX0geCIxI",
"label":"mmh",
"last_updated_at":1670460051449.946,
"pending_fill_quantity":"250",
"price":"-3.0158",
"quantity":"250",
"rfq_id":"r_2IbpBRNYSQLfTHvyUNtjmxqB9zm",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs": [
{
"instrument_id": 194874,
"price": "0.2"
}
]
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Instruments. |
> id | string | true | The Paradigm created unique identifier of the Order. |
> rfq_id | string | true | The Paradigm created unique identifier of the associated RFQ. |
> state | string | true | The availability of the Order for the user to action. Valid values include OPEN , CLOSED . |
> side | string | true | The direction of the Order. Valid values include BUY , SELL . |
> type | string | true | The type of Order. Valid values include LIMIT . |
> time_in_force | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
> created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was created. |
> last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was last updated. |
> venue | string | true | The underlying settlement venue associated with the Order & RFQ. Valid values include DBT , BIT , BYB . |
> quantity | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
> legs | Array of Objects | true | The composite Instrument legs of the Order. |
>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
> price | string | true | The price of the Order, denominated in the quote_currency of the RFQ. |
> label | string | true | The user created label for the order. |
> pending_fill_quantity | string | true | The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
> filled_quantity | string | true | The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
> canceled_quantity | string | true | The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ. |
> account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
> role | string | true | The role of the user in the RFQ. Valid values include TAKER , MAKER . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3005 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [GET] /orders/{order_id}
/orders/{order_id} Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/orders/{order_id}
method = 'GET'
path = '/v2/drfq/orders/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /orders/{order_id}
request returns the specified Order in the endpoint.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
order_id | endpoint | string | true | The Paradigm created unique Order identifier. |
/orders/{order_id} Response example
200 Response
{
"account_name":"ParadigmTestNinetyFive",
"canceled_quantity":"0",
"created_at":1670460051407.791,
"filled_quantity":"0",
"id":"o_2IbpHizejRbn6OXzJmsX0geCIxI",
"label":"mmh",
"last_updated_at":1670460051449.946,
"pending_fill_quantity":"250",
"price":"-3.0158",
"quantity":"250",
"rfq_id":"r_2IbpBRNYSQLfTHvyUNtjmxqB9zm",
"role":"TAKER",
"side":"BUY",
"state":"CLOSED",
"time_in_force":"FILL_OR_KILL",
"type":"LIMIT",
"venue":"DBT",
"legs":[
{
"instrument_id": 194874,
"price": "0.1"
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the Order. |
rfq_id | string | true | The Paradigm created unique identifier of the associated RFQ. |
state | string | true | The availability of the Order for the user to action. Valid values include OPEN , CLOSED . |
side | string | true | The direction of the Order. Valid values include BUY , SELL . |
type | string | true | The type of Order. Valid values include LIMIT . |
time_in_force | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was created. |
last_updated_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was last updated. |
venue | string | true | The underlying settlement venue associated with the Order & RFQ. Valid values include DBT , BIT , BYB . |
quantity | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
legs | Array of Objects | false | The composite Instrument legs of the Order. |
> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
price | string | true | The price of the Order, denominated in the quote_currency of the RFQ. |
label | string | true | The user created label for the order. |
pending_fill_quantity | string | true | The amount of the Order pending settlement on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
filled_quantity | string | true | The amount of the Order which has been successfully settled on the underlying settlement venue, denominated in the clearing_currency of the RFQ. |
canceled_quantity | string | true | The amount of the Order which has been canceled, denominated in the clearing_currency of the RFQ. |
account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
role | string | true | The role of the user in the RFQ. Valid values include TAKER , MAKER . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | 3500 | "Unavailable order" | Unavailable/invalid Order Id provided in request. |
DRFQv2: [POST] /orders
/orders Request example
# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/orders \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const inputBody = `{
"rfq_id": "12312321321321",
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 12312312312,
"price": "0.1"
}
],
"quantity": "0.1",
"side": "SELL"
}`;
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
import json
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# POST /v2/drfq/orders
method = 'POST'
path = '/v2/drfq/orders'
payload = {
"rfq_id": "123456",
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 11434,
"price": "17000"
}
],
"quantity": "250000",
"side": "SELL"
}
json_payload = json.dumps(payload)
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=json_payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.post(
host+path,
headers=headers,
json=payload
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("POST", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [POST] /orders
request attempts to create an Order.
The response, assuming a successful request, will always return with state
== PENDING
demonstrating that the matching engine is processing the request. From the orders
WebSocket Notification channel, a following message with the state
== OPEN
indicates the Order is actionable by yourself or other counterparties (if you're the Maker). If the Order state
== CLOSED
it indicates the order is no longer actionable by anyone.
Desks who create the RFQ, role
== TAKER
, are only able to submit type
== LIMIT
orders with time_in_force
== FILL_OR_KILL
to attempt to cross with an existing Order.
Desks who create the RFQ, role
== TAKER
, should only submit a strategy price
value and should NOT include a legs
array in the request body.
Desks who are the counterparties to the RFQ, role
== MAKER
, are only able to submit type
== LIMIT
orders with time_in_force
== GOOD_TILL_CANCELED
.
Desks who are the counterparties to the RFQ, role
== MAKER
, should only submit individual legs
price
values and NOT a strategy
price value.
Desks whose role
== MAKER
are not able to submit crossing orders. Only desks who are the RFQ creator, role
== TAKER
, are able to attempt to cross with the existing Orders.
/orders
role
==TAKER
, Body parameter example
{
"rfq_id": "12312321321321",
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "FILL_OR_KILL",
"quantity": "0.1",
"side": "BUY",
"price": "0.1",
}
/orders
role
==MAKER
, Body parameter example
{
"rfq_id": "12312321321321",
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 12312312312,
"price": "0.1"
}
],
"quantity": "0.1",
"side": "SELL"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | body | string | true | The Paradigm created unique identifier of the RFQ. |
account_name | body | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. This parameter is optional if role == TAKER . |
label | body | string | false | The user created label for the order. |
type | body | string | true | The type of Order. Valid values include LIMIT . |
time_in_force | body | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
legs | body | Array of Objects | false | The composite Instrument legs of the Order. |
> instrument_id | body | integer | true | The Paradigm created unique identifier of the Instrument. |
> price | body | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
quantity | body | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
price | body | string | false | The total price of the Order, denominated in the quote_currency of the RFQ. |
side | body | string | true | The direction of the Order. Valid values include BUY , SELL . |
/orders Response example
201 Response
{
"account_name": "ParadigmTestNinetyFive",
"canceled_quantity": "0",
"created_at": 1675170636837.993,
"filled_quantity": "0",
"id": "o_123123",
"label": "just for me",
"last_updated_at": 1675170636957.032,
"legs": [],
"quantity": "0.1",
"pending_fill_quantity": "0.1",
"price": "0.154",
"rfq_id": "r_12312321321321",
"role": "TAKER",
"side": "SELL",
"state": "PENDING",
"time_in_force": "FILL_OR_KILL",
"type": "LIMIT",
"venue": "DBT"
}
Response Schema
Status Code 201
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the Order. |
rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
label | string | true | The user created label for the order. |
type | string | true | The type of Order. Valid values include LIMIT . |
time_in_force | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
created_at | integer | true | The time in UNIX nanoseconds since the epoch when the Order was created. |
quantity | string | true | The total size of the Order, denominated in the clearing_currency of the RFQ. |
legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
> instrument_id | integer | false | The Paradigm created unique identifier of the Instrument. |
> price | string | false | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
price | string | true | The total strategy price of the Order, denominated in the quote_currency of the RFQ. |
side | string | true | The direction of the Order. Valid values include BUY , SELL . |
state | string | true | The availability of the Order for the user to action. Valid values include PENDING , OPEN , CLOSED |
role | string | true | The role of the user in the RFQ. Valid values include TAKER , MAKER . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
400 | 100 | "Invalid parameters" | You provided invalid value to one or more parameters. |
400 | 1302 | "Invalid account information" | The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard. |
400 | 3203 | "Invalid leg parameters" | You provided invalid value to one or more leg parameters. |
404 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
400 | 3401 | "Price is outside bands." | You provided price that is outside of venue's price bands. |
400 | 3503 | "An open order for this rfq and side already exists." | There already exist an order for the side and rfq provided in the request. |
DRFQv2: [PUT] /orders/{order_id}
/orders/{order_id} Request example
# You can also use wget
curl -X PUT https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const inputBody = `{
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 12312312312,
"price": "0.1"
}
],
"amount": "0.1",
"side": "BUY",
"rfq_id": "123"
}`;
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
method: 'PUT',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
import json
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# PUT /v2/drfq/orders/{order_id}
method = 'PUT'
path = '/v2/drfq/orders/123'
payload = {
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 1234,
"price": "0.1"
}
],
"amount": "0.1",
"side": "BUY",
"rfq_id": "123"
}
json_payload = json.dumps(payload)
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=json_payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.put(
host+path,
headers=headers,
json=payload
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("PUT", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [PUT] /orders/{order_id}
request allows a desk to replace an existing state
== OPEN
Order.
Desks who are the counterparties to the RFQ, role
== MAKER
, should only submit individual legs
price
values and NOT a strategy
price value.
Upon a successful request, the order will lose it's time priority.
/orders/{order_id}
role
==MAKER
, Body parameter example
{
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"legs": [
{
"instrument_id": 12312312312,
"price": "0.1"
}
],
"amount": "0.1",
"side": "BUY",
"rfq_id": "123"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | body | string | false | The Paradigm created unique identifier of the RFQ. It has to match rfq_id of the Order being replaced. |
account_name | body | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
label | body | string | false | The user created label for the order. |
type | body | string | true | The type of Order. Valid values include LIMIT . |
time_in_force | body | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
legs | body | Array of Objects | false | The composite Instrument legs of the Order. |
> instrument_id | body | integer | false | The Paradigm created unique identifier of the Instrument. |
> price | body | string | false | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
quantity | body | string | true | The size of the Order, denominated in the clearing_currency of the RFQ. |
side | body | string | false | The direction of the Order. Valid values include BUY , SELL . It has to match the side of the Order that is being replaced. |
/orders/{order_id} Response example
201 Response
{
"id": "12312312321",
"rfq_id": "12312312312",
"account_name": "ParadigmTestNinetyFive",
"label": "just for me",
"type": "LIMIT",
"time_in_force": "GOOD_TILL_CANCELED",
"created_at": 1656095317329249937,
"quantity": "0.1",
"legs": [
{
"instrument_id": 123123321,
"price": "0.154"
}
],
"price": "0.154",
"side": "SELL",
"state": "PENDING",
"role": "MAKER"
}
Response Schema
Status Code: 201
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the Order. |
rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
account_name | string | true | The user given name of the Venue API Credentials on the Client Admin Dashboard. |
label | string | true | The user created label for the order. |
type | string | true | The type of Order. Valid values include LIMIT . |
time_in_force | string | true | The validity protocol of the Order. Valid values include GOOD_TILL_CANCELED , FILL_OR_KILL . |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the Order was created. |
quantity | string | true | The total size of the Order, denominated in the clearing_currency of the RFQ. |
legs | Array of Objects | true | The composite Instrument legs of the RFQ. |
> instrument_id | integer | false | The Paradigm created unique identifier of the Instrument. |
> price | string | false | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
price | string | true | The total strategy price of the Order, denominated in the quote_currency of the RFQ. |
side | string | true | The direction of the Order. Valid values include BUY , SELL . |
state | string | true | The availability of the Order for the user to action. Valid values include PENDING , OPEN , CLOSED |
role | string | true | The role of the user in the RFQ. Valid values include TAKER , MAKER . |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
400 | 100 | "Invalid parameters" | You provided invalid value to one or more parameters. |
400 | 1302 | "Invalid account information" | The value provided with the account key should match the name given to the Exchange API key on the Paradigm Client Admin Dashboard. |
400 | 3203 | "Invalid leg parameters" | You provided invalid value to one or more leg parameters. |
404 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
400 | 3401 | "Price is outside bands." | You provided price that is outside of venue's price bands. |
404 | 3500 | "Unavailable order" | Unavailable/invalid Order Id provided in request. |
400 | 3505 | "Invalid quantity." | You provided invalid value for quantity. |
DRFQv2: [DELETE] /orders
/orders Request example
# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/orders \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders',
{
method: 'DELETE',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# DELETE /v2/drfq/orders
method = 'DELETE'
path = '/v2/drfq/orders'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.delete(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/orders", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [DELETE] /orders
request allows you to attempt to cancel all of your desks' state
== OPEN
Orders.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | query | string | false | The Paradigm created unique identifier of the RFQ. |
side | query | string | false | The direction of the Order. Valid values include BUY , SELL . |
label | query | string | false | The user created label for the order. |
/orders Response example
200 Response
{
"successes": {
"count": 2,
"order_ids": ["152799", "152798"]
},
"failures": {
"count": 0,
"order_ids": []
}
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
successes | Object | true | This object demonstrates the successful cancel operations & associated Order IDs. |
> count | integer | true | The number of successfully canceled Orders. |
> order_ids | Array of strings | true | The Paradigm created Order IDs that have been successfully canceled. [] if no Orders are successfully canceled. |
failures | Object | true | This object demonstrates the failed cancel operations & associated Order IDs. |
> count | integer | true | The number of failed canceled Order operations. |
> order_ids | Array of strings | true | The Paradigm created Order IDs that failed to cancel. [] if no Orders fail to cancel. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
DRFQv2: [DELETE] /orders/{order_id}
/orders/{order_id} Request example
# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v2/drfq/orders/123 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/orders/123',
{
method: 'DELETE',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# DELETE /v2/drfq/orders/{order_id}
method = 'DELETE'
path = '/v2/drfq/orders/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.delete(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("DELETE", "https://api.testnet.paradigm.trade/v2/drfq/orders/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [DELETE] /orders/{order_id}
request attempts to cancel the specified state
== OPEN
Order in the endpoint.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
order_id | endpoint | string | true | The Paradigm created unique Order identifier. |
Response Schema
Status Code: 204
There is no response schema.
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | 3500 | "Unavailable order" | Unavailable/invalid Order Id provided in request. |
400 | 3502 | "Too late to cancel order" | The requested order_id is already CLOSED or unavailable to cancel. |
DRFQv2: [GET] /trades
/trades Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trades \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/trades',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/trades
method = 'GET'
path = '/v2/drfq/trades'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/trades", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /trades
request returns all trades your desk has been aparty too.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
state | query | string | false | The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT , FILLED , REJECTED . |
rfq_id | query | string | false | The Paradigm created unique identifier associated with the RFQ. |
venue | query | string | false | The underlying settlement venue to return Instruments for. Valid values include DBT , BIT , BYB . |
kind | query | string | false | The contract type of the associated RFQ. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
role | query | string | false | The role of the user in the Trade. Valid values include TAKER , MAKER . |
order_id | query | string | false | The Paradigm created unique identifier associated with the Order. |
/trades Response example
200 Response
{
"count":2921,
"next":"cD0yMDIyLTEyLTA4KzAwJTNBMzglM0E1MS4yMTY1NjglMkIwMCUzQTAw",
"results":[
{
"id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
"exec_id":"365636",
"order_id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
"rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670460131896.015,
"filled_at":1670460132000.0,
"side":"BUY",
"price":"0.2397",
"quantity":"50",
"filled_quantity":"50",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":154564,
"instrument_name":"BTC-30JUN23-14000-P",
"price":"0.2397",
"product_code":"DO",
"quantity":"50",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186632",
"fee_quantity":"0.0075",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-30JUN23-14000-P",
"description":"Put 30 Jun 23 14000",
"quote_currency":"BTC",
"mark_price":"0.2407"
},
{
"id":"bt_2IbpM7fQWGK1bILTw2OvwPnMc5P",
"exec_id":"365635",
"order_id":"o_2IbpM7f1EFwm4570NdZARA4IpL2",
"rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670460086203.6682,
"filled_at":1670460086000.0,
"side":"BUY",
"price":"0.2724",
"quantity":"25",
"filled_quantity":"25",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":182233,
"instrument_name":"BTC-24FEB23-17000-C",
"price":"0.2724",
"product_code":"DO",
"quantity":"25",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186570",
"fee_quantity":"0.00375",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-24FEB23-17000-C",
"description":"Call 24 Feb 23 17000",
"quote_currency":"BTC",
"mark_price":"0.2735"
},
{
"id":"bt_2IbpBwZLazIBOcI24DYsD7ihRoy",
"exec_id":"365634",
"order_id":"o_2IbpBwYpwJEXsKQRnNZi8B6NxSQ",
"rfq_id":"r_2Ibp7AUyp9HTimRTY1TiGqNcI9a",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670460005229.808,
"filled_at":1670460005000.0,
"side":"BUY",
"price":"4.4713",
"quantity":"50",
"filled_quantity":"50",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":153021,
"instrument_name":"BTC-30JUN23-100000-P",
"price":"4.9549",
"product_code":"DO",
"quantity":"50",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186463",
"fee_quantity":"0",
"fee_currency":"BTC"
},
{
"instrument_id":153009,
"instrument_name":"BTC-30JUN23-15000-P",
"price":"0.2418",
"product_code":"DO",
"quantity":"100",
"ratio":"2",
"side":"SELL",
"venue_trade_id":"141186462",
"fee_quantity":"0.015",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-30JUN23-100000-P_BTC-30JUN23-15000-P",
"description":"Cstm +1 Put 30 Jun 23 100000\n -2 Put 30 Jun 23 15000",
"quote_currency":"BTC",
"mark_price":"4.4741"
},
{
"id":"bt_2Ibp2e4vIBlyII2FDG4hcfV4aXr",
"exec_id":"365633",
"order_id":"o_2Ibp2e43lJPzyPW4S3j3NR3SwOV",
"rfq_id":"r_2Ibozkpq0slrvDz93ZPH6u0AHRV",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670459931825.164,
"filled_at":1670459932000.0,
"side":"BUY",
"price":"-0.4729",
"quantity":"25",
"filled_quantity":"25",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":182746,
"instrument_name":"BTC-16DEC22-15000-P",
"price":"0.0092",
"product_code":"DO",
"quantity":"25",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186363",
"fee_quantity":"0",
"fee_currency":"BTC"
},
{
"instrument_id":141457,
"instrument_name":"BTC-31MAR23-100000-C",
"price":"0.0007",
"product_code":"DO",
"quantity":"75",
"ratio":"3",
"side":"BUY",
"venue_trade_id":"141186361",
"fee_quantity":"0",
"fee_currency":"BTC"
},
{
"instrument_id":148427,
"instrument_name":"BTC-31MAR23-15000-P",
"price":"0.2421",
"product_code":"DO",
"quantity":"50",
"ratio":"2",
"side":"SELL",
"venue_trade_id":"141186362",
"fee_quantity":"0.0075",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-16DEC22-15000-P_BTC-31MAR23-100000-C_BTC-31MAR23-15000-P",
"description":"Cstm +1 Put 16 Dec 22 15000\n +3 Call 31 Mar 23 100000\n -2 Put 31 Mar 23 15000",
"quote_currency":"BTC",
"mark_price":"-0.4699"
},
{
"id":"bt_2Ibp2e0R8HNcoCd709gUyVs4zho",
"exec_id":"365632",
"order_id":"o_2Ibp2dzq4zEk6Yu3HcFs45n3NQ4",
"rfq_id":"r_2Ibp1GHnnO13qvmGeJ6pwAyFAfP",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670459931216.5679,
"filled_at":1670459931000.0,
"side":"BUY",
"price":"-1.0797",
"quantity":"50",
"filled_quantity":"50",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":175553,
"instrument_name":"BTC-29SEP23-15000-C",
"price":"0.3751",
"product_code":"DO",
"quantity":"50",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186360",
"fee_quantity":"0",
"fee_currency":"BTC"
},
{
"instrument_id":155835,
"instrument_name":"BTC-31MAR23-28000-P",
"price":"0.7274",
"product_code":"DO",
"quantity":"100",
"ratio":"2",
"side":"SELL",
"venue_trade_id":"141186359",
"fee_quantity":"0.015",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-29SEP23-15000-C_BTC-31MAR23-28000-P",
"description":"Cstm +1 Call 29 Sep 23 15000\n -2 Put 31 Mar 23 28000",
"quote_currency":"BTC",
"mark_price":"-1.0763"
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Trades. |
> id | string | true | The Paradigm created unique identifier of the Trade. |
> exec_id | string | true | The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue. |
> order_id | string | true | The Paradigm created unique Order identifier associated with the Trade. |
> rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
> kind | string | true | The nature of the strategy traded. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
> state | string | true | The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT , FILLED , REJECTED . |
> role | string | true | The role of the user in the Trade. Valid values include TAKER , MAKER . |
> executed_at | decimal | true | The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm. |
> filled_at | decimal | true | The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle. |
> side | string | true | The direction of the user in the trade. Valid values include BUY , SELL . |
> price | string | true | The strategy price of the trade, denominated the quote_currency of the RFQ. |
> quantity | string | true | The amount of the trade, denominated in the clearing_currency of the RFQ. |
> filled_quantity | string | true | The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ. |
> rejected_quantity | string | true | The rejected amount of the trade, denominated in the clearing_currency of the RFQ. |
> rejected_party | string | true | The counterparty responsible for the Trade Rejection. Valid values include USER , COUNTERPARTY . null of Trade successfully settled. |
> rejected_reason | string | true | The reason for the Trade Rejection. null if Trade successfully settled. |
> legs | Array of Objects | true | The composite Instrument legs of the Trade. |
>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>> instrument_name | string | true | The Paradigm normalized name of the Instrument used across Paradigm’s API. |
>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. |
>> side | string | true | The direction of the composite Instrument to the Trade. Valid values include BUY , SELL . |
>> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
>> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
>> quantity | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
>> venue_trade_id | string | true | The corresponding unique trade identifier present on the underlying settlement venue. Value to be -1 if rejected. |
>> fee_quantity | string | true | The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency . |
>> fee_currency | string | true | The currency the fee_amount is denominated in. |
> strategy_description | string | true | The standardized description of the Trade’s composite Instruments. |
> description | string | true | The verbose description of the Trade’s composite Instruments. |
> quote_currency | string | true | The currency in the price is denominated in, denominated in the quote_currency of the RFQ. |
> mark_price | string | true | The strategy mark price from the underlying settlement venue of the composite Instruments to the trade. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3005 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [GET] /trades/{trade_id}
/trades/{trade_id} Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trades/123 \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/trades/123',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/trades/{trade_id}
method = 'GET'
path = '/v2/drfq/trades/123'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/trades/123", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /trades/{trade_id}
request returns the trade specified in the endpoint.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
trade_id | endpoint | string | true | The Paradigm created unique Trade identifier. |
/trades/{trade_id} Response example
200 Response
{
"id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
"exec_id":"365636",
"order_id":"o_2IbpRmLbgT7yUGl3lgGD9GogSQ1",
"rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
"venue":"DBT",
"kind":"OPTION",
"state":"COMPLETED",
"role":"TAKER",
"executed_at":1670460131896.015,
"filled_at":1670460132000.0,
"side":"BUY",
"price":"0.2397",
"quantity":"50",
"filled_quantity":"50",
"rejected_quantity":"0",
"rejected_party":null,
"rejected_reason":null,
"legs":[
{
"instrument_id":154564,
"instrument_name":"BTC-30JUN23-14000-P",
"price":"0.2397",
"product_code":"DO",
"quantity":"50",
"ratio":"1",
"side":"BUY",
"venue_trade_id":"141186632",
"fee_quantity":"0.0075",
"fee_currency":"BTC"
}
],
"strategy_description":"DO_BTC-30JUN23-14000-P",
"description":"Put 30 Jun 23 14000",
"quote_currency":"BTC",
"mark_price":"0.2407"
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The Paradigm created unique identifier of the Trade. |
exec_id | string | true | The corresponding Block Trade unique identifier created by either the Paradigm or the underlying settlement venue. |
order_id | string | true | The Paradigm created unique Order identifier associated with the Trade. |
rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
kind | string | true | The nature of the strategy traded. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
state | string | true | The indication if the trade has reached settlement finality. Valid values include PENDING_SETTLEMENT , FILLED , REJECTED . |
role | string | true | The role of the user in the Trade. Valid values include TAKER , MAKER . |
executed_at | decimal | true | The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm. |
filled_at | decimal | true | The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. -1 if the Trade failed to successfully settle. |
side | string | true | The direction of the user in the trade. Valid values include BUY , SELL . |
price | string | true | The strategy price of the trade, denominated the quote_currency of the RFQ. |
quantity | string | true | The amount of the trade, denominated in the clearing_currency of the RFQ. |
filled_quantity | string | true | The successfully filled amount of the trade, denominated in the clearing_currency of the RFQ. |
rejected_quantity | string | true | The rejected amount of the trade, denominated in the clearing_currency of the RFQ. |
rejected_party | string | true | The counterparty responsible for the Trade Rejection. Valid values include USER , COUNTERPARTY . null of Trade successfully settled. |
rejected_reason | string | true | The reason for the Trade Rejection. null if Trade successfully settled. |
legs | Array of Objects | true | The composite Instrument legs of the Trade. |
> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument., |
> instrument_name | string | true | The Paradigm normalized name of the Instrument used across Paradigm’s API. |
> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. |
> side | string | true | The direction of the composite Instrument to the Trade. Valid values include BUY , SELL . |
> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> quantity | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
> venue_trade_id | string | true | The corresponding unique trade identifier present on the underlying settlement venue. |
> fee_quantity | string | true | The amount of fees paid/earned to execute this leg on the underlying settlement venue, denominated in the fee_currency . |
> fee_currency | string | true | The currency the fee_amount is denominated in. |
strategy_description | string | true | The standardized description of the Trade’s composite Instruments. |
description | string | true | The verbose description of the Trade’s composite Instruments. |
quote_currency | string | true | The currency in the price is denominated in, denominated in the quote_currency of the RFQ. |
mark_price | string | true | The strategy mark price from the underlying settlement venue of the composite Instruments to the trade. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
404 | 3406 | "Unavailable trade" | Unavailable/invalid trade id provided in request. |
DRFQv2: [GET] /trade_tape
/trade_tape Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/trade_tape \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/trade_tape',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/trade_tape
method = 'GET'
path = '/v2/drfq/trade_tape'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/trade_tape", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /trade_tape
request returns all successfully cleared trades.
To return complete results, users must paginate by providing the response's next
key value for the cursor
query string parameter in the subsequent request.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The cursor value used to paginate through pages. The value to use is the next key value from the response. |
page_size | query | string | false | The number of elements to return per page. |
rfq_id | query | string | false | The Paradigm created unique identifier associated with the RFQ. |
venue | query | string | false | The underlying settlement venue to return Instruments for. Valid values include DBT , BIT , BYB . |
product_codes | query | string | false | The Paradigm created Product Codes of the composite Instruments. The request can contain multiple codes such as ?product_codes=DO,CF . |
strategies | query | string | false | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
/trade_tape Response example
200 Response
{
"count":2921,
"next":"cD0yMDIyLTEyLTA4KzAwJTNBMzglM0E1MS4yMTY1NjglMkIwMCUzQTAw",
"results":[
{
"id":"bt_2IbpRmMSOqnQKwPkGEDr2VDZp5e",
"rfq_id":"r_2IbpMsUESAt5bfVEQp7c32SbIDJ",
"venue":"DBT",
"kind":"OPTION",
"state":"FILLED",
"executed_at":1670460131896.015,
"filled_at":1670460132000.0,
"side":"SELL",
"price":"0.2397",
"quantity":"50",
"legs":[
{
"instrument_id":154564,
"instrument_name":"BTC-30JUN23-14000-P",
"ratio":"1",
"side":"BUY",
"price":"0.2397",
"product_code":"DO",
"quantity":"50"
}
],
"strategy_description":"DO_BTC-30JUN23-14000-P",
"description":"Put 30 Jun 23 14000",
"quote_currency":"BTC",
"mark_price":"0.2407"
},
{
"id":"bt_2IbpM7fQWGK1bILTw2OvwPnMc5P",
"rfq_id":"r_2IbpLUknqWjvjJYJxMpt4uv36Lr",
"venue":"DBT",
"kind":"OPTION",
"state":"FILLED",
"executed_at":1670460086203.6682,
"filled_at":1670460086000.0,
"side":"SELL",
"price":"0.2724",
"quantity":"25",
"legs":[
{
"instrument_id":182233,
"instrument_name":"BTC-24FEB23-17000-C",
"ratio":"1",
"side":"BUY",
"price":"0.2724",
"product_code":"DO",
"quantity":"25"
}
],
"strategy_description":"DO_BTC-24FEB23-17000-C",
"description":"Call 24 Feb 23 17000",
"quote_currency":"BTC",
"mark_price":"0.2735"
},
{
"id":"bt_2IbpBwZLazIBOcI24DYsD7ihRoy",
"rfq_id":"r_2Ibp7AUyp9HTimRTY1TiGqNcI9a",
"venue":"DBT",
"kind":"OPTION",
"state":"FILLED",
"executed_at":1670460005229.808,
"filled_at":1670460005000.0,
"side":"SELL",
"price":"4.4713",
"quantity":"50",
"legs":[
{
"instrument_id":153021,
"instrument_name":"BTC-30JUN23-100000-P",
"ratio":"1",
"side":"BUY",
"price":"4.9549",
"product_code":"DO",
"quantity":"50"
},
{
"instrument_id":153009,
"instrument_name":"BTC-30JUN23-15000-P",
"ratio":"2",
"side":"SELL",
"price":"0.2418",
"product_code":"DO",
"quantity":"100"
}
],
"strategy_description":"DO_BTC-30JUN23-100000-P_BTC-30JUN23-15000-P",
"description":"Cstm +1 Put 30 Jun 23 100000\n -2 Put 30 Jun 23 15000",
"quote_currency":"BTC",
"mark_price":"4.4741"
},
{
"id":"bt_2Ibp2e4vIBlyII2FDG4hcfV4aXr",
"rfq_id":"r_2Ibozkpq0slrvDz93ZPH6u0AHRV",
"venue":"DBT",
"kind":"OPTION",
"state":"FILLED",
"executed_at":1670459931825.164,
"filled_at":1670459932000.0,
"side":"SELL",
"price":"-0.4729",
"quantity":"25",
"legs":[
{
"instrument_id":182746,
"instrument_name":"BTC-16DEC22-15000-P",
"ratio":"1",
"side":"BUY",
"price":"0.0092",
"product_code":"DO",
"quantity":"25"
},
{
"instrument_id":141457,
"instrument_name":"BTC-31MAR23-100000-C",
"ratio":"3",
"side":"BUY",
"price":"0.0007",
"product_code":"DO",
"quantity":"75"
},
{
"instrument_id":148427,
"instrument_name":"BTC-31MAR23-15000-P",
"ratio":"2",
"side":"SELL",
"price":"0.2421",
"product_code":"DO",
"quantity":"50"
}
],
"strategy_description":"DO_BTC-16DEC22-15000-P_BTC-31MAR23-100000-C_BTC-31MAR23-15000-P",
"description":"Cstm +1 Put 16 Dec 22 15000\n +3 Call 31 Mar 23 100000\n -2 Put 31 Mar 23 15000",
"quote_currency":"BTC",
"mark_price":"-0.4699"
},
{
"id":"bt_2Ibp2e0R8HNcoCd709gUyVs4zho",
"rfq_id":"r_2Ibp1GHnnO13qvmGeJ6pwAyFAfP",
"venue":"DBT",
"kind":"OPTION",
"state":"FILLED",
"executed_at":1670459931216.5679,
"filled_at":1670459931000.0,
"side":"SELL",
"price":"-1.0797",
"quantity":"50",
"legs":[
{
"instrument_id":175553,
"instrument_name":"BTC-29SEP23-15000-C",
"ratio":"1",
"side":"BUY",
"price":"0.3751",
"product_code":"DO",
"quantity":"50"
},
{
"instrument_id":155835,
"instrument_name":"BTC-31MAR23-28000-P",
"ratio":"2",
"side":"SELL",
"price":"0.7274",
"product_code":"DO",
"quantity":"100"
}
],
"strategy_description":"DO_BTC-29SEP23-15000-C_BTC-31MAR23-28000-P",
"description":"Cstm +1 Call 29 Sep 23 15000\n -2 Put 31 Mar 23 28000",
"quote_currency":"BTC",
"mark_price":"-1.0763"
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
count | integer | true | The number of elements returned in the response. |
next | string | true | Cursor string value to use to paginate results. Equal to null if no more pages are available. |
results | Array of Objects | true | Array of Objects with details related to specific Trades. |
> id | string | true | The Paradigm created unique identifier of the Trade. |
> rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
> venue | string | true | The underlying settlement venue of the RFQ. Valid values include DBT , BIT , BYB . |
> kind | string | true | The nature of the strategy traded. Valid values include OPTION , FUTURE , OPTION_FUTURE . |
> state | string | true | The indication if the trade has reached settlement finality. Valid values include FILLED . |
> executed_at | decimal | true | The time in UNIX milliseconds since the epoch when the trade was executed on Paradigm. |
> filled_at | decimal | true | The time in UNIX milliseconds since the epoch when trade with either successfully settled or rejected on Paradigm. |
> side | string | true | The direction of the user in the trade. Valid values include BUY , SELL . |
> price | string | true | The strategy price of the trade, denominated the quote_currency of the RFQ. |
> quantity | string | true | The amount of the trade, denominated in the clearing_currency of the RFQ. |
> legs | string | true | The composite Instrument legs of the Trade. |
>> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
>> instrument_name | string | true | The Paradigm normalized name of the Instrument to be used across Paradigm’s API. |
>> ratio | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. |
>> side | string | true | The direction of the composite Instrument to the Trade. Valid values include BUY , SELL . |
>> price | string | true | The price of the Instrument leg, denominated in the quote_currency of the RFQ. |
>> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
>> quantity | string | true | The size of the Instrument leg, denominated in the clearing_currency of the RFQ. |
> strategy_description | string | true | The standardized description of the Trade’s composite Instruments. |
> description | string | true | The verbose description of the Trade’s composite Instruments. |
> quote_currency | string | true | The currency the price is denominated in. |
> mark_price | string | true | The strategy mark price from the underlying settlement venue of the composite Instruments to the trade. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 100 | "Invalid filter parameter" | You provided invalid value to one or more filter parameters. |
DRFQv2: [POST] /pricing
/pricing Request example
# You can also use wget
curl -X POST https://api.testnet.paradigm.trade/v2/drfq/pricing \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/pricing',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
import json
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# POST /v2/drfq/pricing
method = 'POST'
path = '/v2/drfq/pricing'
payload = {
"bid_price": "7950",
"ask_price": "9600",
"legs": [
{
"instrument_id": 1234,
"ratio": "1",
"side": "BUY"
},
{
"instrument_id": 123,
"ratio": "1",
"side": "SELL"
}
]
}
json_payload = json.dumps(payload)
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=json_payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.post(
host+path,
headers=headers,
json=payload
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("POST", "https://api.testnet.paradigm.trade/v2/drfq/pricing", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [POST] /pricing
request returns the strategy pricing of the specified composite instruments.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
bid_price | body | string | false | The strategy price of the Order from the BUY side direction. |
ask_price | body | string | false | The strategy price of the Order from the SELL side direction. |
legs | body | Array of Objects | true | The composite Instrument legs of the RFQ. |
> instrument_id | body | integer | true | The Paradigm created unique identifier of the Instrument. |
> ratio | body | string | true | The relative multiplier applied to the quantity of the Instrument’s amount relative to the amount of the RFQ. Maximum of 2 decimal places. |
> side | body | string | true | The direction of the composite leg relative to the RFQ. Valid values include BUY , SELL . |
/pricing Response example
200 Response
{
"bid_prices": ["32655.32", "24705.32"],
"ask_prices": ["33606.76", "24006.76"]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
bid_prices | Array of strings | true | Individual leg composite leg prices for the BUY direction. [] if bid_price is not a part of request payload. |
ask_prices | Array of strings | true | Individual leg composite leg prices for the SELL direction. [] if ask_price is not a part of request payload. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
400 | 3002 | "Invalid leg pricing parameters" | You provided invalid value to one or more pricing parameters. |
400 | 3200 | "Invalid RFQ leg configuration" | You provided invalid legs to the pricing endpoint. |
400 | 3304 | "Submitted quote/s were outside venue's price bands" | Provided leg prices were outside of price bands of the underlying venue. |
400 | 3310 | "Cannot calculate sensical leg prices." | Leg prices couldn't be calculated. |
400 | 3311 | "Cannot calculate leg prices." | Leg prices couldn't be calculated. |
DRFQv2: [GET] /rfqs/{rfq_id}/bbo
/rfqs/bbo/{rfq_id} Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ACCESS_KEY'
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ACCESS_KEY'
};
fetch('https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v2/drfq/rfqs/{rfq_id}/bbo
method = 'GET'
path = '/v2/drfq/rfqs/123/bbo'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(
host+path,
headers=headers
)
print(response.status_code)
print(response.text)
package main
import (
"bytes"
"net/https"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer ACCESS_KEY"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := https.NewRequest("GET", "https://api.testnet.paradigm.trade/v2/drfq/rfqs/123/bbo", data)
req.Header = headers
client := &https.Client{}
resp, err := client.Do(req)
// ...
}
A [GET] /rfqs/{rfq_id}/bbo
request returns the market data for the RFQ's composite instruments from the underlying settlement venue.
If the best_bid_quantity
and best_bid_price
or best_ask_quantity
and best_ask_price
are equal to 0
, it means that one of the composite instruments of the market does not have an underlying screen order. We are working to remedy this in due course as so we return null
when this occurs.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | endpoint | string | true | The Paradigm created unique identifier of the RFQ. |
/rfqs/bbo/{rfq_id} Response example
200 Response
{
"rfq_id": "123213213",
"min_price": "21000.00",
"max_price": "22000.00",
"mark_price": "21500.00",
"best_bid_price": "0.01",
"best_ask_price": "0.011",
"best_bid_quantity": "10",
"best_ask_quantity": "10",
"created_at": 12321321321321321,
"legs": [
{
"best_bid_price": "0.01",
"best_ask_price": "0.011",
"best_bid_quantity": "10",
"best_ask_quantity": "10",
"instrument_id": 123231213213,
"instrument_name": "BTC-PERPETUAL",
"mark_price": "21500.00"
}
]
}
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
rfq_id | string | true | The Paradigm created unique identifier of the RFQ. |
min_price | string | true | The minimum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ. |
max_price | string | true | The maximum allowed price with which the RFQ can trade as per the underlying settlement venue’s trading price bands. Denominated in the quote_currency of the RFQ. |
mark_price | string | true | The strategy mark price of the RFQ’s composite Instruments from the underlying settlement venue. Denominated in the quote_currency of the RFQ. |
best_bid_price | string | true | The RFQ’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
best_ask_price | string | true | The RFQ’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
best_bid_quantity | string | true | The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
best_ask_quantity | string | true | The RFQ’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
created_at | decimal | true | The time in UNIX milliseconds since the epoch when the market data was received from the underlying venue. |
legs | Array of Objects | true | The composite Instruments of the RFQ. |
> instrument_id | integer | true | The Paradigm created unique identifier of the Instrument. |
> instrument_name | string | true | The Paradigm normalized name of the Instrument. |
> mark_price | string | true | The Instrument’s mark price from the underlying settlement venue, denominated in the quote_currency of the RFQ. |
> best_bid_price | string | true | The Instrument’s best bid price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
> best_ask_price | string | true | The Instrument’s best ask price from the underlying settlement venue’s Order Books. Denominated in the quote_currency of the RFQ. |
> best_bid_quantity | string | true | The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
> best_ask_quantity | string | true | The Instrument’s best bid amount from the underlying settlement venue’s Order Books. Denominated in the clearing_currency of the RFQ. |
Error Codes
HTTP Status Code | Paradigm Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials were not provided." | You did not provide authentication credentials. |
400 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
400 | 3202 | "Cannot calculate strategy bbo" | BBO strategy for provider RFQ Id could not be computed. |
DRFQv2: [GET] /mmp/status/
/mmp/status/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/mmp/status/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/mmp/status/
method = 'GET'
path = '/v1/grfq/mmp/status/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/mmp/status/ Response example
{
"rate_limit_hit": false
}
A [GET] /mmp/status/
request returns the desk's Market Maker Protection (MMP) status.
This endpoint takes no parameters as part of the request.
Response Schema
Status Code: 200
Name | Type | Required | Description |
---|---|---|---|
rate_limit_hit | bool | true | A flag indicating if rate limit was hit |
DRFQv2: [PATCH] /mmp/status/
/mmp/status/ Request example
# You can also use wget
curl -X PATCH https://api.testnet.paradigm.trade/v1/grfq/mmp/status/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# PATCH /v1/grfq/mmp/status/
method = 'PATCH'
path = '/v1/grfq/mmp/status/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.patch(host+path,
headers=headers)
print(response.status_code)
print(response.text)
A [PATCH] /mmp/status/
resets the Market Maker Protection (MMP) if triggered and enables the user to create new Quotes.
This endpoint takes no parameters as part of the request.
Response Schema
This request will return an HTTP Status Code of 204 to indicate success of operation.
Status Code 204
GRFQ - API Workflows
Paradigm operates Auto-Market Makers running on our Test environment. All available and created RFQs will have markets made upon them.
GRFQ: High Level
GRFQ is centred around the concepts of "RFQs", "Quotes", "Orders" and "Trades":
- RFQs are globally and publicly available strategies comprised of one or more instruments with specific quantity ratio attributes.
- Quotes are created by Takers and Makers as Quotes upon the Quote Book.
- Orders are created by Takers to execute upon existing Quotes.
- Trades occur when Orders (from Takers) and Quotes (from Makers) are matched and sent for clearing & settlement.
At a high level, the GRFQ workflow is:
- Taker creates an RFQ with the desired Instruments and quantity ratios.
- Makers Quote the RFQ.
- Takers can execute an Order upon an RFQ and consume Quotes which suit the set Limit Price & venue enforced "Block Size Minimums".
- Once a Quote and an Order are matched, the executions are sent to the underlying venue for clearing & settlement.
- Taker and Maker of the trade receive confirmation if clearing & settlement was successful or rejected.
- All Paradigm users are able to see cleared & settled Trades, but NOT the counterparties or the traded RFQ/Order/Quote
side
.
Key GRFQ Concepts
In GRFQ,
- RFQs are public auctions and all have open Quote Books.
- You do NOT select counterparties, anyone is able to contribute/execute upon the Quote Book.
- All trades are on an anonymous basis with no participant or directional information revealed.
- All resulting executions are subject to some venues' determined "Block Size Minimum". Paradigm will enforce this validation at the Quote & Order Execution level.
- There are partials fills of both Quotes and Orders.
- It is possible to have multiple trades where a number of Quotes are consumed by a single Order.
- WebSocket messages will contain two keys,
kind
andstatus
. You should use these keys to know the status and finality of the concept it's referring too.
GRFQ: Common Workflows
Important Note: Both the Taker and the Maker will receive all updates through the JSON-RPCoverWebSockets Notification channels for events relating to RFQs, Quotes, Orders and Trades.
A user is only a Maker where their Quote is executed upon by an Order. A user is only a Taker if they submit an Order which crosses an existing Quote.
Create/Check for RFQ
If you would like to create an RFQ or check if one exists, you should request the RESToverHTTP [POST] /rfqs/
endpoint.
Pull available Quotes on an RFQ
Each RFQ is composed of Quotes. Quotes are NOT aggregated by Price levels as is usual in centralized Quote Book.
Makers submit Quotes on RFQs and Paradigm returns them individually to all users as children of the RFQ primarily because of workflow complications relating to some venues' "Block Size Minimum" rules.
You should request the RESToverHTTP [GET] /quotes/
endpoint.
Submit a non-crossing Quote on an RFQ
Users are NOT able to submit Quotes which cross an existing resting Quote on an RFQ.
You should request the RESToverHTTP [POST] /rfqs/{rfq_id}/quotes/
endpoint.
Submit a crossing Quote/execute upon a Quote with an Order
Users are able to submit a Quote which crosses an existing Quote on an RFQ.
You should request the RESToverHTTP [POST] /rfqs/{rfq_id}/quotes/
.
Replace an existing Quote on an RFQ
Users are able to replace a previously submitted Quote for an existing RFQ.
You should request the RESToverHTTP [PUT] /rfqs/{rfq_id}/quotes/{quote_id}
endpoint.
Cancel a requested Order on an RFQ
Takers are not able to cancel a requested Order. You will receive a successful/erroneous response from the RESToverHTTP [POST] /rfqs/{rfq_id}/orders/
request with information regarding the outcome.
GRFQ: Executable Quote Book
RFQs are comprised of individual Quotes which are not aggregated by price level as is usual with standard centralized Quote Books. This was principally done to accommodate venue created & enforced "Block Size Minimums".
Not all venues have "Block Size Minimums", most notably Bybit, but the workflows for ranking+aggregating what is actually executable is the same for all venues with GRFQ.
So as the user, you are likely to have the following questions:
- Q: "What's the priority of Quotes as part of an RFQ?"
- A: Paradigm prioritises Quotes based upon Price & Time priority. This is the same prioritization mechanism as centralized Quote Books.
- Q: "How does the Block Size Minimum affect what I can execute?"
- A: As Paradigm must conform to the venue enforced Block Size Minimum, so too must you. This means a number of things:
- All Quotes must meet the Block Size Minimum Quantity requirement.
- All Orders must meet the Block Size Minimum Quantity requirement.
- Paradigm will consume multiple Quotes as part of a single Order Execution. If part of a Quote is consumed and the remaining quantity is below the Block Size Minimum, this Quote will be canceled.
- Orders will consume Quotes up to the specified Limit Price, but may not be able to execute the complete requested quantity.
Workflow to create+manage your Quote Book
- Subscribe to the
quote_book
JSON-RPCoverWebSockets Notification Channel to receive updates relating to Quotes upon RFQs. - Request the RESToverHTTP [GET]
/quotes/
endpoint to return all existing Quotes on RFQs. - ADD/REMOVE/UPDATE your locally stored Quotes as updates are received through the
quote_book
WS Channel.
Workflow to create+manage your Executable Quote Book:
- Subscribe to the
quote_book
JSON-RPCoverWebSockets Notification Channel to receive updates relating to Quotes upon RFQs. - Request the RESToverHTTP [GET]
/quotes/
endpoint to return all existing Quotes on RFQs. - ADD/REMOVE/UPDATE your locally stored Quotes as updates are received through the
quote_book
WS Channel. - Determine the Block Size Minimum requirement for the RFQ you are trading upon. This will be the minimum executable quantity.
- For Deribit, this is 25BTC for BTC Options RFQs and $200kUSD for Futures RFQs.
- For Bybit, this is $1USD for Futures RFQs.
- Create levels in your Executable Quote Book by the Block Size minimum quantity size to ascertain the size & price levels.
Helpful perspectives:
- GRFQ is fantastic if you want to trade large size and have a target price in mind. The ability to submit "Limit Orders" as either resting Quotes or Orders with a limit price enables this.
- Thinking in terms of size & price levels is the best way.
- When you submit an Order, Paradigm, depending on the size of your Order and the Quote Book at the time, will likely consume multiple Quotes. This means you will have to wait for multiple trades to clear on the underlying venue.
GRFQ: Comprehensive API Workflow Paths
GRFQ: RFQ Created
Taker's & Maker's Perspective:
- Subscribed to
rfq
WS Channel. - Receives WS message with
kind
==ADDED
,status
==ACTIVE
.
GRFQ: RFQ Expires
Taker's & Maker's Perspective:
- Subscribed to
rfq
WS Channel. - Receives WS message with
kind
==REMOVED
,status
==EXPIRED
.
GRFQ: Quote Created
Taker's & Maker's Perspective:
- Subscribed to the
quote
andquote_book
WS Channels. - Asynchronously:
- Receives WS messages on
quote_book
WS Channel withkind
==ADDED
andstatus
==OPEN
. - Maker only, receives WS messages on
quote
WS Channel withkind
==NEW
andstatus
==OPEN
.
- Receives WS messages on
GRFQ: Quote Canceled
Taker's & Maker's Perspective:
- Subscribed to the
quote
andquote_book
WS Channels. - Asynchronously:
- Receives WS messages on
quote_book
WS Channel withkind
==REMOVED
andstatus
==CLOSED
. - Maker only, receives WS messages on
quote
WS Channel withkind
==CANCELED
andstatus
==CLOSED
.
- Receives WS messages on
GRFQ: Matched Quote and Order
Taker's Perspective:
- Subscribed to
quote_book
,order
,trade
andtrade_tape
WS Channels. - Asynchronously:
- Receives a single WS message on
order
WS Channel withkind
==PENDING_FILL
andstatus
==OPEN
. - Receives a WS message on the
quote_book
WS Channel:- If Quote is completely consumed
kind
==REMOVED
. - If Quote is partially consumed
kind
==UPDATED
.
- If Quote is completely consumed
- Receives a single WS message on
- Asynchronously:
- If Trade execution is successful at clearing & settlement:
- Receives WS messages on
trade
WS channel withkind
==CONFIRMATION
for each successful trade execution as part of the Order. - Receives WS messages on
trade_tape
WS channel withkind
==COMPLETED
for each successful trade execution through Paradigm.
- Receives WS messages on
- If Trade execution is rejected at clearing & settlement:
- Receives WS messages on
trade
WS channel withkind
==REJECTION
for each rejected trade execution as part of the Order.
- Receives WS messages on
- In the event of Successful/Rejected executions at clearing & settlement:
- Receives WS messages on
order
on WS channel withkind
==SUMMARY
andstatus
==CLOSED
.
- Receives WS messages on
- If Trade execution is successful at clearing & settlement:
Maker's Perspective:
- Subscribed to
quote_book
,quote
,trade
andtrade_tape
WS Channels. - Asynchronously:
- Receives a single WS message on
quote
WS Channel:- If Quote is completely consumed
kind
==PENDING_FILL
andstatus
==CLOSED
.- Also occurs if the Remaining Quantity is below the venue's enforced "Block Size Minimum".
- If Quote is partially consumed
kind
==PENDING_FILL
andstatus
==OPEN
.
- If Quote is completely consumed
- Receives a WS message on the
quote_book
WS Channel:- If Quote is completely consumed
kind
==REMOVED
. - If Quote is partially consumed
kind
==UPDATED
.
- If Quote is completely consumed
- Receives a single WS message on
- Asynchronously:
- If Trade execution is successful at clearing & settlement:
- Receives WS messages on
trade
WS channel withkind
==CONFIRMATION
for each successful trade execution as part of the Order. - Receives WS messages on
trade_tape
WS channel withkind
==COMPLETED
for each successful trade execution through Paradigm. - If a Quote is only partially consumed at execution, meaning there is remaining available quantity:
- Receives a WS message on the
quote
WS Channel withkind
==PARTIALLY_FILLED
andstatus
==OPEN
.
- Receives a WS message on the
- If a Quote is only completely consumed at execution, meaning there is NO remaining available quantity:
- Receives a WS message on the
quote
WS Channel withkind
==FILLED
andstatus
==OPEN
.
- Receives a WS message on the
- Receives WS messages on
- If Trade execution is rejected at clearing & settlement:
- Receives WS messages on
trade
WS channel withkind
==REJECTION
for each rejected trade execution as part of the Order. - Receives a WS message on the
quote
WS Channel withkind
==CANCELED
andstatus
==CLOSED
.
- Receives WS messages on
- If Trade execution is successful at clearing & settlement:
GRFQ - Code Examples
Reach out if you ever need any help! We are more than happy to help.
You will need to update the provided Code Examples with your own Paradigm Access Key and Secret Key.
You can find all existing examples on our GitHub: https://github.com/tradeparadigm/code-samples
Note: All examples in this section are in Python3.
GRFQ: JSON-RPCoverWebSockets
GRFQ: Authentication + Subscribe & Unsubscribe to Notification Channels
- Authenticate, establish a heartbeat and Subscribe to the
rfq
,quote_book
,quote
,order
,trade
, andtrade_tape
JSON-RPCoverWebSockets Notification Channels.
GRFQ - WebSocket Notifications Channels
GRFQ: rfq
An example of the
rfq
notification received when an RFQ is created
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfq",
"data":{
"kind":"ADDED",
"rfq":{
"id":1232,
"created":1628038165427.771,
"description":"Call 4 Aug 21 39000",
"last_trade":null,
"latest_activity":1628038165427.839,
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code": "CP",
"venue":"DBT",
"legs":[
{
"instrument":"BTC-4AUG21-39000-C",
"product_code":"DO",
"ratio":"1",
"venue_instrument":"BTC-4AUG21-39000-C",
"side":"BUY"
}
]
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
rfq
notification received when an RFQ expires
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"rfq",
"data":{
"kind":"REMOVED",
"rfq":{
"id":589,
"venue":"DBT",
"created":1625191497588.2312,
"description":"FSpd 2 Jul 21 / 25 Mar 22",
"last_trade":null,
"latest_activity":1625191497588.316,
"legs":[
{
"instrument":"BTC-2JUL21",
"venue_instrument":"BTC-2JUL21",
"product_code":"CF",
"ratio":"1",
"side":"SELL"
},
{
"instrument":"BTC-25MAR22",
"venue_instrument":"BTC-25MAR22",
"product_code":"CF",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"status":"EXPIRED",
"strategy_code": "FS"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to RFQs are sent through the rfq
WebSocket Notifications channel.
This is a public channel and consumable by all.
Notifications received through the rfq
WebSocket channel can include RFQ creations, expirations, and updates. Updates are used to update the latest_activity
and last_trade
fields while the rfq
is active.
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. Valid value is rfq . |
data | object | true | |
> kind | string | true | WS Action. Valid values include ADDED , REMOVED , UPDATED . |
> rfq | object | true | |
>> id | int | true | The Paradigm created unique identifier of the RFQ. |
>> venue | string | true | The underlying venue the RFQ is cleared & settled upon. Valid values include DBT , BIT , and BYB . |
>> created | number | true | Time in unix milliseconds since the epoch when the RFQ was created. |
>> description | string | true | Paradigm created description of the RFQ. |
>> last_trade | object | true | null if RFQ has not been traded. |
>>> traded | number | false | Time in unix milliseconds since the epoch when the the Trade occurred. |
>>> quantity | string | false | The size of the trade in the contract units of the RFQ. |
>>> price | string | false | The price the RFQ was Traded at. |
>> latest_activity | number | true | Time in unix milliseconds since the epoch when the RFQ was last acted upon. |
>> legs | array of objects | true | |
>>> instrument | string | true | The Paradigm standardized name of the Instrument. |
>>> venue_instrument | string | true | The name of the Instrument per the underlying venue's naming convention. |
>>> product_code | string | true | The Paradigm created product code of the Instrument. |
>>> ratio | string | true | The quantity multiple relative to other legs. |
>>> price | string | false | The price of the Instrument in the Quote Currency of the RFQ. |
>>> side | string | true | The direction of the leg. Valid values include BUY and SELL . |
>> product_codes | array of strings | true | Paradigm created product codes being traded in the RFQ. |
>> status | string | true | Status of the RFQ. Valid values include ACTIVE and EXPIRED . |
>> strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group |
GRFQ: quote_book
An example of the
quote_book
notification received when a Quote is newly added to the Quote Book
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote_book",
"data":{
"kind":"ADDED",
"quote":{
"remaining_quantity":"20000",
"side":"BUY",
"rfq_id":816,
"id":482396,
"price":"-9",
"status":"OPEN",
"created":1626155549137.585
"last_activity":1626155549137.600
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote_book
notification received when a Quote is removed from the Quote Book
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote_book",
"data":{
"kind":"REMOVED",
"quote":{
"id":482395,
"side":"SELL",
"created":1626155407461.441,
"last_activity":1626155407461.512,
"rfq_id":816,
"status":"CLOSED",
"price":"-13",
"remaining_quantity":"20000"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote_book
notification received when a Quote is updated in the Quote Book
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote_book",
"data":{
"kind":"UPDATED",
"quote":{
"remaining_quantity":"1990000",
"side":"SELL",
"rfq_id":816,
"id":482399,
"price":"9",
"status":"OPEN",
"created":1626155762785.293
"last_activity":1626155762785.315
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
Updates relating to Quotes upon RFQs are sent through the quote_book
WebSocket Notifications channel.
This is a public channel and is consumable by all. This is the channel you should use to create your own Quote Book & Executable Quote Book.
Updates received through the quote_book
WebSocket Notification channel can include newly created quotes, removed quotes as well as updates to existing Quotes.
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. |
data | object | true | |
> kind | string | true | The action of the message. Valid values include ADDED , REMOVED , UPDATED . |
> quote | object | true | |
> side | string | true | The side of the Quote from the Maker's perspective. Valid values include BUY and SELL . |
> rfq_id | int | true | The Paradigm created unique identifier of the RFQ. |
> id | int | true | The Paradigm created unique identifier of the Quote. |
> price | string | true | The price in the Quote Currency of the RFQ. |
> status | string | true | The status of the Quote. Valid values include OPEN , CLOSED . |
> created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
> last_activity | number | true | The time in unix milliseconds since the epoch when the Quote was updated. |
> remaining_quantity | string | true | The remaining Quantity upon the Quote in contract units of the RFQ. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired with seq_group. |
GRFQ: quote
An example of the
quote
notification received when a Quote is created
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"NEW",
"quote":{
"id":709037,
"status":"OPEN",
"maker":"DSK95",
"created":1628041444199.396,
"original_quantity":"50",
"rfq_id":1232,
"price":"0.004",
"remaining_quantity":"50",
"side":"BUY",
"client_order_id":""
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote
notification received when a Quote is canceled
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"CANCELED",
"quote":{
"id":2776215,
"order":{
"id":266357,
"client_order_id":"st121221",
"filled_quantity":"0",
"filled_average_price":"0",
"limit_price":"0.06",
"requested_quantity":"50",
"rfq_id":2073,
"side":"SELL",
"status":"OPEN",
"venue":"DBT"
},
"status":"CLOSED",
"maker":"DSK95",
"remaining_quantity":"22",
"side":"SELL",
"created":1631590685753.57,
"original_quantity":"22",
"client_order_id":"st12122",
"rfq_id":2073,
"price":"0.06"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote
notification received when a Quote is being executed upon
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"PENDING_FILL",
"quote":{
"original_quantity":"34",
"order":{
"id":266376,
"client_order_id":"st12122121",
"filled_quantity":"26",
"filled_average_price":"0.0904",
"limit_price":"0.1",
"requested_quantity":"60",
"rfq_id":2073,
"side":"BUY",
"status":"CLOSED",
"venue":"DBT"
},
"id":2776296,
"side":"BUY",
"price":"0.1",
"rfq_id":2073,
"created":1631591051681.613,
"status":"OPEN",
"client_order_id":"st121221",
"remaining_quantity":"7",
"maker":"DSK95"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote
notification received when a Quote has been partially filled
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"PARTIALLY_FILLED",
"quote":{
"rfq_id":816,
"id":482399,
"remaining_quantity":"1990000",
"status":"OPEN",
"client_order_id":"",
"price":"9",
"side":"SELL",
"created":1626155762785.2932,
"maker":"DSK95",
"original_quantity":"2000000"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote
notification received when a Quote has been partially filled & is partially executed again
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"PENDING_FILL",
"quote":{
"maker":"DSK95",
"rfq_id":816,
"client_order_id":"",
"price":"-13",
"side":"SELL",
"id":482407,
"created":1626156440976.632,
"status":"OPEN",
"original_quantity":"50000",
"remaining_quantity":"20000"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
quote
notification received when a Quote has been completely executed upon
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"quote",
"data":{
"kind":"PARTIALLY_FILLED",
"quote":{
"side":"BUY",
"rfq_id":2073,
"maker":"DSK95",
"status":"CLOSED",
"id":2776296,
"created":1631591051681.613,
"remaining_quantity":"7",
"order":{
"id":266376,
"client_order_id":"st12",
"filled_quantity":"26",
"filled_average_price":"0.0904",
"limit_price":"0.1",
"requested_quantity":"60",
"rfq_id":2073,
"side":"BUY",
"status":"CLOSED",
"venue":"DBT"
},
"price":"0.1",
"original_quantity":"34",
"client_order_id":"st12"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to Quotes upon RFQs are sent through the quote
WebSocket Notifications channel.
This is a private channel and only provides updates to the Maker who created the Quote.
Updates received through the quote
WebSocket Notification channel can include newly created quotes, removed quotes, quotes pending settlement & clearing, quotes which are partially filled as well as quotes which are completely filled.
Quotes which are executed upon and a rejection occurs at the underlying venue are canceled upon rejected. The remaining_quantity
of the Quote is no longer available on the Quote Book. It does not matter which party is to blame, the Quote is kind
== CANCELED
and status
== CLOSED
.
Quotes which have been [PATCH] /rfqs/{rfq_id}/quotes/{quote_id}/
have the original quote kind
== CANCELED
and status
== CLOSED
and a new Quote with kind
== NEW
and status
== OPEN
.
Workflow Steps:
- Maker creates Quote.
kind
==NEW
&status
==OPEN
. - Taker partially executes upon Quote.
kind
==PENDING_FILL
&status
==OPEN
.- Upon finality at settlement & clearing, Maker receives
kind
==PARTIALLY_FILLED
&status
==OPEN
.
- Upon finality at settlement & clearing, Maker receives
- Taker partially executes upon already partially executed Quote.
kind
==PENDING_FILL
&status
==OPEN
.- Upon finality at settlement & clearing, Maker receives
kind
==PARTIALLY_FILLED
&status
==OPEN
.
- Upon finality at settlement & clearing, Maker receives
- Taker executes upon a Quote, but the Trade is rejected by the underlying venue.
kind
==CANCELED
&status
==CLOSED
. - Taker completely executes quote as so there is
0
remaining_quantity
.kind
==FILLED
&status
==CLOSED
.
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. |
data | object | true | |
> kind | string | true | The action of the message. Valid values include NEW , CANCELED , PENDING_FILL , PARTIALLY_FILLED , FILLED . |
> quote | object | true | |
>> order | object | false | Present if Quote crosses the existing market. |
>>> id | int | false | The Paradigm created unique identifier of the Order. |
>>> client_order_id | string | false | A unique user created identifier for the Order. |
>>> filled_quantity | string | false | The filled quantity of the Order in the contract units of the RFQ. |
>>> filled_average_price | string | false | The average filled price of the Order in the quote currency of the RFQ. |
>>> limit_price | string | false | The price of the Order in quote currency of the RFQ. |
>>> requested_quantity | string | false | The requested crossing quantity of the Order. |
>>> rfq_id | int | false | The Paradigm created unique identifier of the RFQ the Order is a child of. |
>>> side | string | false | The direction of the Order. Valid values include BUY and SELL . |
>>> status | string | false | The current status of the Order. Valid values include OPEN and CLOSED . |
>>> venue | string | false | Underlying venue RFQ is cleared & settled upon. Valid values include DBT , BIT , BYB . |
>> created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
>> client_order_id | string | false | A unique user created identifier for the Quote. Not present if th subscribed user is not the Maker. |
>> id | int | true | The Paradigm created unique identifier of the Quote. |
>> maker | string | true | The Paradigm desk name of the Maker. |
>> original_quantity | string | true | The initial available quantity of the Quote in the contract units of the RFQ. |
>> price | string | true | The price of the Quote in the Quote Currency of the RFQ. |
>> remaining_quantity | string | true | The remaining available quantity of the Quote in the contract units of the RFQ. |
>> rfq_id | int | true | The Paradigm created unique identifier of the RFQ. |
>> side | string | true | The side of the Quote. Valid values include BUY and SELL . |
>> status | string | true | The status of the Quote. Valid values include OPEN and CLOSED . |
venue_error | object | false | |
> message | string | false | Example: "Deribit error: Trade rejected" |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired with this identifier. |
GRFQ: order
An example of the
order
notification received when an Order is Pending Fill
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"order",
"data":{
"kind":"PENDING_FILL",
"order":{
"id":1113,
"client_order_id":"",
"filled_quantity":"0",
"filled_average_price":"0",
"limit_price":"0.0054",
"requested_quantity":"25",
"rfq_id":1232,
"side":"BUY",
"status":"OPEN",
"venue":"DBT"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
order
notification received when an Order has reached finality
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"order",
"data":{
"kind":"SUMMARY",
"order":{
"id":1113,
"client_order_id":"",
"filled_quantity":"25",
"filled_average_price":"0.0054",
"limit_price":"0.0054",
"requested_quantity":"25",
"rfq_id":1232,
"side":"BUY",
"status":"CLOSED",
"venue":"DBT"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to Orders upon RFQs are sent through the order
WebSocket Notifications channel.
This is a private channel and only provides updates to the Taker who submitted the Order.
Updates received through the order
WebSocket Notification channel can include a pending fill notification as well as a summary of an order's execution at finality. You will receive a single kind
== PENDING_FILL
and kind
== SUMMARY
per order execution regardless of the number of Quotes consumed.
It is important to be aware that executions can be rejected by exchanges. You should the difference between the requested_quantity
and the filled_quantity
in the messages to be aware of the success of the execution(s).
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. |
data | object | true | |
> kind | string | true | The action of the message. Valid values include PENDING_FILL , SUMMARY . |
> order | object | true | |
>> id | int | true | The Paradigm created unique identifier of the Order. |
>> client_order_id | string | true | The user created unique value associated with the Order. |
>> filled_quantity | string | true | The filled quantity upon finality of the Order. |
>> filled_average_price | string | true | The average price of the filled quantity of the Order upon finality. |
>> limit_price | string | true | The price in the Quote currency of the RFQ of the Order. |
>> requested_quantity | string | true | The requested quantity of the Order in the contract units of the RFQ. |
>> rfq_id | int | true | The Paradigm created unique identifier of the RFQ. |
>> side | string | true | The direction of the Order. Valid values include BUY and SELL . |
>> status | string | true | The status of the Order. Valid values include OPEN , CLOSED . |
>> venue | string | true | The underlying venue the trade was settled upon. Valid values include DBT , BIT , BYB . |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired within seq_group |
GRFQ: trade
An example of the
trade
notification received when a Trade successfully settles and clears
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trade",
"data":{
"kind":"CONFIRMATION",
"trade":{
"quote_id":709033,
"action":"BUY",
"id":1257,
"rfq_id":1232,
"order_id":1120,
"quantity":"25",
"product_codes":[
"DO"
],
"traded":1628040498333.169,
"api_credential":"ParadigmTestNinetySix",
"price":"0.0055",
"client_order_id":"",
"status":"COMPLETED",
"legs":[
{
"id":2044,
"instrument":"BTC-4AUG21-39000-C",
"price":"0.0055",
"product_code":"DO",
"quantity":"25",
"ratio":"1",
"side":"BUY",
"action":"BUY",
"exec_id":"78144401"
}
],
"venue":"DBT",
"mark_price":"0.0054",
"quote_currency":"BTC",
"description":"Call 4 Aug 21 39000"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
An example of the
trade
notification received when a Trade is rejected at settlement and clearing
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trade",
"data":{
"kind":"REJECTION",
"trade":{
"order_id":1121,
"quote_currency":"BTC",
"id":1258,
"mark_price":"0.0054",
"client_order_id":"",
"price":"0.0055",
"quote_id":709033,
"quantity":"25",
"traded":1628040604131.9612,
"action":"BUY",
"api_credential":"ParadigmTestNinetySix",
"status":"REJECTED",
"description":"Call 4 Aug 21 39000",
"product_codes":[
"DO"
],
"legs":[
{
"id":2045,
"instrument":"BTC-4AUG21-39000-C",
"price":"0.0055",
"product_code":"DO",
"quantity":"25",
"ratio":"1",
"side":"BUY",
"action":"BUY",
"exec_id":null
}
],
"venue":"DBT",
"rfq_id":1232
}
},
"venue_error":{
"message":"DBT Error: Trade refused by exchange"
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
Updates relating to Trades upon RFQs are sent through the trade
WebSocket Notifications channel.
This is a private channel and only provides updates to the Taker & Maker of the Trade (matching of an Order and a Quote).
Updates received through the trade
WebSocket Notification channel can include trade success and rejection at clearing & settlement.
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. |
data | object | true | |
> kind | string | true | The action of the WS Message. Valid values include CONFIRMATION and REJECTION . |
> trade | object | true | |
>> api_credential | string | false | The name given the to the Exchange API Key entered on the Paradigm Client Admin dashboard. |
>> description | false | true | The Paradigm created description of the RFQ. |
>> client_order_id | string | true | A unique user created identifier for the Quote (Maker) or trade Order (Taker). |
>> rfq_id | int | true | The Paradigm created unique identifier of the RFQ. |
>> id | int | true | The Paradigm created unique identifier of the Trade. |
>> mark_price | string | false | The calculated mark price of the RFQ from the underlying venue's mark prices in the Quote Currency of the RFQ. |
>> order_id | int | false | The Paradigm created unique identifier of the Order that triggered execution. |
>> price | string | false | The price the Trade was executed at in the Quote Currency of the RFQ. |
>> product_codes | array of strings | false | The Paradigm created Product Codes of the trade. |
>> quantity | string | false | The size of the trade in contracts units of the RFQ. |
>> quote_currency | string | false | The Quote Currency of the RFQ executed upon. |
>> quote_id | int | false | The Paradigm created unique identifier of the Quote executed upon. |
>> action | string | false | The direction of the Trade from the perspective of the User. Valid values include BUY and SELL . |
>> status | string | true | Trade status. Valid values include COMPLETED , REJECTED . |
>> traded | number | false | The time in unix milliseconds since the epoch when the trade was cleared & settled. |
>> venue | string | true | Venue the underlying RFQ clears and settles upon. Valid values include DBT , BIT , BYB . |
>> legs | array of objects | true | |
>>> id | int | true | The Paradigm created unique individual leg trade identifier. |
>>> exec_id | string | false | The venue created leg trade execution identifier. Only available to participants of the trade. |
>>> instrument | string | true | The Paradigm standardized name of the Instrument. |
>>> quantity | string | true | The size of the leg traded in contract unit terms. |
>>> price | string | true | The price of the leg traded in the Quote Currency of the RFQ. |
>>> product_code | string | true | The Paradigm created product code of the Instrument traded. |
>>> ratio | string | true | The quantity multiplier relative to other Instrument legs. |
>>> side | string | true | The direction of the leg of the RFQ. Valid values include BUY , SELL . |
>>> action | string | true | The direction of the leg from the user's perspective Traded. Valid values include BUY , SELL . |
venue_error | object | false | Only present if the Trade was rejected by the underlying venue. |
> message | string | false | Reason the trade was rejected by the underlying venue. |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired with this identifier. |
GRFQ: trade_tape
An example of the
trade_tape
notification received when a trade settles & clears
{
"jsonrpc":"2.0",
"method":"subscription",
"params":{
"channel":"trade_tape",
"data":{
"kind":"COMPLETED",
"trade":{
"id":1260,
"description":"Call 4 Aug 21 39000",
"mark_price":"0.0054",
"price":"0.0054",
"product_codes":[
"DO"
],
"quantity":"25",
"quote_currency":"BTC",
"rfq_id":1232,
"traded":1628041230769.151,
"venue":"DBT"
}
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
All updates relating to Trades upon RFQs are sent through the trade_tape
WebSocket Notifications channel.
This is a public channel and provides updates about all Trades which are executed through Paradigm & successfully clear and settle on the underlying venue.
All notifications through the trade_tape
WebSocket channel do not reveal Taker or Maker information or the side
/action
the RFQ/Order/Quote was executed.
Member | Type | Required | Description |
---|---|---|---|
channel | string | true | WebSocket Notification Channel message is received upon. |
data | object | true | |
> kind | string | true | The action of the WS Message. Valid values include COMPLETED . |
> trade | object | true | |
>> id | int | true | The Paradigm created unique identifier of the Trade. |
>> description | string | true | The Paradigm created description of the RFQ. |
>> mark_price | string | true | The calculated mark price of the RFQ from the underlying venue's mark prices in the Quote Currency of the RFQ. |
>> price | string | true | The price the Trade was executed at in the Quote Currency of the RFQ. |
>> product_codes | array of strings | true | The Paradigm created Product Codes of the trade. |
>> quantity | string | true | The size of the trade in contracts units of the RFQ. |
>> quote_currency | string | true | The Quote Currency of the RFQ executed upon. |
>> rfq_id | int | true | The Paradigm created unique identifier of the RFQ. |
>> traded | number | true | The time in unix milliseconds since the epoch when the trade was cleared & settled. |
>> venue | string | true | Venue the underlying RFQ clears and settles upon. Valid values include DBT , BIT , BYB . |
meta | object | true | |
> seq_num | int | true | Incrementing sequence number, relevant to messages within the sequence_group/channel. |
> seq_group | int | true | Identifier for a channel group. Sequence numbers are only relevant paired with this identifier. |
Message Sequence Numbers
WebSocket messages contain sequence numbers to help clients identify if
they have missed any messages during temporary disconnections or network errors. The sequence number
is included in the WebSocket messages under the meta
field.
Message Structure with Sequence Numbers
WebSocket messages now include an additional meta
field that contains the following properties:
Member | Type | Description |
---|---|---|
seq_group | number | Unique identifier for the group of messages |
seq_num | number | Sequence number of the message within the group |
Here's an example of a WebSocket message with sequence numbers:
{
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "rfq",
"data": {
},
"meta": {
"seq_group": 1692463499,
"seq_num": 1027
}
}
}
Handling Sequence Numbers
Clients should monitor the sequence numbers of the incoming messages to ensure they have not missed any messages. If a client detects a gap in the sequence numbers, it may have missed one or more messages and should take appropriate action, such as refreshing data from REST.
Sequences increase monotonically within the context of a sequence group. Sequences are only relevant within a sequence group, which represents a subscribed channel. Sequences may be re-used between sequence groups.
While messages are sent ordered according to their sequences, sequences are not guaranteed not to repeat.
GRFQ - REST Endpoints
GRFQ: [GET] /instruments/
/instruments/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/instruments/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/v1/instruments/
method = 'GET'
path = '/v1/grfq/instruments/?asset=BTC&kind=FUTURE'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/instruments/ Response example
{
"count": 1341,
"next": "cD05NjE0Nw==",
"results": [
{
"expiration": 1680854400000,
"greeks": null,
"base_currency": "ETH",
"margin_kind": "INVERSE",
"kind": "FUTURE",
"mark_price": "1718.3",
"name": "ETH-7APR23",
"option_kind": null,
"product_code": "AZ",
"strike": null,
"venue": "DBT",
"venue_name": "ETH-7APR23"
},
{
"expiration": 1680854400000,
"greeks": null,
"base_currency": "BTC",
"margin_kind": "INVERSE",
"kind": "FUTURE",
"mark_price": "27144.7",
"name": "BTC-7APR23",
"option_kind": null,
"product_code": "CF",
"strike": null,
"venue": "DBT",
"venue_name": "BTC-7APR23"
},
{
"expiration": 1703836800000,
"greeks": {
"delta": "0.46821",
"gamma": "0.00043",
"mark_price": "0.1437",
"theta": "-0.67045",
"vega": "6.03833",
"last_updated_at": 1679945359701
},
"base_currency": "ETH",
"margin_kind": "INVERSE",
"kind": "OPTION",
"mark_price": "0.1437",
"name": "ETH-29DEC23-2100-C",
"option_kind": "CALL",
"product_code": "EH",
"strike": "2100",
"venue": "DBT",
"venue_name": "ETH-29DEC23-2100-C"
},
{
"expiration": 1703836800000,
"greeks": {
"delta": "-0.52159",
"gamma": "2e-05",
"mark_price": "0.3911",
"theta": "-11.79815",
"vega": "95.74543",
"last_updated_at": 1679945357964
},
"base_currency": "BTC",
"margin_kind": "INVERSE",
"kind": "OPTION",
"mark_price": "0.3911",
"name": "BTC-29DEC23-34000-P",
"option_kind": "PUT",
"product_code": "DO",
"strike": "34000",
"venue": "DBT",
"venue_name": "BTC-29DEC23-34000-P"
}
]
}
A [GET] /instruments/
request allows you to return all available Instruments upon Paradigm. Instruments are the legs part of an RFQ.
Instrument names match the naming conventions of the underlying venue.
You must paginate to return the complete results.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | Cursor value used to paginate through pages. |
asset | query | string | false | Base Currency of Instrument. Valid values include BTC , ETH , BCH , XRP , EOS . |
ordering | query | string | false | How returned Instruments are sorted. Valid values include creation , expiration , and default . |
page_size | query | string | false | Number of Instruments returned per pagination. |
kind | query | string | false | The type of Instrument. Valid values include FUTURE and OPTION . |
venue | query | string | false | The underlying venue the Instrument is cleared & settled upon. Valid values include DBT , BIT , BYB . |
name | query | [string] | false | Paradigm Name of Instruments. Example /v1/grfq/instruments/?name=BTC-PERPETUAL,ETH-PERPETUAL . |
include_greeks | query | boolean | false | Include greeks in the response. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
count | int | true | Total number of Instruments to paginate. |
next | string | true | Pagination cursor value. |
results | array of objects | true | |
> base_currency | string | true | The currency the Instrument is exposed to. Valid values include BCH , BTC , ETH . |
> margin_kind | string | true | The nature of how the contract is margined. Valid values include LINEAR , INVERSE . |
> option_kind | string | true | The kind of Option. null if instrument is not an Option. Valid values include CALL , PUT , null . |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> name | string | true | The Paradigm standardized name of the Instrument. |
> strike | string | true | Option Instrument Strike Price. null if kind == FUTURE . |
> kind | string | true | The type of Instrument. Valid values include FUTURE and OPTION . |
> venue | string | true | Underlying venue Instrument is cleared & settled upon. Valid values include DBT , BIT , BYB . |
> expiration | number | true | Instrument expiration timestamp in unix milliseconds since the epoch. null if Instrument does not have an expiration. |
> venue_name | string | true | The name of the Instrument per the underlying venue's naming conventions. |
> mark_price | string | true | The mark price of the Instrument. |
> greeks | object | false | The greeks of the Instrument. |
>> delta | string | true | The delta of the Instrument. |
>> gamma | string | true | The gamma of the Instrument. |
>> theta | string | true | The theta of the Instrument. |
>> vega | string | true | The vega of the Instrument. |
>> mark_price | string | true | The mark price of the Instrument. Deprecated: please use the top level mark_price |
>> last_updated_at | int | true | The timestamp in unix milliseconds since the epoch when the greek values were last updated. |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
GRFQ: [GET] /instruments/{venue}/{instrument_name}/
/instruments/{venue}/{instrument_name}/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/instruments/DBT/BTC-PERPETUAL/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/instruments/{venue}/{instrument_name}
method = 'GET'
path = '/v1/grfq/instruments/DBT/BTC-PERPETUAL/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/instruments/{venue}/{instrument_name}/ Response example
{
"expiration": 1703836800000,
"greeks": {
"delta": "-0.52159",
"gamma": "2e-05",
"mark_price": "0.3911",
"theta": "-11.79815",
"vega": "95.74543",
"last_updated_at": 1679945357964
},
"base_currency": "BTC",
"margin_kind": "INVERSE",
"kind": "OPTION",
"mark_price": "0.3911",
"name": "BTC-29DEC23-34000-P",
"option_kind": "PUT",
"product_code": "DO",
"strike": "34000",
"venue": "DBT",
"venue_name": "BTC-29DEC23-34000-P"
}
A [GET] /instruments/{venue}/{instrument_name}/
allows you to return information about a specific available Instrument.
Instruments are the legs part of an RFQ.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
venue | query | string | true | The underlying venue the Instrument is cleared & settled upon. Valid values include DBT , BIT , BYB . |
name | query | string | true | Paradigm Instrument Name. |
include_greeks | query | boolean | false | Include greeks in the response. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
count | int | true | Total number of Instruments to paginate. |
next | string | true | Pagination cursor value. |
results | array of objects | true | |
> base_currency | string | true | The currency the Instrument is exposed to. Valid values include BCH , BTC , ETH . |
> margin_kind | string | true | The nature of how the contract is margined. Valid values include LINEAR , INVERSE . |
> option_kind | string | true | The kind of Option. null if instrument is not an Option. Valid values include CALL , PUT , null . |
> product_code | string | true | The Paradigm created unique two-letter code to represent the specific Instrument. |
> name | string | true | The Instrument name per the underlying venue's naming convention. |
> strike | string | true | Option Instrument Strike Price. null if kind == FUTURE . |
> kind | string | true | The type of Instrument. Valid values include FUTURE and OPTION . |
> venue | string | true | Underlying venue Instrument is cleared & settled upon. Valid values include DBT , BIT , BYB . |
> expiration | number | true | Instrument expiration timestamp in unix milliseconds since the epoch. null if Instrument does not have an expiration. |
> venue_name | string | true | The name of the Instrument per the underlying venue's naming conventions. |
> mark_price | string | true | The mark price of the Instrument. |
> greeks | object | false | The greeks of the Instrument. |
>> delta | string | true | The delta of the Instrument. |
>> gamma | string | true | The gamma of the Instrument. |
>> theta | string | true | The theta of the Instrument. |
>> vega | string | true | The vega of the Instrument. |
>> mark_price | string | true | The mark price of the Instrument. Deprecated: please use the top level mark_price |
>> last_updated_at | int | true | The timestamp in unix milliseconds since the epoch when the greek values were last updated. |
Error Codes
HTTP Status Code | Message | Meaning |
---|---|---|
401 | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
GRFQ: [GET] /orders/
/orders/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/orders/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/orders/
method = 'GET'
path = '/v1/grfq/orders/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/orders/ Response example
{
"count":2,
"next":null,
"results":[
{
"client_order_id":"",
"rfq_id":551,
"id":379,
"filled_quantity":"0",
"filled_average_price":"0",
"limit_price":"0.1645",
"requested_quantity":"25",
"status":"CLOSED",
"side": "BUY",
"venue":"DBT"
},
{
"client_order_id":"",
"rfq_id":551,
"id":378,
"filled_quantity":"0",
"filled_average_price":"0",
"limit_price":"0.0642",
"requested_quantity":"25",
"satus":"CLOSED",
"side": "BUY",
"venue":"DBT"
}
]
}
A [GET] /orders/
request will return all the requesting user's and trading desks' Orders.
Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.
You must paginate to return the complete series of results.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The pagination cursor value. |
page_size | query | string | false | Number of orders to return per page. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
count | int | true | The total number of Orders available from request. |
next | string | true | The next pagination cursor. This value is null if there are no more pages. |
results | array of objects | true | |
> client_order_id | string | true | A unique user created identifier for the Order. |
> rfq_id | int | true | The Paradigm created unique identifier of the parent RFQ. |
> id | int | true | The Paradigm created unique identifier of the Order. |
> filled_quantity | string | true | The amount of the Order cleared & settled in the contract units of the RFQ. |
> filled_average_price | string | true | The average price of the filled quantity in the Quote Currency of the RFQ. |
> limit_price | string | true | The price of the submitted Order in the Quote Currency of the RFQ. |
> requested_quantity | string | true | The size of the Order in contract units of the RFQ. |
> side | string | true | The direction the Order executed upon the RFQ. Valid values include BUY and SELL . |
> status | string | true | The current status of the Order. Valid values include CLOSED . |
> venue | string | true | Underlying venue RFQ is cleared & settled upon. Valid values include DBT , BIT , BYB . |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
GRFQ: [GET] /orders/{order_id}/
/orders/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/orders/62/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/orders/{order_id}/
method = 'GET'
path = '/v1/grfq/orders/62/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/orders/ Response example
{
"client_order_id":"",
"rfq_id":589,
"id":432,
"filled_quantity":"0",
"filled_average_price":"0",
"limit_price":"2498",
"requested_quantity":"50000000000",
"side":"SELL",
"status":"CLOSED",
"venue":"DBT",
"trades":[
{
"product_code":"CF",
"quantity":"50000000000",
"price":"2498",
"id":479,
"mark_price":"2498.93",
"traded":1625193887212.47,
"action":"SELL",
"quote_currency":"USD",
"quote_id":152838,
"api_credential":"ParadigmTestNinetyFive"
}
]
}
A [GET] /orders/{order_id}/
request will one of the requesting user's and trading desks' Orders.
Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | endpoint | string | true | The Paradigm created unique identifier of the Order. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
client_order_id | string | true | A unique user created identifier for the trade Order. |
rfq_id | int | true | The Paradigm created unique identifier of the parent RFQ. |
id | int | true | The Paradigm created unique identifier of the Order. |
filled_quantity | string | true | The amount of the Order filled in the contract units of the RFQ. |
filled_average_price | string | true | The average price of the filled quantity in the Quote Currency of the RFQ. |
limit_price | string | true | The price of the submitted Order in the Quote Currency of the RFQ. |
requested_quantity | string | true | The size of the Order in contract units of the RFQ. |
side | string | true | The execution side of the Order on the RFQ. Valid values include BUY and SELL . |
status | string | true | The current status of the Order. Valid values include CLOSED . |
venue | string | true | Underlying venue Instrument is cleared & settled upon. Valid values include DBT , BIT , BYB . |
trades | array of objects | true | |
> product_codes | array of strings | true | The Paradigm Product Codes of the Trade. |
> quantity | string | true | The amount of contracts of the RFQ traded. |
> price | string | true | The price in the Quote Currency of the RFQ of the Trade. |
> id | int | true | The Paradigm created unique identifier of the Trade. |
> mark_price | string | true | The calculated mark price of the RFQ using the Venue's mark prices. |
> traded | number | true | The time in unix milliseconds since the epoch when the trade was cleared & settled. |
> action | string | true | The action taken on the Trade. valid values include BUY and SELL . |
> quote_currency | string | true | The asset which is the Quote Currency of the RFQ. |
> quote_id | int | true | The Paradigm created unique identifier of the Quote. |
> api_credential | string | true | The name given the to the Exchange API Key entered on the Paradigm Client Admin dashboard. |
> status | string | true | The status of the Trade. Valid values include PENDING , COMPLETED , REJECTED . |
Error Codes
HTTP Status Code | Message | Meaning |
---|---|---|
401 | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
GRFQ: [GET] /quotes/
/quotes/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/quotes/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/quotes/
method = 'GET'
path = '/v1/grfq/quotes/?page_size=10&side=BUY'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/quotes/ Response example
{
"count":5755,
"next":"cD0yMDIxLTA3LTI2KzA2JTNBMjMlM0ExOC4xMTc1NDMlMkIwMCUzQTAw",
"results":[
{
"id":2775578,
"created":1631587522444.227,
"maker":"DSK95",
"price":"0.08",
"remaining_quantity":"0",
"side":"SELL",
"status":"CLOSED",
"client_order_id":"",
"original_quantity":"25",
"rfq_id":2073
},
{
"id":2775577,
"created":1631587522410.562,
"maker":"DSK95",
"price":"0.0795",
"remaining_quantity":"0",
"side":"BUY",
"status":"CLOSED",
"client_order_id":"",
"original_quantity":"25",
"rfq_id":2073
},
{
"id":2775572,
"created":1631587470993.799,
"maker":"DSK95",
"price":"0.09",
"remaining_quantity":"24",
"side":"BUY",
"status":"CLOSED",
"client_order_id":"",
"order":{
"id":266218,
"client_order_id":"",
"filled_quantity":"26",
"filled_average_price":"0.0879",
"limit_price":"0.09",
"requested_quantity":"50",
"rfq_id":2073,
"side":"BUY",
"status":"CLOSED",
"venue":"DBT"
},
"original_quantity":"24",
"rfq_id":2073
},
{
"id":2775564,
"created":1631587437845.888,
"maker":"DSK95",
"price":"0.0879",
"remaining_quantity":"50",
"side":"SELL",
"status":"CLOSED",
"client_order_id":"",
"original_quantity":"50",
"rfq_id":2073
}
]
}
A [GET] /quotes/
request will return all the requesting user's and trading desks' Quotes.
Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.
You must paginate to return the complete series of results.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | The pagination cursor value. |
page_size | query | string | false | Number of Quotes to return per page. |
rfq_id | query | string | false | The Paradigm created unique identifier of the RFQ. |
side | query | string | false | The direction of the Quotes. Valid values include BUY and SELL . |
status | query | string | false | The status of the Quotes. Valid values include OPEN and CLOSED . |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
count | int | true | The total number of Quotes available to paginate over. |
next | string | true | The next pagination cursor. This value is null if there are no more pages. |
results | array of objects | true | |
> created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
> last_activity | number | true | The time in unix milliseconds since the epoch when the Quote was updated. |
> id | int | true | The Paradigm created unique identifier of the Quote. |
> maker | string | true | The Paradigm desk name of the Maker. |
> price | string | true | The price of the Quote in the Quote Currency of the Strategy. |
> remaining_quantity | string | true | The total remaining Quote size in contract units of the RFQ. |
> side | string | true | The direction of the Quote. Valid values include BUY and SELL . |
> type | string | true | The Quote OrderType. Valid values include LIMIT . |
> description | string | true | The RFQ strategy description. |
> product_codes | array of strings | true | The RFQ product codes. |
> status | string | true | The status of the Quote. Valid values include OPEN and CLOSED . |
> client_order_id | string | true | A unique user created identifier for the Quote. |
> order | object | false | Present if Quote crosses the existing market. |
>> id | int | false | The Paradigm created unique identifier of the Order. |
>> client_order_id | string | false | A unique user created identifier for the Order. |
>> filled_quantity | string | false | The filled quantity of the Order in the contract units of the RFQ. |
>> filled_average_price | string | false | The average filled price of the Order in the quote currency of the RFQ. |
>> limit_price | string | false | The price of the Order in quote currency of the RFQ. |
>> requested_quantity | string | false | The requested crossing quantity of the Order. |
>> rfq_id | int | false | The Paradigm created unique identifier of the RFQ the Order is a child of. |
>> side | string | false | The direction of the Order. Valid values include BUY and SELL . |
>> status | string | false | The current status of the Order. Valid values include OPEN and CLOSED . |
>> venue | string | false | Underlying venue RFQ is cleared & settled upon. Valid values include DBT , BIT , BYB . |
> rfq_id | int | true | The Paradigm created unique identifier of the RFQ the Quote is a child of. |
> original_quantity | string | true | The original Quote size in contract units of the RFQ. |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
GRFQ: [GET] /quotes/{quote_id}/
/quotes/{quote_id}/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/quotes/482199/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/quotes/{quote_id}/
method = 'GET'
path = '/v1/grfq/quotes/152780/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/quotes/{quote_id}/ Response example
{
"id":2775572,
"created":1631587470993.799,
"maker":"DSK95",
"price":"0.09",
"remaining_quantity":"24",
"side":"BUY",
"status":"CLOSED",
"client_order_id":"",
"order":{
"id":266218,
"client_order_id":"",
"filled_quantity":"26",
"filled_average_price":"0.0879",
"limit_price":"0.09",
"requested_quantity":"50",
"rfq_id":2073,
"side":"BUY",
"status":"CLOSED",
"venue":"DBT"
},
"original_quantity":"24",
"rfq_id":2073,
"canceled":1631587471003.939
}
A [GET] /quotes/{quote_id}/
request will return the requesting user's and trading desks' specified Quote.
Orders are Taker interactions with the Quote Book. Quotes can be Taker & Maker interactions with the Quote Book.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | endpoint | string | true | The Paradigm created unique Quote identifier. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
id | int | true | The Paradigm created unique identifier of the Quote. |
maker | string | true | The Paradigm desk name of the Maker who created the Quote. |
price | string | true | Price of the Quote in the Quote currency of the RFQ. |
remaining_quantity | string | true | The total remaining size of the Quote in contract units of the RFQ. |
side | string | true | The direction of the Quote. Valid values include BUY and SELL . |
status | string | true | The status of the quote. Valid values include OPEN and CLOSED . |
client_order_id | string | true | A unique user created identifier for the Quote. |
order | object | false | Present if Quote crosses the existing market. |
> id | int | false | The Paradigm created unique identifier of the Order. |
> client_order_id | string | false | A unique user created identifier for the Order. |
> filled_quantity | string | false | The filled quantity of the Order in the contract units of the RFQ. |
> filled_average_price | string | false | The average filled price of the Order in the quote currency of the RFQ. |
> limit_price | string | false | The price of the Order in quote currency of the RFQ. |
> requested_quantity | string | false | The requested crossing quantity of the Order. |
> rfq_id | int | false | The Paradigm created unique identifier of the RFQ the Order is a child of. |
> side | string | false | The direction of the Order. Valid values include BUY and SELL . |
> status | string | false | The current status of the Order. Valid values include OPEN and CLOSED . |
> venue | string | false | Underlying venue RFQ is cleared & settled upon. Valid values include DBT , BIT , BYB . |
rfq_id | int | true | The Paradigm created unique identifier of the RFQ the Quote is a child of. |
original_quantity | string | true | The original size of the Quote in contract units of the RFQ. |
canceled | number | true | The time in unix milliseconds since the epoch when the Quote was canceled. null if Quote has not been canceled. |
Error Codes
HTTP Status Code | Message | Meaning |
---|---|---|
401 | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
GRFQ: [DELETE] /quotes/
/quotes/ Request example
# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v1/grfq/quotes/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# DELETE /v1/grfq/quotes/
method = 'DELETE'
path = '/v1/grfq/quotes/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.delete(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/quotes/ Response example
{
"successes":{
"count":2,
"details":[
152799,
152798
]
},
"failures":{
"count":0,
"details":[
]
}
}
A [DELETE] /quotes/
request cancels all active Quotes.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
rfq_id | query | string | false | The Paradigm created unique identifier of the RFQ. |
side | query | string | false | Cancel all Quotes by side. Valid values include BUY and SELL . Cancels all Quotes regardless of side if not specified. |
price | query | decimal | false | Cancel all Quotes matching the given price. |
Response Schema
Status Code 200
In the case of a failure to cancel any quote, the request will return an HTTP Status Code of 207
Quotes that are being processed (previously cancelled, under execution) at the time of request may be returned as failures
Name | Type | Required | Description |
---|---|---|---|
successes | array of objects | true | Information about successful Quote cancellations. |
> count | int | true | The number of OPEN Quotes that have now been canceled. |
> details | array of objects | true | |
>> id | int | true | The Paradigm created unique identifier of the Quote. |
>> created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
>> price | string | true | The price in the Quote Currency of the RFQ of the Quote. |
>> remaining_quantity | string | true | The remaining quantity of the Quote in the contract units of the Quote. |
>> side | string | true | The direction of the Quote. Valid values include BUY and SELL . |
>> status | string | true | The status of the Quote. Valid values include CLOSED . |
failures | array of objects | true | Information about unsuccessful Quote cancellations. |
> count | int | true | The number of OPEN Quotes that have failed to be canceled. |
> details | array of objects | true | |
>> id | int | true | The Paradigm created unique identifier of the Quote. |
>> created | number | true | The time in unix milliseconds since the epoch when the Quote was created. |
>> price | string | true | The price in the Quote Currency of the RFQ of the Quote. |
>> remaining_quantity | string | true | The remaining quantity of the Quote in the contract units of the Quote. |
>> side | string | true | The direction of the Quote. Valid values include BUY and SELL . |
>> status | string | true | The status of the Quote. Valid values include OPEN . |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
400 | 3305 | "Invalid RFQ ID" | Unavailable/Invalid RFQ Id requested. |
400 | 3301 | "Invalid quote side. Must either be BUY or SELL." | Requested side query string value must be BUY or SELL . |
GRFQ: [DELETE] /quotes/{quote_id}/
/quotes/{quote_id}/ Request example
# You can also use wget
curl -X DELETE https://api.testnet.paradigm.trade/v1/grfq/quotes/15/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# DELETE /v1/grfq/quotes/{quote_id}/
method = 'DELETE'
path = '/v1/grfq/quotes/152797/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
response = requests.delete(host+path,
headers=headers)
print(response.status_code)
print(response.text)
A [DELETE] /quotes/{quote_id}/
request cancels an existing OPEN
Quote created by the requesting user or user's trading desk.
You cannot cancel multiple Quotes with a single request using this endpoint.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | endpoint | string | true | The Paradigm unique identifier of the Quote the user would like to cancel. |
Response Schema
This request will return an HTTP Status Code of 204 to indicate success of operation.
Status Code 204
Schema below is solely for if the request resulted in a failed operation.
Name | Type | Required | Description |
---|---|---|---|
code | int | true | Error Code. |
message | string | true | The reason the request was unsuccessful. |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
400 | 3306 | "Too late to cancel." | The requested quote_id is already CLOSED or unavailable to cancel. |
400 | 3308 | "Unavailable quote | You are not the desk who created the Quote. |
GRFQ: [GET] /rfqs/
/rfqs/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/rfqs/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/rfqs/
method = 'GET'
path = '/v1/grfq/rfqs/?rfq_id=57'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/rfqs/ Response example
{
"count":13,
"next":null,
"results":[
{
"id":586,
"venue":"DBT",
"created":1625183214149.205,
"description":"Put 9 Jul 21 32000",
"last_trade":null,
"latest_activity":1625183931073.739,
"legs":[
{
"instrument":"BTC-9JUL21-32000-P",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code": "PT"
},
{
"id":585,
"venue":"DBT",
"created":1625182846124.338,
"description":"PFly 3 Jul 21 32000/33000/34000",
"last_trade":null,
"latest_activity":1625183645052.5972,
"legs":[
{
"instrument":"BTC-3JUL21-32000-P",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"BTC-3JUL21-33000-P",
"product_code":"DO",
"ratio":"2",
"side":"SELL"
},
{
"instrument":"BTC-3JUL21-34000-P",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"IY"
},
{
"id":583,
"venue":"DBT",
"created":1625181172208.664,
"description":"Call 3 Jul 21 32000",
"last_trade":null,
"latest_activity":1625182827211.0642,
"legs":[
{
"instrument":"BTC-3JUL21-32000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"CL"
},
{
"id":584,
"venue":"DBT",
"created":1625182630789.73,
"description":"Call 16 Jul 21 34000",
"last_trade":null,
"latest_activity":1625182651464.818,
"legs":[
{
"instrument":"BTC-16JUL21-34000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"CL"
},
{
"id":573,
"venue":"DBT",
"created":1625159972983.593,
"description":"Put 16 Jul 21 34000",
"last_trade":null,
"latest_activity":1625182626036.611,
"legs":[
{
"instrument":"BTC-16JUL21-34000-P",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"PT"
},
{
"id":576,
"venue":"DBT",
"created":1625163614843.893,
"description":"CFly 3 Jul 21 31000/32000/33000",
"last_trade":null,
"latest_activity":1625180836165.132,
"legs":[
{
"instrument":"BTC-3JUL21-31000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"BTC-3JUL21-32000-C",
"product_code":"DO",
"ratio":"2",
"side":"SELL"
},
{
"instrument":"BTC-3JUL21-33000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"IB"
},
{
"id":581,
"venue":"BIT",
"created":1625174242789.779,
"description":"Straddle 3 Jul 21 1900",
"last_trade":null,
"latest_activity":1625180726439.838,
"legs":[
{
"instrument":"ETH-3JUL21-1900-P",
"product_code":"VT",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"ETH-3JUL21-1900-C",
"product_code":"VT",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"VT"
],
"status":"ACTIVE",
"strategy_code":"ID"
},
{
"id":582,
"venue":"DBT",
"created":1625178072216.012,
"description":"Cstm +1 Call 3 Jul 21 32000\n -2 Put 3 Jul 21 33000\n +2 Call 9 Jul 21 34000\n -1 Put 9 Jul 21 35000",
"last_trade":null,
"latest_activity":1625178072216.1091,
"legs":[
{
"instrument":"BTC-3JUL21-32000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"BTC-3JUL21-33000-P",
"product_code":"DO",
"ratio":"2",
"side":"SELL"
},
{
"instrument":"BTC-9JUL21-34000-C",
"product_code":"DO",
"ratio":"2",
"side":"BUY"
},
{
"instrument":"BTC-9JUL21-35000-P",
"product_code":"DO",
"ratio":"1",
"side":"SELL"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"CM"
},
{
"id":575,
"venue":"DBT",
"created":1625160866037.8489,
"description":"Call 9 Jul 21 32000",
"last_trade":null,
"latest_activity":1625173436428.965,
"legs":[
{
"instrument":"BTC-9JUL21-32000-C",
"product_code":"DO",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"DO"
],
"status":"ACTIVE",
"strategy_code":"CL"
},
{
"id":578,
"venue":"DBT",
"created":1625167876394.6099,
"description":"Future 16 Jul 21",
"last_trade":null,
"latest_activity":1625172957461.732,
"legs":[
{
"instrument":"BTC-16JUL21",
"product_code":"CF",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"status":"ACTIVE",
"strategy_code":"FT"
},
{
"id":580,
"venue":"DBT",
"created":1625172668390.126,
"description":"FSpd 25 Mar 22 / 24 Jun 22",
"last_trade":null,
"latest_activity":1625172668390.178,
"legs":[
{
"instrument":"BTC-25MAR22",
"product_code":"CF",
"ratio":"1",
"side":"SELL"
},
{
"instrument":"BTC-24JUN22",
"product_code":"CF",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"status":"ACTIVE",
"strategy_code":"FS"
},
{
"id":579,
"venue":"DBT",
"created":1625172652154.217,
"description":"FSpd Perpetual / 24 Jun 22",
"last_trade":null,
"latest_activity":1625172652154.271,
"legs":[
{
"instrument":"BTC-PERPETUAL",
"product_code":"CF",
"ratio":"1",
"side":"SELL"
},
{
"instrument":"BTC-24JUN22",
"product_code":"CF",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"CF"
],
"status":"ACTIVE",
"strategy_code":"FS"
},
{
"id":577,
"venue":"BYB",
"created":1625164847566.429,
"description":"FSpd 24 Sep 21 / 31 Dec 21",
"last_trade":null,
"latest_activity":1625164847566.4849,
"legs":[
{
"instrument":"BTCUSDU21",
"product_code":"BB",
"ratio":"1",
"side":"SELL"
},
{
"instrument":"BTCUSDZ21",
"product_code":"BB",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"BB"
],
"status":"ACTIVE",
"strategy_code":"FS"
}
]
}
A [GET] /rfqs/
request returns information about ACTIVE
RFQs.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
cursor | query | string | false | Cursor value, from the next key in the response, used to paginate through pages. |
page_size | query | string | false | Number of RFQs to return per pagination. |
product_codes | query | string | false | Paradigm Product Codes involved in RFQ. There can be multiple product codes. Example: /v1/grfq/rfqs/?product_codes=DO,CF |
rfq_id | query | string | false | Paradigm created unique identifier for the RFQ. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
count | int | true | Total number of RFQs to paginate through from request. |
next | string | true | Pagination cursor value. null if no more pages are available. |
results | array of objects | true | |
> id | int | true | The Paradigm created unique identifier of the RFQ. |
> venue | string | true | The underlying venue the instruments are cleared & settled upon. Valid values include DBT , BIT , BYB . |
> created | number | true | Time in unix milliseconds since the epoch when the RFQ was created. |
> description | string | true | The description of the RFQ. |
> last_trade | object | true | null if RFQ has never been Traded. |
>> traded | number | false | Time in unix milliseconds since the epoch when the the Trade occurred. |
>> quantity | string | false | The size of the trade in the contract units of the RFQ. |
>> price | string | false | The price the RFQ was Traded at in the Quote Currency of the RFQ. |
> latest_activity | number | true | Time in unix milliseconds since the epoch when the RFQ, it’s quotes and trades were last updated. |
> legs | array of objects | true | |
>> instrument | string | true | The Paradigm standardized name of the Instrument. |
>> venue_instrument | string | true | Instrument name per the underlying venue's naming convention. |
>> product_code | string | true | Paradigm Product Code of the Instrument. |
>> ratio | string | true | The multiplier applied to the quantity that the quote applies. |
>> side | string | true | The direction of the leg. Valid values include BUY and SELL . |
> price | string | false | Price of Instrument if the Instrument is a hedge leg in RFQ. |
> product_codes | array of strings | true | Paradigm Product Codes involved in the GRFQ. |
> status | string | true | Status of the RFQ. Valid values include ACTIVE . |
> strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
404 | N/A | "Invalid cursor" | Use the string value from the next key in the first response to paginate. |
GRFQ: [GET] /rfqs/{rfq_id}/
/rfqs/{rfq_id}/ Request example
# You can also use wget
curl -X GET https://api.testnet.paradigm.trade/v1/grfq/rfqs/20/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-key>'
# built ins
import base64
import hmac
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# GET /v1/grfq/rfqs/{rfq_id}/
method = 'GET'
path = '/v1/grfq/rfqs/581/'
payload = ''
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.get(host+path,
headers=headers)
print(response.status_code)
print(response.text)
/rfqs/{rfq_id}/ Response example
{
"id":581,
"venue":"BIT",
"created":1625174242789.779,
"description":"Straddle 3 Jul 21 1900",
"last_trade":null,
"latest_activity":1625180726439.838,
"legs":[
{
"instrument":"ETH-3JUL21-1900-P",
"product_code":"VT",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"ETH-3JUL21-1900-C",
"product_code":"VT",
"ratio":"1",
"side":"BUY"
}
],
"product_codes":[
"VT"
],
"status":"ACTIVE"
}
A [GET] /rfqs/{rfq_id}/
request returns information about a specific RFQ.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
id | endpoint | string | true | The Paradigm created unique identifier of the RFQ. |
Response Schema
Status Code 200
Name | Type | Required | Description |
---|---|---|---|
id | int | true | The Paradigm created unique identifier of the RFQ. |
venue | string | true | The underlying venue the instruments are cleared & settled upon. Valid values include DBT , BIT , BYB . |
created | number | true | Time in unix milliseconds since the epoch when the RFQ was created. |
description | string | true | The description of the RFQ. |
last_trade | object | true | null if the RFQ has never been Traded. |
> traded | number | false | Time in unix milliseconds since the epoch when the the Trade occurred. |
> quantity | string | false | The size of the trade in the contract units of the RFQ. |
> price | string | false | The price the RFQ was Traded at. |
latest_activity | number | true | Time in unix milliseconds since the epoch when the RFQ, it’s quotes and trades were last updated. |
legs | array of objects | true | |
> instrument | string | true | The Paradigm standardized name of the Instrument. |
> venue_instrument | string | true | Instrument name per the underlying venue's naming conventions. |
> price | string | false | Price of Instrument if the Instrument is a hedge leg in RFQ. |
> product_code | string | true | Paradigm Product Code of the Instrument. |
> ratio | string | true | The multiplier applied to the quantity that the quote applies. |
> side | string | true | The direction of the leg. Valid values include BUY and SELL . |
product_codes | array of strings | true | Paradigm Product Codes involved in the RFQ. |
status | string | true | Status of the RFQ. Valid values include ACTIVE and EXPIRED . |
> strategy_code | string | true | Strategy code of the RFQ. Valid values include CL , CB , CC , CR , CS , CM , FT , FS , PT , PB , PC , PR , PS , SD , SG , IC , IP , IB , IY , ID , IG , IS . |
Error Codes
HTTP Status Code | Code | Message | Meaning |
---|---|---|---|
401 | N/A | "Authentication credentials provided were not provided." | You did not provide authentication credentials. |
400 | 3300 | "Unavailable RFQ" | Unavailable/invalid RFQ Id provided in request. |
GRFQ: [POST] /rfqs/
/rfqs/ Request example
# built ins
import base64
import hmac
import json
import time
# installed
import requests
access_key = '<access-key>'
secret_key = b'<secret-key>'
def sign_request(secret_key, method, path, body):
signing_key = base64.b64decode(secret_key)
timestamp = str(int(time.time() * 1000)).encode('utf-8')
message = b'\n'.join([timestamp, method.upper(), path, body])
digest = hmac.digest(signing_key, message, 'sha256')
signature = base64.b64encode(digest)
return timestamp, signature
# Request Host
host = 'https://api.testnet.paradigm.trade'
# POST /v1/grfq/rfqs/
method = 'POST'
path = '/v1/grfq/rfqs/'
payload = {
"venue":"DBT",
"legs":[
{
"instrument":"BTC-PERPETUAL",
"ratio":1,
"side":"BUY"
},
{
"instrument":"BTC-31DEC21",
"ratio":1,
"side":"SELL"
}
]
}
json_payload = json.dumps(payload)
timestamp, signature = sign_request(secret_key=secret_key,
method=method.encode('utf-8'),
path=path.encode('utf-8'),
body=json_payload.encode('utf-8'),
)
headers = {
'Paradigm-API-Timestamp': timestamp,
'Paradigm-API-Signature': signature,
'Authorization': f'Bearer {access_key}'
}
# Send request
response = requests.post(host+path,
headers=headers,
json=payload)
print(response.status_code)
print(response.text)
/rfqs/ Response example
{
"id":588,
"venue":"DBT",
"created":1625187733890.315,
"description":"Cstm +1 Future Perpetual\n -1 Future 31 Dec 21",
"last_trade":null,
"latest_activity":1625187733890.388,
"legs":[
{
"instrument":"BTC-PERPETUAL",
"product_code":"CF",
"ratio":"1",
"side":"BUY"
},
{
"instrument":"BTC-31DEC21",
"product_code":"CF",
"ratio":"1",
"side":"SELL"
}
],
"product_codes":[
"CF"
],
"status":"ACTIVE",
"strategy_code":"CM"
}
A [POST] /rfqs/
request allows a user to create a new RFQ and/or return the RFQ's information if one already exists.
The response schema and response is the same if the requester creates a new RFQ or an RFQ already exists.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
venue | body | string | true | The underlying venue the Instruments in the RFQ are cleared & settled upon. Valid values include DBT , BIT , BYB . |
legs | body | array of objects | true | The individual legs of the RFQ. |
> instrument | body | string | true | The name of the Instrument per Paradigm's naming convention. |
> price | body | string | false | The price of the leg in the Quote Currency of the Instrument if the leg is a hedge leg. |
> ratio | body | s |