How to code a Binance crypto trading bot that trades based on daily news sentiment

News are the talk of the day, or more specifically building a Binance trading bot that buys or sells based on news sentiment. The cryptocurrency market is still quite young compared to the stock market, and therefore news are especially influential in the crypto world.

I’m not sure about you, but I panic sold a few times, as well as hype-bought – a strategy also known as Buy High Sell Low. Me building and testing crypto bots is a rational response to my emotional trading tactics. I have made good manual trades though believe it or not, and this blog is about taking the best strategies that I have tested, read or thought about and turn them into efficient crypto trading bots. 

In the previous blog, we covered how to analyse the daily crypto news sentiment by surfing the web in search of articles that match our keywords, and today we’re going to use that strategy in order to create a fully functional Python crypto trading bot for Binance. 

Just a note here though, during the building and testing of this bot, I realised that the two APIs used in the last article don’t really fit so well in the scope of this bot so I have opted for a slightly different, more robust solution, and I ended up rewriting most of the code from the previous blog post.

Parameters and prerequisites of our Binance trading bot

Let’s clearly define what the bot will do and what you’re going to need to complete this project. 

The bot will:

  • pull and analyse the last headline from the top 100 crypto news sites
  • provide an overview on the most mentioned coin across all the headlines
  • analyse the sentiment of each headline and categorise the output by coin
  • Place a Buy order if the compound sentiment is positive and there are at least 10 articles mentioning a particular coin

This is just a general overview, I will go through each of the points in more detail as we make our way through the code

You will need:

  • a Binance account
  • a GitHub account
  • Binance Testnet API keys
  • a few python libraries
  • some knowledge of Python

Generating Binance Testnet keys

With all of that out of the way, the first thing you’ll want to do is generate an API key and and API secret for the Binance Testnet. The Testnet allows you to test your bot in a safe environment and without having to use real cryptocurrency. Later on if you’re happy with your testing and would like to use it one live account you will simply replace the testnet keys with the mainnet ones.

If  you don’t have a Binance account go ahead and create one. Use my referral link to claim 5% of your transaction fees back. After you have created your Binance account you will need to go over to testnet.binance.vision in order to create a testnet account.

 

 

Click on Log In with GitHub and authenticate with your GitHub account, or start by creating a GitHub account if you don’t have one. After logging in, click on Generate HMAC_SHA256 Key.

 

 

Give your key a description and click Generate.

 

 

Now it’s important that you SAVE your API Key and Secret displayed as for security reasons, this is the only time you will be able to see them. Simply regenerate the keys if you haven’t saved them.

The code

Initial set up

If you don’t already have Python installed on your machine, head over to python.org and select a version compatible with your operating system. After Python has been installed on your computer, open up your cmd or terminal to install Pypi – this will allow you to download the Python modules that we need in order to set your Binance bot up.

Install Pip on Windows

Simply run the following command in Windows to install the pip installer

Install Pip on Mac

To install the pip installer on mac you’ll need to run both commands below. Make sure to replace python3.x with the version of Python that you have installed.

Install Pip on Linux (debian/ubuntu)

Install modules with Pip

That’s it, we’re now only one step away from pure Python joy, the last set-up step is to install the required modules using the pip installer. So, in your cmd or terminal, run the following commands. On Mac, you may need to replace pip with pip3like so: pip3 install requests.

Importing modules

A few modules are needed in order to achieve the desired functionality. I have included comments above each import so you can understand what they do and why they’re needed, but for now simply copy this into your Python compiler. If you don’t have a compiler, I recommend Atom.

Connecting to the Binance Testnet

It’s time to use our API key and secret to connect to the Binance Testnet, so that we can place trades and view the trade history. In order to keep my API keys private, I have created environment variables in my OS and I’m calling them below using the os.getenv() function. If you’re not planning to share the code  and anonymize your keys, simply input your keys as a string: api_key = ‘YOUR_API_KEY’

