Chapter 10: Hands-On Exercise – Building a Trading Bot with Flair

In this final chapter, we will go through a hands-on programming exercise where we will leverage a number of Flair's pre-trained models to build a real-world application. We will build a simple trading bot that uses Flair's Named Entity Recognition (NER) and sentiment analysis tools to make trading decisions. The trading strategy consists of taking the current day's news headlines as input and using NER to determine whether the news articles are discussing a company we are interested in. We will then run sentiment analysis that helps us make a call about whether to hold, buy, or sell this company's stock.

In the first section, we will cover the details of our trading strategy by explaining the motivation behind news sentiment-based trading approaches. Then, we will implement a trading bot using Flair. We plan to wrap the book up with a Flair coding cheat sheet containing a list of the most frequently used classes in Flair. We will cover all this as part of the following sections:

  • Understanding the trading strategy
  • Implementing the Flair trading bot
  • A Flair coding cheat sheet

But before diving straight into the ins and outs of trading bots, let's make sure that we have all the technical requirements taken care of.

Technical requirements

All of the Python libraries used in this chapter are direct dependencies of Flair version 0.11 and require no special setup, assuming Flair is already installed on your machine. Code examples covered in this chapter are found in this book's official GitHub repository in the following Jupyter notebook: https://github.com/PacktPublishing/Natural-Language-Processing-with-Flair/tree/main/Chapter10.

Understanding the trading strategy

For this hands-on exercise, we'll be implementing an interesting trading strategy that leverages several parts of the Flair NLP framework. The strategy is by no means the best and optimal trading strategy or one that is guaranteed to get you rich. It is, however, a strategy that clearly shows how Flair can be used to solve real-world problems with ease.

The strategy will help us make decisions about trading stock. There are many sources of information based on which one can make their trading decisions. A particularly interesting type of trading strategy leverages NLP to process recent news content. The underlying assumption of these trading strategies is that news articles that discuss a certain company hold important information about events that are likely to affect the company's stock price. Automated NLP strategies have a number of advantages compared to humans when it comes to investing. The advantages mostly boil down to the speed and scale of transactions that machines are capable of doing. A good NLP trading bot can analyze thousands of words of text and make a trading decision in a fraction of the time a human would.

Typical NLP trading bots, however, struggle with the problem of word sense disambiguation. Humans have historically been great at deciphering ambiguous word meanings using context. But recent advancements in NLP, such as Flair's contextual string embeddings used on downstream NLP tasks, bring machines one step closer. Take this statement, for example: Amazon deforestation fuelled by greed.

The preceding news article title, to a human, clearly talks about the Amazon rainforest and how it's being affected by deforestation. However, to a naive NLP trading bot, this can easily sound like an article that discusses the Amazon tech company. We can encounter the same type of problems when attempting to trade with companies named after real-world entities or objects, such as Apple, Tesla, Visa, and Shell. A good trading bot should therefore be able to use context to figure out the true meaning of a word in order to determine whether a news article talks about a certain company. Flair's contextually aware NER tagger based around the contextual string embeddings will help us do just that.

Our Flair stock trading strategy follows this sequence of steps:

  1. Find news articles potentially containing useful information that will help us make trading decisions.
  2. Use Flair's NER on news article titles to determine whether a news article talks about a company we are interested in.
  3. Perform sentiment analysis to determine the news article sentiment.
  4. If the result of sentiment analysis is positive, buy stock. If the result of sentiment analysis is negative, sell.
  5. Go back to step 1.

The strategy can best be illustrated using a flowchart:

Figure 10.1 – A Flair trading bot strategy flowchart

Figure 10.1 – A Flair trading bot strategy flowchart

The preceding flowchart shows how simple our trading strategy is in principle. And because we plan to implement it using Flair, it surely will be.

Let's learn how to implement this strategy as part of the upcoming section.

Implementing the Flair trading bot

The trading strategy consists of three main logically independent components:

  • News article acquisition component
  • NER component
  • Sentiment analysis component

The first component, news acquisition, is a very domain-specific piece of code. The data source used largely depends on the types of companies we're interested in trading. There's no universal source of news that will work well for all stock. Therefore, we plan to move the news acquisition part out of our strategy and design it so that the news text is merely provided as input to our bot.

