Pull to refresh

Trade bot python setup (using Binance API), Vol 1

Level of difficulty Medium
Reading time 5 min
Views 3.9K

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:

  1. Visit the Binance official web page and create an account

  2. Open a futures account

  3. 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 /fapi/v1/time

client.get_server_time()

Get the current server time.

GET /fapi/v1/ticker/bookTicker

client.futures_symbol_ticker()

Get latest price of the symbol (returns dict)

GET /fapi/v1/klines

client.futures_historical_klines()

Get historical prices of the symbol (OHLC and other data)

GET /fapi/v2/account

client.futures_account()

Get info about your futures account (including assets balances

POST /fapi/v1/order

client.futures_create_order()

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!

Tags:
Hubs:
+1
Comments 0
Comments Leave a comment

Articles