- Saved searches
- Use saved searches to filter your results more quickly
- License
- JesseCorrington/binance-api-python
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- Exploring the Binance API in Python — Part I: The Order Book
- Top of the book
- Scatter plot
- Histogram plot
- Weighted histogram plot
- Weighted empirical CDF (ECDF) plot – aka the “Depth Chart”
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
License
JesseCorrington/binance-api-python
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
A python wrapper for the Binance API. It supports all public endpoints, signed endpoints, and websocket data streams. All numeric types returned from the API are converted to Decimal, to prevent floating point innacuracies, since we’re dealing with financial data.
Simply copy binance.py into your project and import it. You will also need to install the websockets library. Python 3.6 or newer is required.
These don’t require setting up your API key and are all static methods
import binance binance.enable_logging(True) binance.enable_logging(False)
Ping Binance.com to see if it’s online
Get the order book for a specific symbol
order_book = binance.order_book("BNBBTC", 5) print(order_book)
OrderBook(bids=[(Decimal('0.00020759'), Decimal('97.00000000')), (Decimal('0.00020750'), Decimal('550.00000000')), (Decimal('0.00020702'), Decimal('50.00000000')), (Decimal('0.00020677'), Decimal('64.00000000')), (Decimal('0.00020669'), Decimal('5.00000000'))], asks=[(Decimal('0.00020799'), Decimal('1200.00000000')), (Decimal('0.00020800'), Decimal('10055.00000000')), (Decimal('0.00021083'), Decimal('5141.00000000')), (Decimal('0.00021084'), Decimal('7.00000000')), (Decimal('0.00021297'), Decimal('836.00000000'))])
trades = binance.aggregate_trades("BNBBTC", limit=5) print(trades)
['a': 1367857, 'p': Decimal('0.00020752'), 'q': Decimal('76.00000000'), 'f': 1501629, 'l': 1501629, 'T': 1508527146843, 'm': True, 'M': True>, 'a': 1367858, 'p': Decimal('0.00020795'), 'q': Decimal('16.00000000'), 'f': 1501630, 'l': 1501630, 'T': 1508527182319, 'm': False, 'M': True>, 'a': 1367859, .
candles = binance.candlesticks("BNBBTC", "1m") print(candles)
[CandleStick(open_time=1508497320000, open=Decimal('0.00022551'), high=Decimal('0.00022551'), low=Decimal('0.00022551'), close=Decimal('0.00022551'), volume=Decimal('14.00000000'), close_time=1508497379999, quote_asset_volume=Decimal('0.00315714'), trade_count=1, taker_buy_base_quote_vol=Decimal('0E-8'), taker_buy_quote_asset_vol=Decimal('0E-8')), CandleStick(open_time=1508497380000.
Get current prices for all markets
prices = binance.ticker_prices() print(prices)
'ETHBTC': Decimal('0.05129400'), 'LTCBTC': Decimal('0.01019000'), 'BNBBTC': Decimal('0.00020800'), 'NEOBTC': Decimal('0.00474300').
Get the top order book entry for all markets
order_books = binance.ticker_order_books() print(order_books["ETHBTC"])
OrderBookTicker(bid_price=Decimal('0.05104700'), bid_qty=Decimal('10.00000000'), ask_price=Decimal('0.05135500'), ask_qty=Decimal('15.00000000'))>
Get the 24 hour price change statistics for a specific symbol
last_24hr = binance.ticker_24hr("BNBBTC") print(last_24hr)
'priceChange': Decimal('-0.00001848'), 'priceChangePercent': Decimal('-8.177'), 'weightedAvgPrice': Decimal('0.00022479'), 'prevClosePrice': Decimal('0.00022600'), 'lastPrice': Decimal('0.00020752'), 'lastQty': Decimal('81.00000000'), 'bidPrice': Decimal('0.00020751'), 'bidQty': Decimal('267.00000000'), 'askPrice': Decimal('0.00020798'), 'askQty': Decimal('315.00000000'), 'openPrice': Decimal('0.00022600'), 'highPrice': Decimal('0.00023987'), 'lowPrice': Decimal('0.00020750'), 'volume': Decimal('1098837.00000000'), 'quoteVolume': Decimal('247.01269419'), 'openTime': 1508441273823, 'closeTime': 1508527673823, 'firstId': 1494258, 'lastId': 1501663, 'count': 7406>
These require using an API key and API secret for authentication. If you don’t have a key, log into binance.com and create one here. Be sure to never commit your keys to source control.
Create a new account object
The account object is how you access all the signed enpoints
Set the receive window for all signed requests
This is the number of milliseconds a request must be processed within before being rejected by the server. If not set, the default is 5000 ms
account.set_receive_window(3000)
# a buy limit order account.new_order("ETHBTC", "BUY", "LIMIT", 0.0513605, 4) # or a sell limit order account.new_order("ETHBTC", "SELL", "LIMIT", 0.0513605, 4)
# a buy market order account.new_order("ETHBTC", "BUY", "MARKET", 4) # or a sell market order account.new_order("ETHBTC", "SELL", "MARKET", 4)
account.query_order("ETHBTC", order-id>)
account.cancel_order("ETHBTC", order-id>)
Get all open orders for a given symbol
Get all account orders; active, canceled, or filled
Get your account info, including balances for all symbols
info = account.account_info()
Get trades for a specific account and symbol
trades = account.my_trades("ETHBTC")
In addition to the requests above for getting market data, you can also stream the order books, candlesticks, and aggregated trades.
You just need to create a single stream object, and then you can add ass many data sources to it as you need.
stream = binance.BinanceStream()
Open the user data stream
After it’s open, it will automatically send a keep alive request every 30 seconds.
def on_user_data(data): print("new user data: ", data) stream.start_user("", on_user_data)
Close the user data stream
Add an order book data stream
def on_order_book(data): print("order book update - ", data) stream.add_order_book("ETHBTC", on_order_book)
Add a candlestick data stream
def on_candlestick(data): print("candlestick update - ", data) stream.add_candlesticks("ETHBTC", "1m", on_candlestick)
def on_trades(data): print("trade update - ", data) stream.add_trades("ETHBTC", on_trades)
Remove an order book data stream
stream.remove_order_book("ETHBTC")
Remove a candlestick data stream
stream.remove_candlesticks("ETHBTC", "1m")
Remove a trade data stream
stream.remove_trades("ETHBTC")
Exploring the Binance API in Python — Part I: The Order Book
In this post, we will explore the live order book data on Binance through its official API using Python.
We directly interact with the API endpoints and explicitly make the low-level HTTP requests ourselves. If you’re just looking for a high-level way to interact with the API endpoints that abstracts away these details please check out python-binance, an unofficial, but slick and well-designed Python Client for the Binance API.
We will be making the requests using the requests library. Thereafter, we will process the results with pandas, and visualize them with matplotlib and seaborn. Let’s import these dependencies now:
To make a GET request for the symbol ETHBUSD from the /depth endpoint:
Load the buy and sell orders, or bids and asks, into respective DataFrames:
Concatenate the DataFrames containing bids and asks into one big frame:
Get a statistical summary of the price levels in the bids and asks:
side count mean std min 25% 50% 75% max asks 100 1057.86 0.696146 1056.64 1057.2 1057.91 1058.49 1059.04 bids 100 1055.06 0.832385 1053.7 1054.4 1054.85 1055.82 1056.58
Note that the Binance API only provides the lowest 100 asks and the highest 100 bids (see the count column).
Top of the book
The prices of the most recent trades will be somewhere between the maximum bid price and the minimum asking price. This is known as the top of the book. The difference between these two price levels is known as the bid-ask spread.
We can also get this information from the /ticker/bookTicker endpoint:
Read this into a Pandas Series and render as a Markdown table:
ETHBUSD bidPrice 1056.58 bidQty 7.555 askPrice 1056.64 askQty 7.43152
Scatter plot
Let us visualize all the order book entries using a scatter plot, showing price along the $x$-axis, and quantity along the $y$-axis. The hue signifies whether the entry is an “ask” or a “bid”.
This is the most verbose visualization, displaying all the raw information, but perhaps also providing the least amount of actionable insights.
Histogram plot
We can compress this information into a histogram plot.
This shows the number of bids or asks at specific price points, but obscures the volume (or quantity).
This is obviously misleading. For example, there could be 1 bid at price $p_1$ and and 100 bids at $p_2$. However, the 1 bid at price $p_1$ could be for 100 ETH, while each of those 100 bids at $p_2$ could be for just 1 ETH. At both price points, the total quantity of ETH being bid is in fact identical. Yet this plot would suggest that there is 100 times greater demand for ETH at $p_2$.
Weighted histogram plot
This is easy to fix, simply by weighting each entry by the quantity. This just amounts to setting weights=»quantity» :
This paints a more accurate picture about supply-and-demand, but still offers limited actionable insights.
Weighted empirical CDF (ECDF) plot – aka the “Depth Chart”
Now we finally arrive at the depth chart, which is a popular visualization that is ubiquitous across exchanges and trading platforms. The depth chart is essentially just a combination of two empirical cumulative distribution function (CDF), or ECDF, plots.
More precisely, they are weighted and unnormalized ECDF plots. As before, they are weighted by the quantity and are unnormalized in the sense that they are not proportions between $[0, 1]$. Rather, they are simply kept as counts. Additionally, in the case of bids, we take the complementary ECDF (which basically reverses the order in which the cumulative sum is taken).
In code, this amounts to making calls to sns.ecdfplot with the options weights=»quantity» (self-explanatory) and stat=»count» (to keep the plot unnormalized). Finally, for the bids, we add the option complementary=True . Putting it all together:
To receive updates on more posts like this, follow me on Twitter and GitHub!
Louis Tiao
Machine Learning Researcher (PhD Candidate)
Thanks for stopping by! Let’s connect – drop me a message or follow me
© 2023 Louis C Tiao. This work is licensed under CC BY NC ND 4.0
Published with Wowchemy — the free, open source website builder that empowers creators.