In the previous post we looked at creating market orders on Binance using the {binance}
package. Today we’re going to dig into limit orders.
Market Orders & Limit Orders
What’s the difference between a market order and a limit order? I’m so glad you asked.
In the BTC/USDT chart below the current (or “market”) price is 62110.01. This means that at present 1 BTC costs 62110.01 USDT. The market price is driven by supply and demand. If demand is high (or supply is low) then the market price generally goes up. Conversely, if demand is low (or supply is high) then the market price will usually go down.
A market order is a request to buy or sell an asset at the current market price. A market order will normally be executed immediately. If you order 1 BTC at the market price then this order should immediately by filled at the market price. 🧯 Note: It is not guaranteed to be filled immediately. That depends on liquidity (which we’ll cover in the next post), but in an active market you can be fairly certain that a market order will be filled.
But what if you want to sell at a price higher than the market price? Or buy at a price lower than the market price? Well, then you should make a limit order. With a limit order you specify both the quantity of the asset that you want to buy or sell as well as the desired price. For example, you might make a limit order to buy 1 BTC for 60000 USDT (below the market price) or sell 1 BTC at 65000 USDT (above the market price).
Setup
The setup will be the same as the previous post.
library(binance)
packageVersion("binance")
[1] ‘0.0.4’
We’ll be transacting on the Binance Testnet.
Placing a Limit Order
We’re going to trade ETH/BUSD. First we’ll check on the market price.
market_price_ticker("ETHBUSD")
# A tibble: 1 × 2
symbol price
<chr> <dbl>
1 ETHBUSD 4379.
Suppose we have some ETH and we want to sell at a price of 4400 BUSD per ETH (above the market price).
spot_new_limit_order(symbol = "ETHBUSD", side = "SELL", quantity = 1, price = 4400)
# A tibble: 1 × 11
symbol order_id transact_time price orig_qty exec_qty status time_in_force type side fills
<chr> <int> <dttm> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <list>
1 ETHBUSD 399 2021-11-05 05:05:13 4400 1 0 NEW GTC LIMIT SELL <tibble [0 × 0]>
The status of this order is NEW
and it has not been filled (not even partially). Let’s check the order book (this list of unfilled orders).
market_order_book("ETHBUSD", "sell")
# A tibble: 3 × 3
symbol price qty
<chr> <dbl> <dbl>
2 ETHBUSD 4390 2
3 ETHBUSD 4400 1
There are 2 ETH on offer at a price of 4390 BUSD and our 1 ETH on offer at a price of 4400 BUSD. Our order will not be filled until the market price of ETH shifts up to 4400 BUSD.
Use the spot_open_orders()
function to list our open orders.
spot_open_orders("ETHBUSD")
# A tibble: 3 × 15
symbol order_id price orig_qty executed_qty status time_in_force type side time
<chr> <int> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <dttm>
3 ETHBUSD 399 4400 1 0 NEW GTC LIMIT SELL 2021-11-05 05:05:13
If we are patient then the market price will hopefully move in our direction.
Some time later the order at 4390 BUSD has been filled and our order has been partially filled. This is what the order book looks like:
# A tibble: 1 × 3
symbol price qty
<chr> <dbl> <dbl>
1 ETHBUSD 4400 0.75
Let’s check in on our order using spot_order_query()
.
# A tibble: 1 × 15
symbol order_id price orig_qty executed_qty status time_in_force type side update_time
<chr> <int> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <dttm>
1 ETHBUSD 399 4400 1 0.25 PARTIALLY_FILLED GTC LIMIT SELL 2021-11-05 05:45:58
The status is PARTIALLY_FILLED
because we have not yet sold the full amount we have on offer. The original quantity (orig_qty
) is 1 ETH, of which 0.25 ETH has been filled (the executed quantity, executed_qty
).
A little later still and the order book is empty. We’ll take one last look at our order.
# A tibble: 1 × 15
symbol order_id price orig_qty executed_qty status time_in_force type side update_time
<chr> <int> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <dttm>
1 ETHBUSD 399 4400 1 1 FILLED GTC LIMIT SELL 2021-11-05 05:46:57
The executed quantity is now 1 ETH and the status is FILLED
.
Cancelling a Limit Order
What if you want to cancel a limit order?
Let’s place another order.
spot_new_limit_order(symbol = "ETHBUSD", side = "SELL", quantity = 5, price = 4400)
# A tibble: 1 × 11
symbol order_id transact_time price orig_qty exec_qty status time_in_force type side fills
<chr> <int> <dttm> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <list>
1 ETHBUSD 409 2021-11-05 06:18:39 4400 5 0 NEW GTC LIMIT SELL <tibble [0 × 0]>
Use spot_order_cancel()
to cancel the order, using the order_id
field to identify the order.
spot_order_cancel("ETHBUSD", 409)
# A tibble: 1 × 10
symbol order_id price orig_qty executed_qty status time_in_force type side
<chr> <int> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr>
1 ETHBUSD 409 4400 5 0 CANCELED GTC LIMIT SELL
Order Book
Let’s take a closer look at the order book. To make things more interesting though, we’ll flip over to the Binance Mainnet. Here’s a summary of the orders for a number of symbols. Only the top 100 orders (where “top” means closest to the market price) are listed.
# A tibble: 20 × 4
symbol last_update_id bids asks
<chr> <dbl> <list> <list>
1 BNBBUSD 1766249387 <tibble [100 × 2]> <tibble [100 × 2]>
2 BTCBUSD 6911574714 <tibble [100 × 2]> <tibble [100 × 2]>
3 ETHBUSD 6368992102 <tibble [100 × 2]> <tibble [100 × 2]>
4 LTCBUSD 756494068 <tibble [100 × 2]> <tibble [100 × 2]>
5 TRXBUSD 673935674 <tibble [100 × 2]> <tibble [100 × 2]>
6 XRPBUSD 1124317491 <tibble [100 × 2]> <tibble [100 × 2]>
7 BNBUSDT 5911544226 <tibble [100 × 2]> <tibble [100 × 2]>
8 BTCUSDT 14807883947 <tibble [100 × 2]> <tibble [100 × 2]>
9 ETHUSDT 12256395023 <tibble [100 × 2]> <tibble [100 × 2]>
10 LTCUSDT 4601015676 <tibble [100 × 2]> <tibble [100 × 2]>
11 TRXUSDT 2655288332 <tibble [100 × 2]> <tibble [100 × 2]>
12 XRPUSDT 6576014338 <tibble [100 × 2]> <tibble [100 × 2]>
13 BNBBTC 2303506040 <tibble [100 × 2]> <tibble [100 × 2]>
14 ETHBTC 4424485089 <tibble [100 × 2]> <tibble [100 × 2]>
15 LTCBTC 1487088647 <tibble [100 × 2]> <tibble [100 × 2]>
16 TRXBTC 719114972 <tibble [100 × 2]> <tibble [100 × 2]>
17 XRPBTC 1507425977 <tibble [100 × 2]> <tibble [100 × 2]>
18 LTCBNB 290913789 <tibble [100 × 2]> <tibble [100 × 2]>
19 TRXBNB 269802601 <tibble [100 × 2]> <tibble [100 × 2]>
20 XRPBNB 317863766 <tibble [100 × 2]> <tibble [100 × 2]>
We’ll focus on the orders for ETH/BUSD.
market_price_ticker("ETHBUSD")
order_book <- market_order_book("ETHBUSD", limit = 500) %>%
select(-last_update_id) %>%
pivot_longer(cols = -symbol, names_to = "side") %>%
unnest(cols = value)
# A tibble: 1,000 × 4
symbol side price qty
<chr> <chr> <dbl> <dbl>
1 ETHBUSD bids 4548.34 5.2595
2 ETHBUSD bids 4548.14 0.8011
3 ETHBUSD bids 4548.13 1.75
4 ETHBUSD bids 4548.04 0.1912
5 ETHBUSD bids 4548.01 0.0985
6 ETHBUSD bids 4548 0.4516
7 ETHBUSD bids 4547.81 0.1804
8 ETHBUSD bids 4547.76 0.0194
9 ETHBUSD bids 4547.75 0.0022
10 ETHBUSD bids 4547.74 0.0022
# … with 990 more rows
All those orders are easier to digest as a figure. The histogram below indicates the number of ETH/BUSD orders as a function of price. The market price is given by the vertical dashed line.
Using a plot like this it’s possible to see where the interests of other traders lie.
Conclusion
In this post we’ve used the following functions from {binance}
to explore limit orders:
market_price_ticker()
— retrieve market price for specific pairmarket_order_book()
— retrieve pending orders for specific pairspot_new_limit_order()
— create a new limit orderspot_open_orders()
— list open ordersspot_order_query()
— query an order andspot_order_cancel()
— cancel an order.