{"id":363870,"date":"2024-05-21T02:05:19","date_gmt":"2024-05-21T02:05:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=363870"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=363870","title":{"rendered":"<span>Trade bot python setup (using Binance API), Vol 1<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong>IMPORTANT NOTE:<\/strong> this article is created for <strong>educative purposes only<\/strong>. Trading could be <strong>very risky<\/strong> and can lead to <strong>significant loses<\/strong>.<\/p>\n<h2>Introduction<\/h2>\n<p>In this article we will introduce the fully functioning <code>python<\/code> pipeline for the <strong>trading bot<\/strong> implementation using <strong>Binance API <\/strong>(on the USD\u24c8-M futures market). We will first discuss the framework and prerequisites, then the important API calls and finally the <code>python<\/code> 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.<\/p>\n<h2>Binance API<\/h2>\n<p>Binance, being the largest cryptocurrency exchange, provides extensive API documentation for trading using <code>python<\/code>. To initialize API client you should:<\/p>\n<ol>\n<li>\n<p>Visit the Binance official web page and create an account<\/p>\n<\/li>\n<li>\n<p>Open a futures account<\/p>\n<\/li>\n<li>\n<p>Create an API keys (in the developers tab)<\/p>\n<\/li>\n<\/ol>\n<p>After getting the API keys (public &amp; private) they should be pasted in the <code>python<\/code> code on the marked places (see below).<\/p>\n<h2>API calls descriptions<\/h2>\n<p>Full API documentation is available at <a href=\"https:\/\/binance-docs.github.io\/apidocs\/spot\/en\/#change-log\" rel=\"noopener noreferrer nofollow\">official website<\/a>. In this section we will present the most important for basic usage API calls and their descriptions:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><strong>API call<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><strong>Python implementation<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Description<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/time<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.get_server_time()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get the current server time.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/ticker\/bookTicker<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_symbol_ticker()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get latest price of the symbol (returns dict)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/klines<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_historical_klines()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get historical prices of the symbol (OHLC and other data)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v2\/account<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_account()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get info about your futures account (including assets balances<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>POST \/fapi\/v1\/order<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_create_order()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Create order (buy\/sell, limit\/market) for specified symbol and quantity<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>Python implementation<\/h2>\n<p>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 <code>python-binance<\/code>, which can be installed using standard <code>pip install python-binance<\/code> command.<\/p>\n<p>Next the <strong>client<\/strong> should be initialized:<\/p>\n<pre><code class=\"python\">from binance.client import Client  api_key = \"&lt;your_api_key>\" api_secret = \"&lt;your_private_api_key>\" client = Client(api_key,  api_secret)<\/code><\/pre>\n<p>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.<\/p>\n<pre><code class=\"python\">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')<\/code><\/pre>\n<p>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:<\/p>\n<pre><code class=\"python\"># 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)<\/code><\/pre>\n<p>To close the trade on <strong>futures market<\/strong> you need to open the trade in the opposite direction with the same quantity.<\/p>\n<p>Next, you could be interested in the current balance of your account, this information could be obtained via this code:<\/p>\n<pre><code class=\"python\">i = ... # number of asset you want to get balance for cur_balance = float(client.futures_account()['assets'][i]['walletBalance'])<\/code><\/pre>\n<p>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$.<\/p>\n<p>Note, that is <strong>real-time<\/strong> we do not usually need the <code>Klines<\/code> 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 <em>bid\/ask<\/em> prices with volumes, i.e. the order book). This could be done using the following code:<\/p>\n<pre><code class=\"python\"># returns latest price as str latest_price = client.futures_symbol_ticker(symbol='ETHUSDT')['price'] # convert str to float latest_price = float(latest_price)<\/code><\/pre>\n<p>Now we combine everything together:<\/p>\n<pre><code class=\"python\">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 = \"&lt;your_api_key>\" api_secret = \"&lt;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 &lt; 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)<\/code><\/pre>\n<p>Thank you for reading!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/782892\/\"> https:\/\/habr.com\/ru\/articles\/782892\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong>IMPORTANT NOTE:<\/strong> this article is created for <strong>educative purposes only<\/strong>. Trading could be <strong>very risky<\/strong> and can lead to <strong>significant loses<\/strong>.<\/p>\n<h2>Introduction<\/h2>\n<p>In this article we will introduce the fully functioning <code>python<\/code> pipeline for the <strong>trading bot<\/strong> implementation using <strong>Binance API <\/strong>(on the USD\u24c8-M futures market). We will first discuss the framework and prerequisites, then the important API calls and finally the <code>python<\/code> 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.<\/p>\n<h2>Binance API<\/h2>\n<p>Binance, being the largest cryptocurrency exchange, provides extensive API documentation for trading using <code>python<\/code>. To initialize API client you should:<\/p>\n<ol>\n<li>\n<p>Visit the Binance official web page and create an account<\/p>\n<\/li>\n<li>\n<p>Open a futures account<\/p>\n<\/li>\n<li>\n<p>Create an API keys (in the developers tab)<\/p>\n<\/li>\n<\/ol>\n<p>After getting the API keys (public &amp; private) they should be pasted in the <code>python<\/code> code on the marked places (see below).<\/p>\n<h2>API calls descriptions<\/h2>\n<p>Full API documentation is available at <a href=\"https:\/\/binance-docs.github.io\/apidocs\/spot\/en\/#change-log\" rel=\"noopener noreferrer nofollow\">official website<\/a>. In this section we will present the most important for basic usage API calls and their descriptions:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><strong>API call<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><strong>Python implementation<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Description<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/time<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.get_server_time()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get the current server time.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/ticker\/bookTicker<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_symbol_ticker()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get latest price of the symbol (returns dict)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v1\/klines<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_historical_klines()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get historical prices of the symbol (OHLC and other data)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>GET \/fapi\/v2\/account<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_account()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Get info about your futures account (including assets balances<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"235\" width=\"235\">\n<p align=\"left\"><code>POST \/fapi\/v1\/order<\/code><\/p>\n<\/td>\n<td data-colwidth=\"264\" width=\"264\">\n<p align=\"left\"><code>client.futures_create_order()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Create order (buy\/sell, limit\/market) for specified symbol and quantity<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>Python implementation<\/h2>\n<p>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 <code>python-binance<\/code>, which can be installed using standard <code>pip install python-binance<\/code> command.<\/p>\n<p>Next the <strong>client<\/strong> should be initialized:<\/p>\n<pre><code class=\"python\">from binance.client import Client  api_key = \"&lt;your_api_key>\" api_secret = \"&lt;your_private_api_key>\" client = Client(api_key,  api_secret)<\/code><\/pre>\n<p>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.<\/p>\n<pre><code class=\"python\">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')<\/code><\/pre>\n<p>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:<\/p>\n<pre><code class=\"python\"># 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)<\/code><\/pre>\n<p>To close the trade on <strong>futures market<\/strong> you need to open the trade in the opposite direction with the same quantity.<\/p>\n<p>Next, you could be interested in the current balance of your account, this information could be obtained via this code:<\/p>\n<pre><code class=\"python\">i = ... # number of asset you want to get balance for cur_balance = float(client.futures_account()['assets'][i]['walletBalance'])<\/code><\/pre>\n<p>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$.<\/p>\n<p>Note, that is <strong>real-time<\/strong> we do not usually need the <code>Klines<\/code> 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 <em>bid\/ask<\/em> prices with volumes, i.e. the order book). This could be done using the following code:<\/p>\n<pre><code class=\"python\"># returns latest price as str latest_price = client.futures_symbol_ticker(symbol='ETHUSDT')['price'] # convert str to float latest_price = float(latest_price)<\/code><\/pre>\n<p>Now we combine everything together:<\/p>\n<pre><code class=\"python\">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 = \"&lt;your_api_key>\" api_secret = \"&lt;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 &lt; 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)<\/code><\/pre>\n<p>Thank you for reading!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/782892\/\"> https:\/\/habr.com\/ru\/articles\/782892\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-363870","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=363870"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363870\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=363870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=363870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=363870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}