The previous two articles covered API creation and data retrieval, and now we move on to the trading section. If any of you reading this haven't registered on Binance yet, you can use my referral link to register and get fee discounts (which allows me to earn a little commission as encouragement, haha😘): https://accounts.binance.com/register?ref=DPVSZVI3
Here, we are using the Binance API interface encapsulated in Python's ccxt
library as an example. In the previous chapter, we installed and instantiated the exchange class exchange
. If you are still unsure how to do this, you can refer back to the last article.
1. Spot Account vs. Futures Account#
In the previous section, when we instantiated the exchange class, we mentioned that the optional parameter options
specified defaultType
as future
, which means the futures account:
exchange = ccxt.binance({
'apiKey': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'secret': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'timeout': 30000,
'enableRateLimit': True,
'options': {'defaultType': 'future'}
})
The apiKey and secret here need to be replaced with the values from the API you created. If you don't understand the other parameters, you can refer back to the previous chapter.
If you want to instantiate a spot account, you need to specify defaultType
as spot
:
exchange = ccxt.binance({
'apiKey': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'secret': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'timeout': 30000,
'enableRateLimit': True,
'options': {'defaultType': 'spot'}
})
2. Limit Orders#
The limit order for spot trading uses the same function as for futures, but for futures, you also need to specify the leverage. After discussing market and limit orders, we will explain how to set leverage.
exchange.create_limit_buy_order(symbol='JUP/USDT', amount=6, price=0.9)
It's easy to see the meaning of the parameters:
symbol
is the trading pair symbolamount
is the quantity to buy (this quantity is not the amount of USDT spent, but the number of coins you are buying; for example, here I am buying 6 JUP, and the same applies for selling)price
is the order price
Similarly, the function for selling is create_limit_sell_order()
, with the same parameter meanings as above.
When using these functions, you need to have sufficient funds in your account, and in the case of not just reducing positions, the trading amount must be greater than 5 USDT; otherwise, the error code will be as follows:
root@vultr:~/transaction/main# python3 test.py JUP/USDT
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/exchange.py", line 629, in fetch
response.raise_for_status()
File "/usr/lib/python3/dist-packages/requests/models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.binance.com/api/v3/orderDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/transaction/main/test.py", line 247, in
exchange.create_limit_buy_order(COIN, 6, 0.9)
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/exchange.py", line 4493, in create_limit_buy_order
return self.create_order(symbol, 'limit', 'buy', amount, price, params)
File "/usr/local/lib/python3.10/dist-packages/ccxt/binance.py", line 5554, in create_order
response = self.privatePostOrder(request)
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/types.py", line 35, in unbound_method
return _self.request(self.path, self.api, self.method, params, config=self.config)
File "/usr/local/lib/python3.10/dist-packages/ccxt/binance.py", line 10280, in request
response = self.fetch2(path, api, method, params, headers, body, config)
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/exchange.py", line 3643, in fetch2
return self.fetch(request['url'], request['method'], request['headers'], request['body'])
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/exchange.py", line 645, in fetch
skip_further_error_handling = self.handle_errors(http_status_code, http_status_text, url, method, headers, http_response, json_response, request_headers, request_body)
File "/usr/local/lib/python3.10/dist-packages/ccxt/binance.py", line 10224, in handle_errors
self.throw_exactly_matched_exception(self.exceptions['exact'], message, self.id + ' ' + message)
File "/usr/local/lib/python3.10/dist-packages/ccxt/base/exchange.py", line 4013, in throw_exactly_matched_exception
raise exactstring
ccxt.base.errors.InsufficientFunds: binance Account has insufficient balance for requested action.
Normally, after running the above limit buy code, you can check the corresponding order in spot trading. You can set a smaller order price for testing:
3. Market Orders#
The market order for spot and futures trading uses the same function.
exchange.create_market_buy_order(symbol='BTC/USDT', amount=0.01)
You only need to specify two parameters:
symbol
is the trading pair symbolamount
is the quantity to trade
Market orders do not require a specified price. If the account balance is sufficient, executing this function will immediately buy the corresponding amount of position, so we will not demonstrate it here.
Similarly, the selling function is create_market_sell_order()
, with the same parameters as above.
4. Creating Orders#
The two functions above are used for specific orders and directions, but in fact, one function can handle everything.
def create_order(
symbol: str,
type: OrderType,
side: OrderSide,
amount: float,
price: float = None,
params: Any = {}
) -> Order
There are two additional parameters, type
and side
:
type
is the order type, which can be marketmarket
or limitlimit
side
is the direction, which can be buybuy
or sellsell
price
defaults toNone
, because if it is a market order, the price does not need to be specified
Therefore, the initial limit buy of JUP can be written as follows:
exchange.create_order('JUP/USDT', 'limit', 'buy', 6, 0.9)
In addition, there are functions like create_market_order()
and create_limit_order()
, etc. From the explanations above, you should be able to tell what these functions do just by their names.
5. Setting Futures Leverage#
When trading with a futures account, if you do not specify the leverage, it will default to the leverage you last set in the graphical interface. If you need to set it, you should use set_leverage()
, which has two parameters: symbol
and leverage
, which are the trading pair symbol and the leverage (int type).
Therefore, it is best to always add set_leverage()
to set the leverage before opening a futures position:
exchange.set_leverage(10, 'JUP/USDT')
exchange.create_order('JUP/USDT', 'limit', 'buy', 6, 0.9)