Group And Resources
Bybit API and WebSocket documentation provides guidance to help you access Bybit's endpoints, their expected outputs, and common errors.
For further assistance or feedback, please join the API Telegram chat! API discussion group on Telegram.
Group And Bybit API Resources
Help Center - Learn more about exchange mechanisms here!
pybit - Official Python SDK
QuickStartWithPostman - Postman API Collection
API Discussion Group - get English help here!
API Discussion Group (Chinese) - get Chinese help here!
Bybit API Announcement - subscribe for changes to the API!
Bybit Open API Survey - The survey should take no more than 5 minutes to complete.
Changelog
2022-08-08
REST API
- Transfer [update]
Transfer endpoint supports transfer from/toUNIFIED
, and new error codes.
2022-06-01
REST API
- Symbol List [update]
- Order List [update]
- Create Order [update]
- Close Order [update]
- Cancel Order [update]
- Position List [update]
- Close Position [update]
- Get Wallet Balance [update]
- Transfer [update]
- Set Leverage [update]
URLs of the above copytrading endpoints are updated.
2022-05-31
REST API
- Symbol List [new]
- Order List [new]
- Create Order [new]
- Close Order [new]
- Cancel Order [new]
- Position List [new]
- Close Position [new]
- Get Wallet Balance [new]
- Transfer [new]
- Set Leverage [new]
WebSocket API
FAQ
reduce_only
and close_on_trigger
- what's the difference?
- To close your position, submit an order and specify
reduce_only
totrue
.close_on_trigger
is not strictly applicable here, but you can also set it totrue
if it's required. reduce_only
is the one that really matters for closing position, and we will improve the interface in the future.- Be careful when you specify
close_on_trigger
totrue
as it could cause conflict whenreduce_only
isfalse
.
Why aren't all my orders showing on the website?
- Users who have bots which place large numbers of laddered orders will be restricted by the frontend interface, which only shows a maximum of 50 orders on-screen.
- Don't worry, your orders are still in the system and can be queried by the API, but the frontend cannot show more than 50.
Calculating order size based on available wallet balance
price * available_balance * leverage * perc * (1 - (0.0006 * 2))
- Unfortunately this is not a perfectly accurate formula; the real calculation is complex and may be published in the docs at a later date.
price
- last price (or your entry price) - can be found with the Latest Symbol Info endpoint.available_balance
- can be found with the My Position endpoint.leverage
- up to the respective maximum leverage for the market and your risk limit (eg 2, 10, 50).perc
- 0.1 for 10%, 0.25 for 25%, etc.1 - (0.0006 * 2)
- used to calculate the maximum order cost (always assumes entry & exit orders use taker fee regardless actual fee).
Can I exchange assets with the API?
- There is no endpoint to exchange assets. This can only be done on the website.
- However, it is possible to access your Asset Exchange Records with the API.
Where are Bybit's servers located?
AWS Singapore, Availability Zone ID apse1-az3.
How do I get funds for testnet?
To get testnet funds, please contact the website's customer support using the yellow support button shown in the bottom-right corner.
Why are my Closed PNL prices inaccurate?
- The
entry_price
andexit_price
returned by Closed PNL endpoints are not the actual execution prices of the orders. - It is based on the total costs of the order
- (whether or not the position was only opened/closed by one order executed at one price - it is more complicated if multiple orders opened/closed a position.)
- For instance, the
entry_price
andexit_price
reported by this endpoint are influenced by the fee paid/received on the orders.
Why are values returned to too many decimal places? (float precision issue)
- For example, you received
11.969999
but you expected11.97
. - Some values are returned to too many decimal places, or a fraction too high or low, due to a float precision problem.
- For now, we recommend rounding the received value to the correct decimal place. This can be done with reference to the Query Symbol endpoint.
- This issue will be fixed in the next major version of the API; unfortunately, it is not fixable in the short-term.
How can I ensure I am using up-to-date data?
- It is possible, although unlikely, that the REST API or (even less likely) the websocket could return/push old data.
- For the greatest level of data resilience, we recommend clients to:
- firstly, rely on the websocket, which will not only ensure you get the latest data as fast as possible, but will also ensure you get complete data
- secondly, query the REST API to fill in any discrepencies in data - or between websocket disconnections.
- The best practice is to save all of this data locally in your own database or cache.
- This frees up your rate limits for other requests and also ensures a level of redundancy against the exchange in case of data delays.
What is the difference between turnover and volume?
- Turnover: is in the opposite currency to the quantity's currency
- Volume: is in the same currency as the quantity's currency
Authentication
All requests made to private endpoints must be authenticated. Requests made to public endpoints do not require additional authentication.
Parameters for Authenticated Endpoints
The following parameters must be used for authentication:
- api_key
- timestamp - UTC timestamp in milliseconds
- sign - a signature derived from the request's parameters
We also provide recv_window
(unit in millisecond and default value is 5,000) to specify how long an HTTP request is valid. It is also used to prevent replay attacks.
A smaller recv_window
is more secure, but your request may fail if the transmission time is greater than your recv_window
.
Please make sure that your timestamp
is in sync with our server time. You can use the Server Time endpoint.
Create A Request
1.The parameters are in json format
2. Use the HMAC_SHA256 algorithm to sign the query string in step 1, and convert it to a hex string to obtain the sign parameter.
An example how to place an order:
import requests
import json
import time
import hashlib
import hmac
api_key='API-KEY'
secret_key='SECRET-KEY'
time_stamp=str(int(time.time() * 10 ** 3))
recv_window=str(5000)
url = "https://api-testnet.bybit.com/derivatives/v3/copytrading/order/create"
payload = json.dumps({"side":"Sell","symbol":"BTCUSDT","order_type":"Market","qty":"0.01","price":"1"})
param_str= str(time_stamp) + api_key + recv_window + payload
hash = hmac.new(bytes(secret_key, "utf-8"), param_str.encode("utf-8"),hashlib.sha256)
signature = hash.hexdigest()
headers = {
'X-BAPI-API-KEY': api_key,
'X-BAPI-SIGN': signature,
'X-BAPI-SIGN-TYPE': '2',
'X-BAPI-TIMESTAMP': time_stamp,
'X-BAPI-RECV-WINDOW': recv_window,
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
Market Data Endpoints
The following market data endpoints do not require authentication.
Symbol List
Request Example
curl https://api-testnet.bybit.com/contract/v3/public/copytrading/symbol/list
from pybit import HTTP
session = HTTP("https://api-testnet.bybit.com")
print(session.symbol_list())
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"list": [
{
"symbol": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"priceScale": "1",
"takerFee": "0.00075",
"makerFee": "-0.00025",
"fundingInterval": "480",
"leverageFilter": {
"maxLeverage": "100",
"minLeverage": "1"
},
"priceFilter": {
"minPrice": "0.5",
"maxPrice": "999999.0",
"tickSize": "0.5"
},
"lotSizeFilter": {
"qtyStep": "0.001",
"maxOrderQty": "100.000",
"minOrderQty": "0.001"
}
}
]
}
}
Symbol List
HTTP Request
GET
/contract/v3/public/copytrading/symbol/list
Request Parameters
parameter | Required | Type | Comment |
---|
Response Parameters
Parameter | Type | Comment |
---|---|---|
symbol | string | Symbol |
baseCurrency | string | Base currency |
quoteCurrency | string | Quote currency |
priceScale | string | Price scale (the number of decimal places to which a price can be submitted, although the final price may be rounded to conform to the tick_size ) |
takerFee | string | Taker fee |
makerFee | string | Maker fee |
fundingInterval | string | Funding fee interval |
leverageFilter | object[] | |
maxLeverage | string | Max leverage (indicates the max leverage, assuming the lowest risk limit setting) |
minLeverage | string | Min leverage |
priceFilter | object[] | |
minPrice | string | Min price |
maxPrice | string | Max price |
tickSize | string | Tick size |
lotSizeFilter | object[] | |
qtyStep | string | Qty step |
maxOrderQty | string | Max trading quantity |
minOrderQty | string | Min trading quantity |
Account Data Endpoints
The following account data endpoints require authentication.
Order
Create Order
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/order/create \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","side":"Buy","symbol":"BTCUSDT","orderType":"Market","qty":"10","timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"orderId": "419190fe-016c-469a-810e-936bef2f5d59",
"orderLinkId": "234590fe-016c-44f6-fg78"
}
}
Create Order
HTTP Request
POST
/contract/v3/private/copytrading/order/create
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
side | true | string | Side |
symbol | true | string | Symbol |
orderType | true | string | Active order type |
qty | true | string | Order quantity in USD |
price | true | string | Order price |
orderLinkId | false | string | Unique user-set order ID. Maximum length of 36 characters |
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | Order ID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
Order List
Request Example
curl "https://api-testnet.bybit.com/contract/v3/private/copytrading/order/list?api_key={api_key}×tamp={timestamp}&sign={sign}&symbol=ETHUSDT"
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"list": [
{
"orderId": "ae0700f6-c990-4de5-9d6e-0fdf8d5aabea",
"symbol": "ETHUSDT",
"orderLinkId": "234500f6-c45f-4de5-9d6e",
"side": "Sell",
"copyTradeOrderStatus": "New",
"price": "4000.00",
"qty": "5.55",
"timeInForce": "GoodTillCancel",
"leavesQty": "5.55",
"isIsolated": true,
"leavesValue": "22200",
"leverage": "44",
"cumExecValue": "0",
"cumExecFee": "0",
"createdTime": "1652216213331",
"updatedTime": "1652216213365"
}
]
}
}
Order List
HTTP Request
GET
/contract/v3/private/copytrading/order/list
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
symbol | false | string | Symbol |
orderId | false | string | Order ID |
orderLinkId | false | string | Unique user-set order ID. Maximum length of 36 characters |
copyTradeOrderType | false | string | CopyTrading order type |
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | Order ID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
symbol | string | Symbol |
side | string | Side |
price | string | Order price |
qty | string | Order quantity in USD |
timeInForce | string | Time in force |
isIsolated | boolean | true means isolated margin mode; false means cross margin mode |
leverage | string | In Isolated Margin mode, the value is set by the user. In Cross Margin mode, the value is the max leverage at current risk level |
copyTradeOrderStatus | string | Copy trade order type |
leavesQty | string | Number of unfilled contracts from the order's size |
leavesValue | string | The estimated value corresponding to the number of remaining orders |
cumExecValue | string | Cumulative value of trading |
cumExecFee | string | Cumulative trading fees |
createdTime | string | Creation time (when the order_status was Created ) |
updatedTime | string | Update time |
Cancel Order
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/order/cancel \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","orderId":"419190fe-016c-469a-810e-936bef2f5d59","timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"orderId": "419190fe-016c-469a-810e-936bef2f5d59",
"orderLinkId": ""
}
}
Cancel Order
HTTP Request
POST
/contract/v3/private/copytrading/order/cancel
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
orderId | false | string | Order ID |
orderLinkId | false | string | Unique user-set order ID |
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | Order ID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
Close Order
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/order/close \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","symbol":"BTCUSDT","orderId":"419190fe-016c-469a-810e-936bef2f5d59","timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"orderId": "419190fe-016c-469a-810e-936bef2f5d59",
"orderLinkId": ""
}
}
Close Order
HTTP Request
POST
/contract/v3/private/copytrading/order/close
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
symbol | false | string | Symbol |
orderLinkId | false | string | Unique user-set order ID. Maximum length of 36 characters |
parentOrderId | false | string | Required if not passing parent_order_link_id |
parentOrderLinkId | false | string | Required if not passing parent_order_id |
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | UserID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
Position
Position List
Request Example
curl "https://api-testnet.bybit.com/contract/v3/private/copytrading/position/list?apiKey={api_key}&symbol=XRPUSDT×tamp={timestamp}&sign={sign}"
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"list": [
{
"symbol": "XRPUSDT",
"side": "Buy",
"size": "4",
"positionValue": "3.28",
"entryPrice": "0.82",
"liqPrice": "0.0001",
"bustPrice": "0.0001",
"markPrice": "0.5047",
"leverage": "10",
"isIsolated": false,
"positionMargin": "0.0415737",
"occClosingFee": "0.0000003",
"occFundingFee": "0",
"cumRealisedPnl": "-0.36682",
"freeQty": "-4",
"unrealisedPnl": "-1.2612",
"positionIdx": "1",
"createdTime": "1651594009009",
"updatedTime": "1652223355185"
},
{
"symbol": "XRPUSDT",
"side": "Sell",
"size": "28",
"positionValue": "22.6984",
"entryPrice": "0.81065714",
"liqPrice": "199.9998",
"bustPrice": "199.9998",
"markPrice": "0.5047",
"leverage": "10",
"isIsolated": false,
"positionMargin": "88881979.32381973",
"occClosingFee": "4.1999958",
"occFundingFee": "0",
"cumRealisedPnl": "1.76750995",
"freeQty": "28",
"unrealisedPnl": "8.5668",
"positionIdx": "2",
"createdTime": "1651594009009",
"updatedTime": "1652223355185"
}
]
}
}
Position List
HTTP Request
GET
/contract/v3/private/copytrading/position/list
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
symbol | false | string | Symbol |
Response Parameters
Parameter | Type | Comment |
---|---|---|
symbol | string | Symbol |
side | string | Side |
size | string | Position qty |
positionValue | string | Position value |
entryPrice | string | Average entry price |
liqPrice | string | Liquidation price |
bustPrice | string | Bankruptcy price |
markPrice | string | Mark price |
leverage | string | In Isolated Margin mode, the value is set by the user. In Cross Margin mode, the value is the max leverage at current risk level |
isIsolated | boolean | true means isolated margin mode; false means cross margin mode |
positionMargin | string | Position margin |
occClosingFee | string | Position closing fee occupied (your opening fee + expected maximum closing fee) |
occFundingFee | string | Pre-occupied funding fee: calculated from position qty and current funding fee |
cumRealisedPnl | string | Accumulated realised pnl (all-time total) |
freeQty | string | Qty which can be closed. (If you have a long position, free_qty is negative. vice versa) |
unrealisedPnl | string | unrealised pnl |
positionIdx | string | Position idx, used to identify positions in different position modes: 1-Buy side of both side mode 2-Sell side of both side mode |
createdTime | string | Creation time (when the order_status was Created ) |
updatedTime | string | Update time |
Close Position
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/position/close \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","symbol":"BTCUSDT",positionIdx:"2","timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {}
}
Close Position
HTTP Request
POST
/contract/v3/private/copytrading/position/close
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
symbol | true | string | Symbol |
positionIdx | true | string | Position idx, used to identify positions in different position modes: 1-Buy side of both side mode 2-Sell side of both side mode |
Response Parameters
Parameter | Type | Comment |
---|
Set Leverage
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/position/set-leverage \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","symbol":"BTCUSDT","buyLeverage":"14","sellLeverage":"14",timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {}
}
Only integers can be set to set the leverage
HTTP Request
POST
/contract/v3/private/copytrading/position/set-leverage
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
symbol | true | string | Symbol |
buyLeverage | true | string | The value of buy_leverage must be equal to sell_leverage . |
sellLeverage | true | string | The value of buy_leverage must be equal to sell_leverage . |
Response Parameters
Parameter | Type | Comment |
---|
Wallet Data Endpoints
The following wallet data endpoints require authentication.
Get Wallet Balance
Request Example
curl "https://api-testnet.bybit.com/contract/v3/private/copytrading/wallet/balance?api_key={api_key}×tamp={timestamp}&sign={sign}"
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"availableBalance": "88881981.61301266",
"usedMargin": "6463.81892229",
"orderMargin": "6461.736762",
"positionMargin": "2.08216029",
"walletBalance": "88888445.43193495",
"realisedPnl": "-444.061167",
"unrealisedPnl": "6.948",
"cumRealisedPnl": "-442.56806505",
"coin": "USDT",
"equity": "88888452.37993495"
}
}
Get Wallet Balance
HTTP Request
GET
/contract/v3/private/copytrading/wallet/balance
Request Parameters
Parameter | Required | Type | Comment |
---|
Response Parameters
Parameter | Type | Comment |
---|---|---|
coin | string | currency alias |
equity | string | User equity (wallet_balance + unrealised_pnl) |
availableBalance | string | Available balance = wallet balance - used margin |
usedMargin | string | Used margin |
orderMargin | string | Pre-occupied order margin |
positionMargin | string | Position margin |
walletBalance | string | Wallet balance |
realisedPnl | string | Today's realised pnl |
unrealisedPnl | string | unrealised pnl |
cumRealisedPnl | string | Accumulated realised pnl (all-time total) |
Transfer
Request Example
curl https://api-testnet.bybit.com/contract/v3/private/copytrading/wallet/transfer \
-H "Content-Type: application/json" \
-d '{"api_key":"{api_key}","transferId":"5f95de18-b10f-43be-9746-7b95c4a37d97","coin":"USDT","amount":"88.88","fromAccountType":"CONTRACT","toAccountType":"COPYTRADING","timestamp":{timestamp},"sign":"{sign}"}'
Response Example
{
"retCode": 0,
"retMsg": "success",
"result": {
"transferId": "5f95de18-b10f-43be-9746-7b95c4a37d97"
}
}
Transfer
HTTP Request
POST
/contract/v3/private/copytrading/wallet/transfer
Request Parameters
Parameter | Required | Type | Comment |
---|---|---|---|
transferId | true | string | UUID, which is unique across the platform |
coin | true | string | Currency type |
amount | true | string | Exchange to amount |
fromAccountType | true | string | Account type |
toAccountType | true | string | Account type |
Response Parameters
Parameter | Type | Comment |
---|---|---|
transferId | string | UUID, which is unique across the platform |
API Data Endpoints
The following API data endpoints do not require authentication.
Server Time
Request Example
curl https://api-testnet.bybit.com/v2/public/time
from pybit import HTTP
session = HTTP("https://api-testnet.bybit.com")
print(session.server_time())
Response Example
{
"ret_code": 0,
"ret_msg": "OK",
"ext_code": "",
"ext_info": "",
"result": {},
"time_now": "1577444332.192859"
}
Get Bybit server time.
HTTP Request
GET
/v2/public/time
Request Parameters
Parameter | Required | Type | Comment |
---|
Announcement
Request Example
curl https://api-testnet.bybit.com/v2/public/announcement
Response Example
{
"ret_code": 0,
"ret_msg": "OK",
"ext_code": "",
"ext_info": "",
"result": [
{
"id": 2,
"title": "2019-12-02 RELEASE",
"link": "https://github.com/bybit-exchange/bybit-official-api-docs/blob/master/en/CHANGELOG.md",
"summary": "<p>New `cancel all` endpoint is here now!</p><p>Additionally, we strongly recommend that you use the new released place and cancel active V2 endpoints, which are more stable and efficient.The old ones are deprecated (although still working for the time be",
"created_at": "2019-12-02T11:33:42Z"
}
],
"time_now": "1577444818.227082"
}
Get Bybit OpenAPI announcements in the last 30 days in reverse order.
HTTP Request
GET
/v2/public/announcement
Request Parameters
Parameter | Required | Type | Comment |
---|
Rate Limits
IP Rate Limit
Bybit has different IP frequency limits depending on the request method. We do not recommend running your application at the very edge of these limits in case abnormal network activity results in an unexpected violation.
-
GET
&DELETE
methods (shared):- 50 requests per second for 2 consecutive minutes
- 70 requests per second for 5 consecutive seconds
-
POST
method:- 20 requests per second for 2 consecutive minutes
- 50 requests per second for 5 consecutive seconds
This table shows how there are different IP rate limit counters depending on the API you are using.
IP rate limit | API | Path |
---|---|---|
2mins 50/s; 5s 70/s |
||
Inverse Perpetual | /v2 | |
Inverse Futures | /futures | |
Linear Perpetual | /public, /private | |
Account Asset | /asset | |
2mins 50/s; 5s 70/s |
||
Spot | /spot | |
2mins 50/s; 5s 70/s |
||
USDC Options | /option | |
USDC Perpetual | /perpetual |
After violating the limit your IP will be banned for a set period of time (usually 30 minutes). Continually violating the limit will result in a permanent ban. We cannot undo permanent bans or shorten temporary bans.
Rate Limits For All Private Endpoints
Limit | Path | Consume |
---|---|---|
75/min | ||
/contract/v3/private/copytrading/position/set-leverage | 1 / request | |
/contract/v3/private/copytrading/position/close | 1 / request | |
/contract/v3/private/copytrading/position/list | 1 / request | |
100/min | ||
/contract/v3/private/copytrading/order/create | 1 / request | |
/contract/v3/private/copytrading/order/close | 1 / request | |
/contract/v3/private/copytrading/order/cancel | 1 / request | |
/contract/v3/private/copytrading/order/list | 1 / request | |
120/min | ||
/contract/v3/private/copytrading/wallet/balance | 1 / request | |
/contract/v3/private/copytrading/wallet/transfer | 1 / request |
Order Limits
Max. number of unfilled orders supported for each leader:
- Active orders: 50
How to Increase API Limits
- Please refer to Understanding Bybit's Liquidity System regarding how our system automatically allocates rate limits for users who place over 2,000 orders per day.
- Please email api@bybit.com with the following information. We will reply within 1-4 working days:
- Your name and your company details
- Your Bybit UID or registered email, and the assets you are trading
- General description of your trading strategy and reasons for higher rate limits
- Screenshot of previous monthly trading volume (maker/taker) on other platforms
- Optional: your order history in CSV format
Understanding Bybit's Liquidity System
Bybit uses Order Fill Ratio (OFR)
and Liquidity Contribution Points (LCP)
to measure customers' contribution to our executable liquidity.
The LCP
and OFR
of different assets are calculated separately.
Order Fill Ratio (OFR) Threshold
If you place more than 2000
orders per day on Bybit, please make sure that your 7-day OFR is above a Minimum OFR threshold
. Otherwise, Bybit may reduce the rate limits for your API request.
Minimum OFR Threshold
7-day OFR must be kept above 0.1%.
Order Fill Ratio (OFR)
Order Fill Ratio (OFR)
:Orders Filled
toOrders Submitted to Bybit
to Bybit.Orders Submitted to Bybit
: any order submitted to Bybit.Orders Filled
: any order that has been filled (regardless of filled quantity).OFR = (number of orders filled / number of orders submitted to Bybit)
Order Fill Ratio Example
User A: Orders Filled = 2 Orders Submitted to Bybit = 8 OFR = 2/8 = 25%
User B: Orders Filled = 1 Orders Submitted to Bybit = 1 OFR = 1/1 = 100%
Rate Limits for API Requests
The rate limits for your API requests are based on your min. Liquidity Contribution Points (LCP)
within 7
days.
LCP | Order Frequency Limit |
---|---|
20-100 | 800 times per minute |
10-20 | 600 times per minute |
5-10 | 400 times per minute |
2-5 | 200 times per minute |
<2 | 100 times per minute |
Liquidity Contribution Points (LCP)
Liquidity Contribution Points (LCP) = POU * POA * 100
Explanation
Effective Price Range
effective price range
: order price that falls within the lower and upper price bounds.Min
effective price
: (best bid price + best ask price) / 2 - (3 * tick_size)Max
effective price
: (best bid price + best ask price) / 2 + (3 * tick_size)
Effective Price Range Example
BTC best bid = 10000 BTC best ask = 10001 Effective Price Range: [(10000 + 10001) / 2 - 3* 0.5, (10000 + 10001) / 2 + 3* 0.5] = [9999,10002]
POU
POU
: The size of your orders that fall within theeffective price range
in proportion to the total size of your orders in the order book.
Bybit calculates the size of your orders that fall within the effective price range
/ the total size of your orders in the order book per second, and then computes the time-weighted-average of the day.
amount of User C's orders within effective price range = 8000 amount of all User C's orders = 2000 + 8000 = 10000 POU = 8000 / 10000 = 0.8
POA
POA
: the proportion of your orders withineffective price range
to all orders withineffective price range
in orderbook.
Bybit calculates your amount of orders within effective price range
/ amount of all orders within effective price range
in orderbook, and then performs a 1-Day Time-Weighted-Average over the series of seconds rates.
POA example
The size of user C's orders that fall within the effective price range is 8,000, while the total size of orders in the order book that fall within the effective price range is 200,000.
Size of user C's orders within effective price range = 8000 Total size of orders within effective price range = 200000 POA = 8000 / 200000 = 0.04
WebSocket Data
Authentication
Authentication methods:
First method: Apply for authentication when establishing a connection.
# based on: https://github.com/bybit-exchange/pybit/blob/master/pybit/_http_manager.py
import hmac
import json
import time
import websocket
ws_url = "wss://stream.bybit.com/realtime_private"
api_key = ""
api_secret = ""
# Generate expires.
expires = int((time.time() + 1) * 1000)
# Generate signature.
signature = str(hmac.new(
bytes(api_secret, "utf-8"),
bytes(f"GET/realtime{expires}", "utf-8"), digestmod="sha256"
).hexdigest())
param = "api_key={api_key}&expires={expires}&signature={signature}".format(
api_key=api_key,
expires=expires,
signature=signature
)
url = ws_url + "?" + param
ws = websocket.WebSocketApp(
url=url,
...
)
Second method: Apply for authentication after establishing a connection through auth request.
ws = websocket.WebSocketApp(
url=url,
...
)
# Authenticate with API.
ws.send(
json.dumps({
"op": "auth",
"args": [api_key, expires, signature]
})
)
Base endpoints:
- Testnet public: wss://stream-testnet.bybit.com/realtime_public
- Testnet private: wss://stream-testnet.bybit.com/realtime_private
- Mainnet public (both endpoints are available):
- wss://stream.bybit.com/realtime_public
- wss://stream.bytick.com/realtime_public
- Mainnet private (both endpoints are available):
- wss://stream.bybit.com/realtime_private
- wss://stream.bytick.com/realtime_private
Authentication examples are shown in the code block.
How to Send Heartbeat Packet
How to Send
ws.send('{"op":"ping"}');
Response Example
{
"success": true, // Whether ping is successful
"ret_msg": "pong",
"conn_id": "036e5d21-804c-4447-a92d-b65a44d00700",// current connection id
"request": {
"op": "ping",
"args": null
}
}
How to Subscribe to Topics
Understanding Websocket Filters
How to subscribe with a filter
// Subscribing to the trade data for BTCUSD
ws.send('{"op":"subscribe","args":["trade.BTCUSD"]}')
How to subscribe with multiple filters
// Example: Subscribing to the trade data for BTCUSD and XRPUSD
ws.send('{"op":"subscribe","args":["trade.BTCUSD|XRPUSD"]}')
How to subscribe without filters
// Example: Subscribing to the trade data for all symbols
ws.send('{"op": "subscribe", "args": ["trade.*"]}')
After establishing the connection, one can subscribe to a new topic by sending a JSON request. The specific formats are as follows:
ws.send('{"op": "subscribe", "args": ["topic.filter"]}');
The topic
indicates the data you would like to receive whilst the filter
parses for the specific data you desire - for example, the symbol. The topic
is mandatory but the filter
is optional.
To subscribe to more than one topic, simply list multiple topics out, like so:
ws.send('{"op": "subscribe", "args": ["topic.filter", "topic.filter"]}');
It is possible to use multiple filters for the same topic by splitting them with a pipe (|
) - of course, these filters must all be applicable to the selected topic
.
Finally, to subscribe to the topic without filters please use the *
wildcard.
Unsubscribing From Websocket Topics
How to unsubscribe with a filter
// Unsubscribing from the trade data for ETHUSD
ws.send('{"op":"unsubscribe","args":["trade.ETHUSD"]}')
You can dynamically subscribe and unsubscribe from topics (with or without filters) without websocket disconnection as follows:
ws.send('{"op": "unsubscribe", "args": ["topic.filter", "topic.filter"]}');
Intervals
Some topics are pushed at intervals. If the args
contain a millisecond param, such as 100ms
, this topic is pushed at intervals. Otherwise, it is pushed constantly.
Understanding Subscription Response
Subscription Response
{
"success": true, // Whether subscription is successful
"ret_msg": "", // Successful subscription: "", otherwise it shows error message
"conn_id":"e0e10eee-4eff-4d21-881e-a0c55c25e2da",// current connection id
"request": { // Request to your subscription
"op": "subscribe",
"args": [
"kline.BTCUSD.1m"
]
}
}
Each subscription will have a response. You can determine whether the subscription is successful based on the response.
Public Topics
orderBookL2_25
How to Subscribe
ws.send('{"op": "subscribe", "args": ["orderBookL2_25.BTCUSD"]}');
from pybit import WebSocket
subs = [
"orderBookL2_25.BTCUSD"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Snapshot Response Example - format of the first response
{
"topic": "orderBookL2_25.BTCUSD",
"type": "snapshot",
"data": [
{
"price": "2999.00",
"symbol": "BTCUSD",
"id": 29990000,
"side": "Buy",
"size": 9
},
{
"price": "3001.00",
"symbol": "BTCUSD",
"id": 30010000,
"side": "Sell",
"size": 10
}
],
"cross_seq": 11518,
"timestamp_e6": 1555647164875373
}
Delta Response Example - format of the responses following the snapshot response
{
"topic": "orderBookL2_25.BTCUSD",
"type": "delta",
"data": {
"delete": [
{
"price": "3001.00",
"symbol": "BTCUSD",
"id": 30010000,
"side": "Sell"
}
],
"update": [
{
"price": "2999.00",
"symbol": "BTCUSD",
"id": 29990000,
"side": "Buy",
"size": 8
}
],
"insert": [
{
"price": "2998.00",
"symbol": "BTCUSD",
"id": 29980000,
"side": "Buy",
"size": 8
}
],
"transactTimeE6": 0
},
"cross_seq": 11519,
"timestamp_e6": 1555647221331673
}
Fetches the orderbook with a depth of 25 orders per side.
After the subscription response, the first response will be the snapshot response. This shows the entire orderbook. The data is ordered by price, starting with the lowest buys and ending with the highest sells.
Following this, all responses are in the delta format, which represents updates to the orderbook relative to the last response.
Push frequency: 20ms
Response Parameters
Parameter | Type | Comment |
---|---|---|
price | string | Order price |
symbol | string | Symbol |
side | string | Side |
size | number | Position qty |
orderBookL2_200
How to Subscribe
ws.send('{"op": "subscribe", "args": ["orderBook_200.100ms.BTCUSD"]}');
from pybit import WebSocket
subs = [
"orderBook_200.100ms.BTCUSD"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Snapshot Response Example - format of the first response
{
"topic": "orderBook_200.100ms.BTCUSD",
"type": "snapshot",
"data": [
{
"price": "2999.00",
"symbol": "BTCUSD",
"id": 29990000,
"side": "Buy",
"size": 9
},
{
"price": "3001.00",
"symbol": "BTCUSD",
"id": 30010000,
"side": "Sell",
"size": 10
}
],
"cross_seq": 11518,
"timestamp_e6": 1555647164875373
}
Delta Response Example - format of the responses following the snapshot response
{
"topic": "orderBook_200.100ms.BTCUSD",
"type": "delta",
"data": {
"delete": [
{
"price": "3001.00",
"symbol": "BTCUSD",
"id": 30010000,
"side": "Sell"
}
],
"update": [
{
"price": "2999.00",
"symbol": "BTCUSD",
"id": 29990000,
"side": "Buy",
"size": 8
}
],
"insert": [
{
"price": "2998.00",
"symbol": "BTCUSD",
"id": 29980000,
"side": "Buy",
"size": 8
}
],
"transactTimeE6": 0
},
"cross_seq": 11519,
"timestamp_e6": 1555647221331673
}
Fetches the orderbook with a depth of 200 orders per side.
After the subscription response, the first response will be the snapshot response. This shows the entire orderbook. The data is ordered by price, starting with the lowest buys and ending with the highest sells.
Following this, all responses are in the delta format, which represents updates to the orderbook relative to the last response.
Push frequency: 100ms
Response Parameters
Parameter | Type | Comment |
---|---|---|
price | string | Order price |
symbol | string | Symbol |
side | string | Side |
size | number | Position qty |
trade
How to Subscribe
ws.send('{"op": "subscribe", "args": ["trade"]}')
from pybit import WebSocket
subs = [
"trade"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic": "trade.BTCUSD",
"data": [
{
"timestamp": "2020-01-12T16:59:59.000Z",
"trade_time_ms": 1582793344685, // trade time in millisecond
"symbol": "BTCUSD",
"side": "Sell",
"size": 328,
"price": 8098,
"tick_direction": "MinusTick",
"trade_id": "00c706e1-ba52-5bb0-98d0-bf694bdc69f7",
"cross_seq": 1052816407
}
]
}
Push frequency: 100ms
Response Parameters
Parameter | Type | Comment |
---|---|---|
timestamp | string | UTC time |
trade_time_ms | number | Millisecond timestamp |
symbol | string | Symbol |
side | string | Direction of taker |
size | number | Position qty |
price | number | Order price |
tick_direction | string | Direction of price change |
trade_id | string | Trade ID |
cross_seq | number | Cross sequence (internal value) |
insurance
How to Subscribe
ws.send('{"op": "subscribe", "args": ["insurance"]}')
from pybit import WebSocket
subs = [
"insurance.BTC"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic": "insurance.BTC",
"data": [
{
"currency": "BTC",
"timestamp": "2020-01-11T20:00:00Z",
"wallet_balance": 98786916569
}
]
}
Get the daily insurance fund update.
Push frequency: 20:00 UTC / day
Response Parameters
Parameter | Type | Comment |
---|---|---|
currency | string | Currency type |
timestamp | string | UTC time |
wallet_balance | number | Wallet balance |
instrumentInfo
How to Subscribe
ws.send('{"op": "subscribe", "args": ["instrument_info.100ms.BTCUSD"]}')
from pybit import WebSocket
subs = [
"instrument_info.100ms.BTCUSD"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Snapshot Response Example - format of the first response
{
"topic":"instrument_info.100ms.BTCUSD",
"type":"snapshot",
"data": {
"id": 1,
"symbol": "BTCUSD", //instrument name
"last_price_e4": 81165000, //the latest price
"last_price": "81165000",
"bid1_price_e4":400025000, // best bid price
"bid1_price":"400025000",
"ask1_price_e4":475450000, // best ask price
"ask1_price":"475450000",
"last_tick_direction": "ZeroPlusTick", //the direction of last tick:PlusTick,ZeroPlusTick,MinusTick,ZeroMinusTick
"prev_price_24h_e4": 81585000, //the price of prev 24h
"prev_price_24h": "81585000",
"price_24h_pcnt_e6": -5148, //the current last price percentage change from prev 24h price
"high_price_24h_e4": 82900000, //the highest price of prev 24h
"high_price_24h": "82900000",
"low_price_24h_e4": 79655000, //the lowest price of prev 24h
"low_price_24h": "79655000",
"prev_price_1h_e4": 81395000, //the price of prev 1h
"prev_price_1h": "81395000",
"price_1h_pcnt_e6": -2825, //the current last price percentage change from prev 1h price
"mark_price_e4": 81178500, //mark price
"mark_price": "81178500",
"index_price_e4": 81172800, //index price
"index_price": "81172800",
"open_interest": 154418471, //open interest quantity - Attention, the update is not immediate - slowest update is 1 minute
"open_value_e8": 1997561103030, //open value quantity - Attention, the update is not immediate - the slowest update is 1 minute
"total_turnover_e8": 2029370141961401, //total turnover
"turnover_24h_e8": 9072939873591, //24h turnover
"total_volume": 175654418740, //total volume
"volume_24h": 735865248, //24h volume
"funding_rate_e6": 100, //funding rate
"predicted_funding_rate_e6": 100, //predicted funding rate
"cross_seq": 1053192577, //sequence
"created_at": "2018-11-14T16:33:26Z",
"updated_at": "2020-01-12T18:25:16Z",
"next_funding_time": "2020-01-13T00:00:00Z", //next funding time
//the rest time to settle funding fee
"countdown_hour": 6, //the remaining time to settle the funding fee
"funding_rate_interval": 8
},
"cross_seq":9267002,
"timestamp_e6":1615794861826248
}
Delta Response Example - format of the responses following the snapshot response
{
"topic": "instrument_info.100ms.BTCUSD",
"type": "delta",
"data": {
"delete": [],
"update": [
{
"id": 1,
"symbol": "BTCUSD",
"prev_price_24h_e4": 81565000,
"prev_price_24h": "81565000",
"price_24h_pcnt_e6": -4904,
"open_value_e8": 2000479681106,
"total_turnover_e8": 2029370495672976,
"turnover_24h_e8": 9066215468687,
"volume_24h": 735316391,
"cross_seq": 1053192657,
"created_at": "2018-11-14T16:33:26Z",
"updated_at": "2020-01-12T18:25:25Z"
}
],
"insert": []
},
"cross_seq": 1053192657,
"timestamp_e6": 1578853525691123
}
Get latest information for symbol.
Push frequency: 100ms
Response Parameters
Parameter | Type | Comment |
---|---|---|
symbol | string | Symbol |
last_price_e4 | integer | (Deprecated) Latest transaction price 10^4 |
tick_direction | string | Direction of price change |
prev_price_24h_e4 | integer | (Deprecated) Price of 24 hours ago * 10^4 |
price_24h_pcnt_e6 | integer | Percentage change of market price relative to 24h * 10^4 |
high_price_24h_e4 | integer | (Deprecated) The highest price in the last 24 hours * 10^4 |
low_price_24h_e4 | integer | (Deprecated) Lowest price in the last 24 hours * 10^4 |
prev_price_1h_e4 | integer | (Deprecated) Hourly market price an hour ago * 10^4 |
price_1h_pcnt_e6 | integer | Percentage change of market price relative to 1 hour ago * 10^6 |
mark_price_e4 | integer | (Deprecated) Mark price * 10^4 |
index_price_e4 | integer | (Deprecated) Index_price * 10^4 |
last_price | integer | Latest transaction price |
prev_price_24h | integer | Price of 24 hours ago |
high_price_24h | integer | The highest price in the last 24 hours |
low_price_24h | integer | Lowest price in the last 24 hours |
prev_price_1h | integer | Hourly market price an hour ago |
mark_price | integer | Mark price |
index_price | integer | Index_price |
open_interest | integer | Open interest. The update is not immediate - slowest update is 1 minute |
open_value_e8 | integer | Open position value * 10^8. The update is not immediate - slowest update is 1 minute |
total_turnover_e8 | integer | Total turnover * 10^8 |
turnover_24h_e8 | integer | Turnover for 24h * 10^8 |
total_volume | integer | Total volume |
volume_24h | integer | Trading volume in the last 24 hours |
predicted_funding_rate_e6 | integer | Predicted funding rate * 10^6 |
cross_seq | integer | Cross sequence (internal value) |
created_at | string | Creation time (when the order_status was Created ) |
updated_at | string | Update time |
next_funding_time | string | Next settlement time of capital cost |
countdown_hour | integer | Countdown of settlement capital cost |
funding_rate_interval | integer | funding rate time interval, unit hour |
klineV2
How to Subscribe
ws.send('{"op":"subscribe","args":["klineV2.1.BTCUSD"]}')
from pybit import WebSocket
subs = [
"klineV2.1.BTCUSD"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic": "klineV2.1.BTCUSD", //topic name
"data": [{
"start": 1572425640, //start time of the candle
"end": 1572425700, //end time of the candle
"open": 9200, //open price
"close": 9202.5, //close price
"high": 9202.5, //max price
"low": 9196, //min price
"volume": 81790, //volume
"turnover": 8.889247899999999, //turnover
"confirm": False, //snapshot flag
"cross_seq": 297503466,
"timestamp": 1572425676958323 //cross time
}],
"timestamp_e6": 1572425677047994 //server time
}
Currently supported intervals:
- 1 3 5 15 30
- 60 120 240 360 720
- D
- W
- M
Push frequency: 1-60s
Response Parameters
Parameter | Type | Comment |
---|---|---|
start | integer | Start timestamp point for result, in seconds |
end | integer | End timestamp point for result, in seconds |
open | number | Starting price |
close | number | Closing price |
high | number | Maximum price |
low | number | Minimum price |
volume | number | Trading volume |
turnover | number | Turnover |
confirm | bool | Is confirm |
cross_seq | integer | Cross sequence (internal value) |
timestamp | integer | End timestamp point for result, in seconds |
liquidation
How to Subscribe
ws.send('{"op":"subscribe","args":["liquidation"]}')
from pybit import WebSocket
subs = [
"liquidation"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime",
subscriptions=subs
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic":"liquidation.ETHUSD",
"data": {
"symbol":"ETHUSD",
"side":"Sell",
"price":"3384.15",
"qty":"3655",
"time":1631608881954
}
}
Pushes liquidation orders.
Push frequency: real-time
Response Parameters
Parameter | Type | Comment |
---|---|---|
symbol | string | Symbol |
side | string | Liquidated position's side |
price | string | Bankruptcy price |
qty | string | Order quantity in USD |
time | number | Millisecond timestamp |
Private Topics
position
How to Subscribe
ws.send('{"op": "subscribe", "args": ["copyTradePosition"]}')
from pybit import WebSocket
subs = [
"copyTradePosition"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime_private",
subscriptions=subs,
api_key="", api_secret=""
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic":"copyTradePosition",
"data":[
{
"symbol":"ETHUSDT",
"positionIdx":"2",
"positionValue":"80.05065626",
"riskId":11,
"leverage":"10.000000",
"isIsolated":true,
"side":"Sell",
"size":"0.040000",
"unrealisedPnl":"1.62665626",
"liqPrice":"2191.350098",
"bustPrice":"2201.350098",
"entryPrice":"2001.26640650",
"positionMargin":"8.00506666",
"orderMargin":"0.00000000",
"occClosingFee":"0.05283240",
"cumRealisedPnl":"0.55284374",
"positionStatus":"Normal",
"positionSeq":0
}
]
}
Response Parameters
Parameter | Type | Comment |
---|---|---|
symbol | string | Symbol |
positionIdx | string | Position idx, used to identify positions in different position modes: 1-Buy side of both side mode 2-Sell side of both side mode |
positionValue | string | Position value |
riskId | string | Risk ID |
leverage | string | In Isolated Margin mode, the value is set by the user. |
isolated | bool | true means isolated margin mode; false means cross margin mode |
side | string | Side |
size | string | Position qty |
unrealisedPnl | string | unrealised pnl |
liqPrice | string | Liquidation price |
bustPrice | string | Bankruptcy price |
entryPrice | string | Average entry price |
positionMargin | string | Position margin |
orderMargin | string | Pre-occupied order margin |
occClosingFee | string | Position closing fee occupied (your opening fee + expected maximum closing fee) |
cumRealisedPnl | string | Accumulated realised pnl (all-time total) |
positionStatus | string | Position status: Normal , Liq , Adl
|
positionSeq | number | Position sequence |
order
How to Subscribe
ws.send('{"op": "subscribe", "args": ["copyTradeOrder"]}')
from pybit import WebSocket
subs = [
"copyTradeOrder"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime_private",
subscriptions=subs,
api_key="", api_secret=""
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic":"copyTradeOrder",
"data":[
{
"orderId":"6d667921-3cf4-4efd-b93f-727bd10a3b62",
"orderLinkId":"w11a313223ddd132111",
"symbol":"ETHUSDT",
"orderType":"Market",
"price":"1863.250000",
"qty":"0.010000",
"side":"Sell",
"positionIdx":"2",
"cumExecFee":"0.01175970",
"cumExecValue":"19.59950000",
"lastExecPrice":"1959.949951",
"cumExecQty":"0.010000",
"createTime":1652932133873,
"updateTime":1652932133892,
"copyTradeOrderStatus":"OpenOrderFilled"
}
]
}
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | Order ID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
symbol | string | Symbol |
orderType | string | Conditional order type |
price | string | Order price |
qty | string | Transaction qty |
side | string | Side |
positionIdx | string | Position idx, used to identify positions in different position modes: 1-Buy side of both side mode 2-Sell side of both side mode |
cumExecFee | string | Cumulative trading fees |
cumExecValue | string | Cumulative value of trading |
lastExecPrice | string | Last execution price |
cumExecQty | string | Cumulative qty of trading |
createTime | string | Commission time |
updateTime | string | Update time |
copyTradeOrderStatus | string | Copy trade order status |
execution
How to Subscribe
ws.send('{"op": "subscribe", "args": ["copyTradeExecution"]}')
from pybit import WebSocket
subs = [
"copyTradeExecution"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime_private",
subscriptions=subs,
api_key="", api_secret=""
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic":"copyTradeExecution",
"data":[
{
"orderId":"6d667921-3cf4-4efd-b93f-727bd10a3b62",
"orderLinkId":"w11a313223ddd132111",
"symbol":"ETHUSDT",
"side":"Sell",
"execId":"0182b08b-a3ce-5038-a8be-5e1e9f862e90",
"execQty":"0.010000",
"execType":"Trade",
"execFee":"0.01175970",
"price":"1863.250000",
"orderQty":"0.010000",
"tradeTime":1652932133873
}
]
}
Response Parameters
Parameter | Type | Comment |
---|---|---|
orderId | string | Order ID |
orderLinkId | string | Unique user-set order ID. Maximum length of 36 characters |
symbol | string | Symbol |
side | string | Side |
execId | string | Transaction ID |
execQty | string | Transaction qty |
execType | string | Execution type (cannot be Funding ) |
execFee | string | Transaction fee |
price | string | Transaction price |
orderQty | string | Order qty |
tradeTime | string | Transaction timestamp |
wallet
How to Subscribe
ws.send('{"op": "subscribe", "args": ["copyTradeWallet"]}')
from pybit import WebSocket
subs = [
"copyTradeWallet"
]
ws = WebSocket(
"wss://stream-testnet.bybit.com/realtime_private",
subscriptions=subs,
api_key="", api_secret=""
)
while True:
data = ws.fetch(subs[0])
if data:
print(data)
Response Example - format of all responses
{
"topic":"copyTradeWallet",
"data":{
"walletBalance":"14009.12164704",
"availableBalance":"13998.97749271"
}
}
Response Parameters
Parameter | Type | Comment |
---|---|---|
walletBalance | number | Wallet balance |
availableBalance | number | Available balance = wallet balance - used margin |
Archive Data
Historical Market Data
You can get Bybit's historical market data here.
Historical funding rates are not available through the API. However, you can obtain a CSV of this data by using the "Export" button here.
Enums Definitions
The following lists enumerator names for the request and response parameters of each endpoint.
Side (side
)
Buy
Sell
Symbol (symbol
)
BTCUSD
ETHUSD
EOSUSD
XRPUSD
DOTUSD
You can get all symbols with the Query Symbol endpoint.
Currency (currency
/coin
)
BTC
ETH
EOS
XRP
DOT
USDT
Contract Type(contract_type
)
InversePerpetual
LinearPerpetual
InverseFutures
Contract Status(status
)
Trading
Settling
Closed
Wallet fund type (wallet_fund_type
/ type
)
Deposit
Withdraw
RealisedPNL
Commission
Refund
Prize
ExchangeOrderWithdraw
ExchangeOrderDeposit
ReturnServiceCash
- Refund of handling fee bonusInsurance
- Insurance account transferSubMember
- Parent-child account transferCoupon
- Coupon interestAccountTransfer
- Account transferCashBack
- Cash back
Withdraw status (status
)
ToBeConfirmed
UnderReview
Pending
- Pending transferSuccess
CancelByUser
Reject
Expire
Order type (order_type
)
Limit
Market
Quantity (qty
)
- The maximum qty for an order (
max_trading_qty
) can be queried with the Query Symbol endpoint. - Must be a positive integer
- Must conform to the symbol's
qty_step
. For example, for the inverse perpetual BTCUSD market: 40
- allowed30.5
- not allowed
Price (price
)
- Active order
- Must be an integral multiple of
tick_size
- Information about current trading pair (e.g.
tick_size
) can be queried with the Query Symbol endpoint. - Modulo (
%
) can be used to calculate whether the price will be accepted:IF price % tick_size = 0 // send request ELSE // do not send request as the price will not be accepted by the system
- Information about current trading pair (e.g.
- Must be less than the symbol's
max_price
- If the user has no open position, the order price must be higher than 10% of the last traded price
- For example, if the last traded price (last price) is
10314
, the min. order price will be1031.5
. - Pseudocode (assuming the price is a multiple of 0.5):
IF price > (last_price * 0.1) // send request ELSE // do not send request as the price will not be accepted by the system
- For example, if the last traded price (last price) is
- If the user has an open position, the order price must be better than the liquidation price.
- For example, if the liquidation price of a long position is
5176.5
, the min. order price will be5177
. For short position, the order price must be less than the liquidation price.
- For example, if the liquidation price of a long position is
- Must be an integral multiple of
- Conditional order
- Must be greater than or equal to
1
- Must be greater than or equal to
Time in force (time_in_force
)
GoodTillCancel
ImmediateOrCancel
FillOrKill
PostOnly
Trigger price type (trigger_by
)
LastPrice
IndexPrice
MarkPrice
Order (order
)
This is used for sorting orders/trades in a specified direction.
desc
asc
Order status (order_status
)
Created
- order has been accepted by the system but not yet put through the matching engineRejected
New
- order has been placed successfullyPartiallyFilled
Filled
Cancelled
PendingCancel
- matching engine has received the cancelation request but it may not be canceled successfully
Account type (from_account_type
/to_account_type
)
CONTRACT
COPYTRADING
UNIFIED
Stop order status (stop_order_status
)
Active
- order has been triggered and the new active order has been successfully placed. Is the final state of a successful conditional orderUntriggered
- order yet to be triggeredTriggered
- order has been triggered by last traded priceCancelled
- order has been canceled successfullyRejected
- order has been triggered but failed to be placed (e.g. due to insufficient margin)Deactivated
- order has been canceled by the user before being triggered
Cancel type (cancel_type
)
CancelByUser
CancelByReduceOnly
CancelByPrepareLiq
,CancelAllBeforeLiq
- canceled due to liquidationCancelByPrepareAdl
,CancelAllBeforeAdl
- canceled due to ADLCancelByAdmin
CancelByTpSlTsClear
- TP/SL order canceled successfullyCancelByPzSideCh
- order has been canceled after TP/SL is triggered
Create type (create_type
)
CreateByUser
CreateByClosing
CreateByAdminClosing
CreateByStopOrder
CreateByTakeProfit
CreateByStopLoss
CreateByTrailingStop
CreateByLiq
- Created by partial liquidationCreateByAdl_PassThrough
- Created by ADLCreateByTakeOver_PassThrough
- Created by liquidation takeover
Exec type (exec_type
)
Trade
AdlTrade
Funding
BustTrade
Settle
Liquidity type (last_liquidity_ind
)
AddedLiquidity
- liquidity makerRemovedLiquidity
- liquidity Taker
Tick direction type (tick_direction
)
It indicates price fluctuation relative to the last trade.
PlusTick
- price riseZeroPlusTick
- trade occurs at the same price as the previous trade, which occurred at a price higher than that for the trade preceding itMinusTick
- price dropZeroMinusTick
- trade occurs at the same price as the previous trade, which occurred at a price lower than that for the trade preceding it
TP/SL mode (tp_sl_mode
)
Take profit/stop loss mode
Full
- Full take profit/stop loss mode (a single TP order and a single SL order can be placed, covering the entire position)Partial
- Partial take profit/stop loss mode (multiple TP and SL orders can be placed, covering portions of the position)
Kline interval (interval
)
1
- 1 minute3
- 3 minutes5
- 5 minutes15
- 15 minutes30
- 30 minutes60
- 1 hour120
- 2 hours240
- 4 hours360
- 6 hours720
- 12 hoursD
- 1 dayW
- 1 weekM
- 1 month
Date (start_date
/end_date
)
Follows the format: yyyy-mm-dd
Stop order type (stop_order_type
)
TakeProfit
StopLoss
TrailingStop
Stop
CopyTrading order type (copy_trading_order_type
)
ACTIVE
- active ordersTPSLCONDITIONAL
- take profit or stop loss conditional ordersOPENFILLED
- filled orders
Errors
The Bybit API uses the following HTTP codes and error codes:
HTTP Code | Meaning |
---|---|
200 | Request is valid -- Your request is valid |
403 | Access denied -- You request too many times (refer to the IP rate limit) |
404 | Request path not found |
10000
An unknown error occurred while processing the request.
10001
There was a problem with the value passed to the API. For example, if you pass a float, ensure it conforms to the tick_size
and qty_step
(ie, make sure it does not have too many decimals!).
10002
Request not authorized - an API key is required and should be included in all requests.
10003
Invalid api key
10004
Invalid sign
10005
Permission denied for current apikey. API key was created without the correct permissions (e.g. doesn´t have Order permission, or it's set to read-only)
10006
Too many visits. Refer to the API rate limit. Please use WebSocket for live updates. Current limit is %s requests per minute.
10007
Response timeout from backend server. Delivery and request status unknown.
10010
Request IP mismatch.
10016
Service not available.
10017
Request path not found or request method is invalid
10018
Exceeded IP rate limit.
10020
Request not supported.
10021
Timestamp for the request is outside of the recvWindow. The timestamp of this request is 1000 milliseconds ahead of the server time. Please check local time and server time.
10022
Invalid request signature.
11000
Parameter characters not supported.
11001
Too many parameters sent for this endpoint.
11002
Required parameter not sent. Parameter was empty/null or format was incorrect.
11003
Unknown parameter sent.
11004
Not all parameters sent were read.
11005
Empty parameter.
11006
Parameter was sent when no longer required.
11011
Order price exceeded upper limit.
11012
Trading pair does not exist.
11014
TimeInForce parameter sent when not required.
11015
Invalid timeInForce.
11016
Invalid orderType.
11017
Invalid direction.
11018
User-generated order ID was empty.
11019
User-generated order ID was empty.
11020
Invalid interval.
11021
Invalid symbol.
11025
listenKey does not exist.
11027
Query intervals too large.
11028
Invalid parameter combination.
11030
Invalid parameter sent.
11030
Invalid parameter sent.
11031
Insufficient balance.
11032
Order price exceeded upper limit.
11033
Order price exceeded lower limit.
11034
Order price has too many decimals.
11035
Order quantity exceeded upper limit.
11036
Order quantity exceeded lower limit.
11037
Order quantity has too many decimals.
11038
Order price exceeded limits.
11039
Order has been filled.
11040
Order value exceeded lower limit.
20001
Order does not exist.
20003
Missing parameter side
20004
Invalid parameter side
20005
Missing parameter symbol
20006
Invalid parameter symbol
20007
Missing parameter order_type
20008
Invalid parameter order_type
20009
Missing parameter qty
20010
New order rejected.
20011
Cancelation rejected.
20012
qty
must be greater than zero and less than 1 million
20013
Order does not exist.
20014
Invalid API key format.
20015
Invalid API key or IP.
20016
Trading window not open yet for current pair.
20017
Missing parameter order_id
20018
Invalid date format
20019
Missing parameter stop_px
20020
Missing parameter base_price
20021
Missing parameter stop_order_id
20022
Missing parameter leverage
20023
Leverage must be a number
20031
Leverage must be greater than zero
20070
Missing parameter margin
20071
margin
must be greater than zero
20084
order_id
or order_link_id
is required
30001
order_link_id
is not unique.
30003
qty
must be higher than the minimum allowed.
30004
qty
must be higher than the minimum allowed. The number of contracts exceeds maximum limit allowed. Order qty should be less than 1 million per order.
30005
Order price is out of permissible range.
30006
No last_price
.
30007
Order price is out of permissible range.
30008
Invalid order_type
.
30009
No position found.
30010
Insufficient wallet balance.
30011
Operation not allowed as position is undergoing liquidation
30012
Operation not allowed as position is undergoing ADL
30013
Position is in liq or adl status
30014
Invalid closing order, qty should not be greater than size.
30015
Invalid closing order, side should be the opposite.
30016
TP and SL must be cancelled before closing the position.
30017
Estimated fill price cannot be lower than current Buy liq_price.
30018
Estimated fill price cannot be higher than current Sell liq_price.
30019
Cannot attach TP/SL params for non-zero position when placing non-opening position order.
30020
Position already has TP/SL params.
30021
Cannot afford estimated position_margin.
30022
Estimated buy liq_price cannot be higher than current mark_price.
30023
Estimated sell liq_price cannot be lower than current mark_price.
30024
Cannot set TP/SL/TS for zero-position
30025
Trigger price should bigger than 10% of last price.
30026
Price is too high.
30027
Price set for Take profit should be higher than Last Traded Price.
30028
Price set for Stop Loss should be between Liquidation price and Last Traded Price.
30029
Price set for Stop Loss should be between Last Traded Price and Liquidation Price.
30030
Price set for Take Profit should be lower than Last Traded Price.
30031
Insufficient available balance for order cost.
30032
Order has been filled or cancelled.
30033
The number of stop orders exceeds maximum limit allowed.
30034
No stop order found.
30035
Too fast to cancel, try it later.
30036
The expected position value after order execution exceeds the current risk limit
30037
Order already cancelled
30038
No mark_price.
30039
Applied leverage has exceeded the permitted range.
30040
Any adjustments made will trigger immediate liquidation.
30041
No position found.
30042
Insufficient wallet balance.
30043
Operation not allowed as position is undergoing liquidation.
30044
Operation not allowed as position is undergoing ADL.
30045
Operation not allowed as position is not in normal status.
30046
There are multiple untriggered stop orders.
30047
Inconsistent p:o.
30048
Applied leverage has exceeded the permitted range.
30049
Insufficient available balance.
30050
Any adjustments made will trigger immediate liquidation!
30051
Due to risk limit, cannot adjust leverage.
30052
Leverage cannot be less than 1x.
30053
max_affordable_position_margin <= 0, position:%s
30054
fixed_new_position_margin is invalid.
30055
Available Balance is not enough to add margin.
30056
The position is in cross_margin.
30057
Requested quantity of contracts exceeds risk limit, please adjust your risk limit level before trying again.
30063
Reduce-only rule not satisfied
30066
Set auto add margin fail.
30067
Insufficient available balance.
30068
Exit value must be positive.
30074
Can't create the stop order, because you expect the order will be triggered when the LastPrice
(or IndexPrice
, MarkPrice
, determined by trigger_by
) is raising to stop_px
, but the LastPrice
(or IndexPrice
, MarkPrice
) is already equal to or greater than stop_px
, please adjust base_price
or stop_px
30075
Can't create the stop order, because you expect the order will be triggered when the LastPrice
(or IndexPrice
, MarkPrice
, determined by trigger_by
) is falling to stop_px
, but the LastPrice
(or IndexPrice
, MarkPrice
) is already equal to or less than stop_px
, please adjust base_price
or stop_px
30076
Replace params invalid. Order not modified.
30077
Submission of order will result in the breach of user's limit according to open interest.
30078
Contracts not in trading status
30079
The position is about to trigger a liquidation
30080
Price cannot be lower than current Buy liq_price
30081
Price cannot be greater than current sell liq_price
30082
Position exists No switching of position mode allowed
30083
No change in position pattern
30084
No changes to the full position-by-position model
30085
Margin unchanged
30086
With a commissioned order, switching position mode is not allowed
30087
Symbol does not support two-way open positions
30088
Symbol does not exist
30089
Duplicate order number
30090
Risk limit info does not exist
30091
Illegal orders (meaning that the order os|cs is not legal in various scenarios)
30092
No position is not allowed to set margin
30093
No net position
30094
Withdrawal of an order before a liquidation is not concluded
30095
Full positions are not allowed to modify leverage
31003
User account banned
32006
The available balance is not sufficient to cover the handling fee.
32008
Insufficient available margin.
32009
Any adjustments made will trigger immediate liquidation.
32010
Risk limit cannot be adjusted due to insufficient available margin.
32011
Risk limit cannot be adjusted as the current/expected position value held exceeds the revised risk limit.
33004
apikey already expired
34010
Wallet Balance is less than zero.
34015
Cannot set new leverage as it is equal to the previous leverage.
34017
Current leverage is less than 1X
34018
Cannot set leverage lower than 1X
34019
Cannot set leverage greater than maxLeverage.
34020
Cannot set leverage which is same to the previous leverage.
34021
Cannot cancel occ_calc_data, the data is wrong.
34022
Cannot set leverage which will cause available balance less than 0.
34023
The request was canceled because the origin request has been handled.
34024
The request does not include add margin data.
34025
Increase in leverage has failed.
34026
The new limit is equal to the old limit (no change).
34027
Cannot adjust leverage.
32009
Any adjustments made will trigger immediate liquidation.
34028
ReCalc Funding Fee Failed.
34030
positionInfo not sync with current exec_rpt.
34033
Realized PNL already rotated.
34032
PositionSeq not match on Withdraw.
34035
Add margin not modified.
34036
Set leverage not modified.
34037
Set custom fee rate not modified.
34038
Update deleverage indicator not modified.
34039
Update position status not modified.
34040
Set TP/SL/TS not modified.
35014
37001
Both side positions tp_sl_mode is equal.
37002
Same tp_sl_mode.
37003
This position has at least one stop-link order and cannot switch between stop-loss and take-profit modes.
37004
This position has at least one stop-loss link order and cannot switch between stop-loss and take-profit modes
37005
This position has at least one trailing stop or trailing stop link order and cannot be switched to take profit and stop loss mode
37006
Conditional or limit orders carry a take profit and stop loss parameter
37007
Insufficient number of positions left to set Stop Loss and Take Profit
37008
Active orders are not allowed to modify the price and quantity when they also modify the trigger price
37009
Activity orders are not allowed to modify the stop-loss and take-profit settings if the order is partially filled
37010
In Full Take Profit Stop Loss mode, it is not allowed to modify the Stop Profit Stop Loss size
37011
In partial SL mode, SL is set to more than 20. Set SL/TP exceeds the limit oldTpNum+oldStNum+newNum=(2 the num is tp+sl)
37012
Stop loss price needs to be greater than base price.
37013
Stop loss price needs to be less than base price.
38101
Replacement of order will result in the breach of user's limit according to open interest.
90063
In the progress of liquidation
90066
In the reconciliation
90067
Reconciliation failed
90016
Rejected by risk control. It may cause liquidation after the transfer.
90015
Insufficient balance