Our trading strategy components will often access the same mutual variables such as the name of the company we are interested in. Therefore, it makes sense to use an object-oriented design and implement our strategy as part of a Python class. We will call our trading strategy class FlairTrader. The class's constructor method will receive the company name (the name of the company we want to trade) and will store it in memory, along with a NER tagger object and a sentiment analysis classifier object that will later be used by the named entity recognition and the sentiment analysis components respectively:

from flair.data import Sentence

from flair.models import SequenceTagger

from flair.models import TextClassifier

class FlairTrader:

    def __init__(self, company_name):

        self.company_name = company_name

        self.tagger = SequenceTagger.load('ner')

        self.classifier = TextClassifier.load('en-sentiment')

In the preceding code snippet, we simply define the FlairTrader class and its constructor (a type of method that gets called when a class is instantiated) __init__. We then set three class properties – the company name variable called company_name, Flair's default English NER tagger object called tagger, and Flair's English sentiment analysis classifier object called classifier.

Flair currently supports only English sentiment analysis models. For languages other than English, you'll need to use other NLP libraries such as Hugging Face that offer a wider support of languages. Flair does, however, support a variety of NER taggers for a number of languages. For example, you can replace ner with fr-ner in the preceding code snippet to use French NER tagging instead.

It's now time to implement the named entity recognition component. Its only purpose is, given some input text, to determine whether the text relates to the company we want to invest in or not. It will achieve this goal by looking for a named entity tag called ORG, which indicates that the context in which our company name was used refers to an organization – meaning our actual company. In the opposite scenario, for example, when Amazon refers to the Amazon rainforest as opposed to the company, the tag will be LOC – meaning location:

    def _references_company(self, text):

        sentence = Sentence(text)

        self.tagger.predict(sentence)

        for entity in sentence.get_spans('ner'):

            if (entity.get_label('ner').value == "ORG" and

                entity.text == self.company_name):

                return True

        return False

The preceding code snippet takes the news article title or text as input and tags it using Flair's default English NER tagger. It then looks for tokens matching our company_name and checks whether any tokens are tagged with ORG. If yes, the method returns True, meaning the text indeed references our company. If not, the method returns False.

Note that the method name is prepended with _. This is often used for private class methods in Python that are only used by other methods of the same class, while the method isn't intended to be called directly from outside the class.

Important Note

The preceding code snippet is a class method, meaning that the code should not be a standalone piece of code – it belongs inside the FlairTrader class definition. This is also the reason the entire code block is indented by four characters.

We can now test how our named entity recognition component performs:

  1. We first need to instantiate the FlairTrader object. We will test it by using amazon as the name of the company we want to invest in. This is simply due to the fact that Amazon can be confused with geographical places such as the Amazon rainforest or the Amazon River. We can define the FlairTrader object by running the following code:

    ft = FlairTrader("amazon")

  2. This now allows us to test the NER component out by running the following:

    print(ft._references_company("amazon river is deadly"))

The preceding code block prints out False. Rightfully so, it indicates that the word amazon does not relate to the Amazon company in the given context. Let's try another example:

print(ft._references_company("amazon is underpaying staff"))

The preceding code block prints out True. Flair correctly figured out that the previous sentence indeed relates to Amazon the company. Let's try another:

print(ft._references_company("amazon deforestation is bad"))

This preceding code block, as expected, prints False.

In the preceding code, we can clearly see our named entity recognition component is excellent in differentiating between text that references the Amazon River or the Amazon rainforest as opposed to text that discusses the Amazon tech company.

  1. We can now implement the sentiment analysis component, responsible for doing, as the name suggests, sentiment analysis and making calls about whether we should buy, sell, or hold. The method will be optimized so that it will only perform sentiment analysis if we think the input text is relevant to the company we want to trade with. If not, it will return hold (meaning we neither buy nor sell stock):

        def buy_or_sell(self, text):

            if self._references_company(text):

                sentence = Sentence(text)

                self.classifier.predict(sentence)

                if sentence.labels[0].value == "POSITIVE":

                    return "buy"

                elif sentence.labels[0].value == "NEGATIVE":

                    return "sell"

            else:

                return "hold"

