IMPORTANT NOTE: this article is created for educative purposes only. Trading could be very risky and can lead to significant loses.
Introduction
In this article we will introduce the fully functioning python
pipeline for the trading bot implementation using Binance API (on the USDⓈ-M futures market). We will first discuss the framework and prerequisites, then the important API calls and finally the python
code. The framework that we will discuss concentrates on the one asset trading bot, but on the same time it gives opportunities for generalization to multiple assets.
Binance API
Binance, being the largest cryptocurrency exchange, provides extensive API documentation for trading using python
. To initialize API client you should:
Visit the Binance official web page and create an account
Open a futures account
Create an API keys (in the developers tab)
After getting the API keys (public & private) they should be pasted in the python
code on the marked places (see below).
API calls descriptions
Full API documentation is available at official website. In this section we will present the most important for basic usage API calls and their descriptions:
API call | Python implementation | Description |
|
| Get the current server time. |
|
| Get latest price of the symbol (returns dict) |
|
| Get historical prices of the symbol (OHLC and other data) |
|
| Get info about your futures account (including assets balances |
|
| Create order (buy/sell, limit/market) for specified symbol and quantity |
Python implementation
Now we can implement the whole trading bot using python. First of all you should install python package to connect with Binance. The standard package for this purpose is python-binance
, which can be installed using standard pip install python-binance
command.
Next the client should be initialized:
from binance.client import Client
api_key = "<your_api_key>"
api_secret = "<your_private_api_key>"
client = Client(api_key, api_secret)
After the client is being initialized we can to request market data. The simplest and most commonly used data is the candlestick data. After the candlestick data is retrieved from the server it is converted to pandas data frame and types are changed to the appropriate data types.
symbol = "BTCUSDT"
interval = "15m"
start_time = dt.datetime.now() - dt.timedelta(hours=24)
end_time = dt.datetime.now()
# get the kline data from Binance server
klines = client.futures_historical_klines(symbol,
interval,
start_time,
end_time)
# convert the json data to pd.DataFrame
klines_data = pd.DataFrame(klines)
klines_data.columns = ['open_time',
'open',
'high',
'low',
'close',
'volume',
'close_time',
'qav',
'num_trades',
'taker_base_vol',
'taker_quote_vol',
'ignore']
# convert data to appropriate data types
klines_data['close_time'] = [dt.datetime.fromtimestamp(x/1000.0) for x in klines_data["close_time"]
klines_data['open_time'] = [dt.datetime.fromtimestamp(x/1000.0) for x in klines_data["open_time"]
klines_data['close'] = klines_data['close'].astype('float')
klines_data['open'] = klines_data['open'].astype('float')
klines_data['high'] = klines_data['high'].astype('float')
klines_data['low'] = klines_data['low'].astype('float')
After we have the candlestick data for last 24 hours we are ready to make the decisions and open any orders. To open an order the following script could be used:
# to open the market short trade
client.futures_create_order(symbol=symbol,
side='SELL',
type='MARKET',
quantity=quantity)
# to open the market long trade
client.futures_create_order(symbol=symbol,
side='BUY',
type='MARKET',
quantity=quantity)
To close the trade on futures market you need to open the trade in the opposite direction with the same quantity.
Next, you could be interested in the current balance of your account, this information could be obtained via this code:
i = ... # number of asset you want to get balance for
cur_balance = float(client.futures_account()['assets'][i]['walletBalance'])
Now we can present the full code of the very basic trading system, which will open the short trade if the latest price of an asset exceeds 2000$ and open the long trade if the price of an asset falls below 1900$.
Note, that is real-time we do not usually need the Klines
request because it is sometimes sufficient just to know the latest price (in the simplest case just the latest price, but in more natural way: the latest bid/ask prices with volumes, i.e. the order book). This could be done using the following code:
# returns latest price as str
latest_price = client.futures_symbol_ticker(symbol='ETHUSDT')['price']
# convert str to float
latest_price = float(latest_price)
Now we combine everything together:
import time
from datetime import datetime
from binance.client import Client
# exchange operations:
# note that short_open and long_close are exactly the same
# this is due to the fact mentioned above, that closing the trade
# is just opening the trade in other direction with the same qty;
# here we kept both for the convience of understanding
def short_open(symbol, quantity):
client.futures_create_order(symbol=symbol,
side='SELL',
type='MARKET',
quantity=quantity)
def short_close(symbol, quantity):
client.futures_create_order(symbol=symbol,
side='BUY',
type='MARKET',
quantity=quantity)
def long_open(symbol, quantity):
client.futures_create_order(symbol=symbol,
side='BUY',
type='MARKET',
quantity=quantity)
def long_close(symbol, quantity):
client.futures_create_order(symbol=symbol,
side='SELL',
type='MARKET',
quantity=quantity)
# initialize Client with your API keys
api_key = "<your_api_key>"
api_secret = "<your_private_api_key>"
client = Client(api_key, api_secret)
# traded symbol
symbol = "ETHUSDT"
# flags to track the exchanges to avoid duplicated entries
in_short = False
in_long = False
# main loop
while True:
# get latest price for the symbol
latest_price = client.futures_symbol_ticker(symbol=symbol)['price']
latest_price = float(latest_price)
# print latest price with current time
latest_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(latest_time, latest_price)
# check the condition (these conditions could be substitued by any other)
if latest_price > 2000.0:
# if we are in long position, close it
if in_long:
long_close(symbol=symbol, quantity=1)
in_long = False
# if we are not in short position, open it
if not in_short:
short_open(symbol=symbol, quantity=1)
in_short = True
elif latest_price < 1900.0:
# if we are in long position, close it
if not in_long:
long_open(symbol=symbol, quantity=1)
in_long = True
# if we are in short position, close it
if in_short:
short_close(symbol=symbol, quantity=1)
in_short = False
# 1 second sleep
time.sleep(1)
Thank you for reading!