Creating user input variables

With the connection to the Binance testnet, it’s time to define user-configurable variables for you Binance trading bot. These can be edited without too much technical skills and pose little risk of breaking the code. 

  • keywords represent the coins you want the Bot to look for in each article headline
  • QUANTITY represents the amount to buy, by default in USDT
  • PAIRING allows you to change the pairing for example from BTCUSD to BTCBNB – If you do choose BNB as the paired coin, make sure to adjust the Quantity as 100 BNB is a lot more than 100 USDT.
  • SENTIMENT_THRESHOLD represents a compound value of positive, negative and neutral sentiments for each headline. Adjust this depending on how you want the bot to trade. A smaller value means that the average headline sentiment doesn’t have to be overwhelmingly positive in order to place a trade.
  • MINUMUM_ARTICLES determines the minimum amount of mentions for a coin across all headlines in order to trigger a trade. This is to ensure we get an accurate sentiment reading by analysing multiple headlines.
  • REPEAT_EVERY tells your Binance bot how often to run, check for news and decide whether to trade or not.

Connecting to a Binance websocket

In order to keep track of the current price, we need to get this from Binance. It can be done with the REST api as a request, or preferably through a websocket. Websockets stream live data to your code, so you don’t have to call them every time you need to get the live price for a coin. 

The live price for each of our coins defined in keywords will live in CURRENT_PRICE under their own dictionary. So if you want to access the current price of bitcoin you would use CURRENT_PRICE[‘BTCUSDT’].

Calculate trading volume

By default, Binance will expect you to input the volume of your trade in the coin that you’re trading on. So for example, if you’re trading BTCUSDT, the Binance API expects the volume to be in BTC. This is tricky when you work with multiple coins and can lead to uncontrolled spend. The next function will help you to convert from your QUANTITY variable USDT to BTC. 

Import a list of crypto sites

I have used Feedspot’s top 100 Cryptocurrency blogs as news sources to be scraped – or so I thought. I actually ended up using Feedspot’s top 100 Bitcoin RSS Feeds, so right now there is some bias towards bitcoin. Luckily it’s easy to add more sources to the list as they are saved in a CSV file. 

Returning the last headline for each news source

The next function will return the latest headline in a dictionary format. It’s currently iterating through every rss feed one by one in a for loop. The operation takes about 2 minutes to complete. This can be improved by enabling multiprocessing, so I will probably update this in a future version.

Categorising the headlines

Now that all the headlines are returned, we need to organise them in their own dictionary, based on the keywords found. So every time a headline matches one of the keywords in our keywords variable, that headline will be appended to a dictionary that looks like this: categorised_headlines[BTC] = [‘Headline 1’, ‘headline 2’, ‘headline 3’].

Determining the sentiment

The first function will analyse the sentiment of each headline, while the second one will categorise the results in a dictionary for each coin that was mentioned at least once in the headlines. The sentiment is analysed by using the Sentiment Intensity Analyser in the nltk module – a great Python library for neuro-linguistic analysis. You may have to run nltk.download() in your Python compiler once, otherwise you might get an error.

Calculating the average compound sentiment

Now that you’ve returned and compiled each result based on the coin keyword found, it’s time we crunch the numbers for each coin. We’re going to use numpy in order to automatically calculate the mean from all the values in our lists. So instead of having an array with multiple compound values, for each coin we will only have an average of all these values. We’re also going to return the number of headlines analysed so that our Binance bot knows how many headlines were taken into the calculation of the average. 

Buy logic and request

This is it, we now have the headlines, the sentiment, the price and the coins we’re looking for. All we need to do now is check that the compound_sentiment is over the threshold that we have defined, and that the number of articles is higher than 10. If those two conditions match, we create and send a trading request to the Binance API.

If an order has been successful, the Binance bot will confirm in a message that says: “Order 1234 has been placed on BTCUSDT with 0.0012500 at 17/04/2021 and bought at 62,500”. There is currently no logging apart from what is stored on Binance, in the future all the information could be stored in a CSV file.