This component is a class method called buy_or_sell(self, text). It receives text as input and, if the text is relevant to our company, performs sentiment analysis. If the text is deemed positive by the sentiment analysis classifier, we buy. If the text is negative, we sell. If the text isn't relevant to our company, we hold. It's important to note here that we completely disregard the classifier probability. Sometimes, the classifier will be 100% sure of its results, and sometimes, it'll be making a 51% guess. A good strategy will leverage this information and make use of certain probability thresholds.

Important Note

Make sure to add the preceding method to the FlairTrader class definition and not define it as a standalone piece of code.

Our trading strategy class is now complete!

We can now try it out by using another company name, such as Apple:

ft = FlairTrader("apple")

Let's see how our trading strategy performs:

print(ft.buy_or_sell("this year's apple harvest"))

The preceding code block prints out hold, which makes sense. The text is talking about apple as fruit and not Apple the company, meaning we gained no information about what trading decision to make.

Now, let's try an example with a positive sentiment:

print(ft.buy_or_sell("apple stock is doing great"))

The preceding code block, as expected, prints out buy.

We can now try a slightly less straightforward positive example:

print(ft.buy_or_sell("apple shows steady growth"))

The code block also prints out buy. It indicates that Flair was able to pick up more subtle positive signals in the text.

The following code block, thankfully, prints out sell:

print(ft.buy_or_sell("apple is being sued by the EU"))

The preceding examples show how good our trading strategy is at making decisions about buying, selling, or holding stock. It performs especially well on input text, such as news article titles where words in English are typically capitalized and there's no way of inferring meaning from capitalization.

Given the right set of daily news article feeds, the FlairTrader class gives us an excellent base for a trading bot that can be used in the real world. But before throwing all your life savings into this trading bot, you should be aware that real-world stock trading is usually more complicated than it appears. Good trading bots usually rely on a number of different indicators and rarely rely on a single source of truth, such as news article sentiment. A handy way to test a trading strategy without investing real money is to use backtesting where the strategy is tested on months or years of historical trading data, which gives us a rough idea of what to expect from our trading strategy in the real world before investing real funds. If you want to dig deeper into the field of trading with languages such as Python, you should give the brilliant Packt technical book called Python for Finance a go.

But regardless of whether your bot will make a profit or a loss in the real world, the implementation clearly shows how using Flair allows us to build smart and capable apps with only a few simple lines of code.

A Flair coding cheat sheet

Before wrapping up, we should do a quick recap of the most important Flair classes used throughout this book:

This short overview of frequently used Flair classes and commands should hopefully serve as an easy-to-remember list of the most important Flair commands used throughout this book.

Summary

This simple and fun hands-on exercise concludes our journey through the state-of-the-art NLP library Flair. At the beginning of the book, we kicked off with some motivation, followed by the Flair base types that set the foundation of how different objects typically interact with one another in Flair. We then covered word and document embeddings, which are an essential part of Flair and one of the main reasons why its taggers achieve state-of-the-art performance on sequence labeling tasks. This allowed us to progress towards sequence tagging itself, where we learned about all the different types of sequence taggers available in Flair. However, we weren't constrained to reusing the pre-trained models only; we quickly learned how to train our own sequence taggers as part of the next chapter. This left us overwhelmed by the long list of training hyperparameters, and we had to find a way of using machine learning to help us find the best set of parameters. We did so by mastering hyperparameter tuning and learning how to do it in Flair.

Shortly after, we dove into the most complex topic of this book where we trained our very own embeddings. This was followed by a slightly more relaxed topic of text classification in Flair, which was also the last chapter that explored Flair's features and capabilities. We then switched our focus on the applicability of Flair in the real world by learning how to deploy NLP models in production and finally wrapped up the book by implementing a simple Flair trading bot.

Though this book covers most Flair features at a fairly high level, you should note that Flair is a constantly evolving open source project with over 170 contributors. It constantly evolves and improves, and new features are added on a monthly basis. These final closing words should, therefore, not mark the end of your Flair journey. Instead, they should mark a new beginning. A beginning of a journey where you feel confident in your NLP abilities and are ready to see them come to life through Flair.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.199.27