Putting it all together

You did it. You followed along through over 300 lines of code and now you have a working Binance trading bot that places Buy positions based on analysed news sentiment. All you need to do now, is ensure the code will execute at a pre-defined interval. By default the script will run once every hour, you can change the frequency in the REPEAT_EVERY variable. If you’re using Atom to compile your code you can Run it by pressing Ctrl+Shift+B, other compilers will have different shortcuts.

Considerations

  • The list of articles can be improved to make it less biased
  • Multiprocessing would help improve the performance
  • The default compound threshold seems to be quite high in order to place any trades, experiment with the value of the SENTIMENT_THRESHOLD

Did you enjoy this article? Please consider subscribing to the newsletter for more awesome content.

Want to support me more? You can contribute by donating here, or via the Brave Browser. Thank you!

 

42 thoughts on “How to code a Binance crypto trading bot that trades based on daily news sentiment

  1. Hi,

    Thank you for your article, it is very interesting! Would it be possible to have the code you used to scrape and generate the ‘Crypto feeds.csv’ file? Otherwise, I did not to manage to run the code.

    Thank you in advance!

    1. Hi there, glad that you find it interesting. I don’t think I ever saved that script, but if you go to the GitHub repo linked at the end of the article you can download the whole package.

      1. Hi! I have another question, I keep getting the following error when running the code:
        “RuntimeError: asyncio.run() cannot be called from a running event loop”

        I looked on several forums and tried different ways but did not manage to resolve it. I ran it on both Jupyter notebook and Spyder, but keep on having the same error message. Do you know how I can fix this please?

  2. Thank you very much for providing this! I have got everything in order (I think), but when I run the script, I get the following error message:

    Traceback (most recent call last):
    File “C:\Users\*******\*******\Binance Bot\BinanceNewsBot.py”, line 124, in
    with open(‘Crypto feeds.csv’) as csv_file:
    FileNotFoundError: [Errno 2] No such file or directory: ‘Crypto feeds.csv’

    The csv file is in the specified folder, so I don’t know why it can’t find it?? Any ideas would be greatly appreciated.

    1. oh I had that as well at some point. I don’t have a clear reason why, but deleting the csv file and pasting it in the folder once again did the trick for me.

      1. Thanks for the speedy reply! I tried deleting and pasting, but still getting the same error.

        I’ve tried renaming the file with the .csv, I tried making it open with Atom by default, nothing works. Can I add the crypto feeds directly into the code instead of referring to the csv?

          1. OK, so I decided to start with a fresh install and it worked 100%. I just had to add the vader library.

            I see the new version has a mechanism to stop buying the same stock if there is already a non-zero balance of that coin. Is there a way to make it buy the dip, instead of not buying? So, if the previous-bought price is higher than the current price, but the sentiment is still positive, it buys again?

  3. If it helps with my previous comment I get the following error when I install phython-binance:

    ERROR: Package u’aiohttp’ requires a different Python: 2.7.16 not in ‘>=3.4.2’

    1. Hi there, looks like you may have upgrade your version of Python. Try and upgrade to 3.9 and see if you’re getting that error still ๐Ÿ™‚

  4. Thanks for the article its really interesting I’m trying to test it out but for some reason I get a syntax error on the get_feed function after running it for the first time I downloaded the package from GitHub to make sure I got it right but still the same thing.

      1. This is the error I am getting

        text = await response.text()
        ^
        SyntaxError: invalid syntax

        I’m using atom to compile the script, its weird. Do you happen to have any additional packages installed?

        1. That’s an odd one. Can’t seem to replicate your issue. Have you installed all of the below requirements?

          nltk==3.6.1 + vader_lexicon
          numpy==1.20.2
          python-binance==0.7.10
          requests==2.25.1
          aiohttp==3.7.4

          1. Yeah I installed all of them multiple times just to be sure, Its a weird issue

  5. Hi Andrei,

    I get this error while executing the bot, any help?
    binance.exceptions.BinanceAPIException: APIError(code=-1013): Filter failure: MIN_NOTIONAL

    Thanks.

    1. It appears that python-binance have changed the name and the way websockets work in the latest version. The script was built for version 0.7.9 initially. Version 1.0.7 is no longer compatible, but I will update the script to use the new format.

      1. Thanks for this article Andrei. This is some amazing stuff. I’m fairly new to Python/Coding, but wanted to understand is there a way to revert to 0.7.9? or are we stuck for the time being until a fix is created?

  6. HI do you maybe know why such call returns None ? : client.get_symbol_info(“DOGEBTC”)
    same situation with other options “DOGEUSDT” and for other pairs on testnet.

  7. Amazing!

    thanks for the long post, that seems super interesting

    Is there a way to check the bot results/performance ?

  8. Hi Andrei… I’m in need of some help, I’m getting this error:

    Traceback (most recent call last):
    File “BinanceMoonings.py”, line 27, in
    api_key_test = xxxxxxxx
    NameError: name ‘xxxxxxxx’ is not defined

  9. Hey it was working great yesterday great project. Today however it seems to run for the configured 5 mins before it buys up coins. After that process itll buy them and crash without sending any data to the coins json. Any attempt to re open without a restart causes immediate closing of the CMD prompt. The only part of the error I can read before it closes is something regarding a traceback. Thanks for any help.

    1. Are you able to run the code in a Python compiler, like Atom for example? You would get more details into the error taking place

  10. Hi Andrei,
    this is a great idea!
    Unfortunately I’m stuck on the install modules section and I get the following error:

    Traceback (most recent call last):
    File “C:\Users\Hassan\OneDrive\Documents\1.Documents\1.Personal\Finances\crypto\Binance\News Bot\import modules”, line 29, in
    from binance.websockets import BinanceSocketManager
    ModuleNotFoundError: No module named ‘binance.websockets’

    Any help would be appreciated!
    Thanks,

    1. The python-binance module has changed the way websockets work. In order for the script to work you need python-binance 0.7.9 while I update to work for the latest version

  11. Hi,
    I am completely new to python but the way you explained everything was amazing!
    I keep running into this error and I don’t understand why?

    Traceback (most recent call last):
    File “/Users/ngl/PycharmProjects/binance /Binance Detect Moonings.py”, line 360, in
    coins_sold = sell_coins()
    File “/Users/ng/PycharmProjects/binance /Binance Detect Moonings.py”, line 288, in sell_coins
    test_order = client.create_test_order(symbol=coin, side=’SELL’, type=’MARKET’, quantity=coins_bought[coin][‘volume’])
    File “/Users/ngl/PycharmProjects/binance /venv/lib/python3.9/site-packages/binance/client.py”, line 1578, in create_test_order
    return self._post(‘order/test’, True, data=params)
    File “/Users/ng/PycharmProjects/binance /venv/lib/python3.9/site-packages/binance/client.py”, line 240, in _post
    return self._request_api(‘post’, path, signed, version, **kwargs)
    File “/Users/ng/PycharmProjects/binance /venv/lib/python3.9/site-packages/binance/client.py”, line 202, in _request_api
    return self._request(method, uri, signed, **kwargs)
    File “/Users/ng/PycharmProjects/binance /venv/lib/python3.9/site-packages/binance/client.py”, line 197, in _request
    return self._handle_response()
    File “/Users/ng/PycharmProjects/binance /venv/lib/python3.9/site-packages/binance/client.py”, line 230, in _handle_response
    raise BinanceAPIException(self.response)
    binance.exceptions.BinanceAPIException: APIError(code=-1013): Filter failure: MIN_NOTIONAL

    Process finished with exit code 1

Leave a Reply

Your email address will not be published. Required fields are marked *