This is a public lemon.markets repository that outlines a sentiment analysis strategy using our API.
To get a general understanding of the API, please refer to our documentation.
The financial-news-trader
scrapes headlines found on MarketWatch.com, performs
sentiment analysis using VADER and places trades depending on the direction of the sentiment. Note that this is only a
showcase of the product and should not be used as investment advice.
A walk-through of this script can be found in this blog-post.
Not interested in reading a novella before you get started? We get it! To get this project up and running quickly, here's what you need to do:
headlines.py
file;headlines.py
file;quantity
) in the helpers.py
file;'Sentiment' is a view or opinion about a particular topic - if we analyse the sentiment expressed in a news article about a financial instrument, we want to determine whether it is positive or negative. For example, the headline "Pelaton Earnings Disappointed. Another Pandemic Play Sinks." (real headline collected on 05-11-2021) clearly tells us that a long position in Pelaton probably isn't a good move. We can make this kind of judgement based off of the words 'disappointed' and 'sinks'.
In this project, we'd like to automate this process, so we're going to use VADER, which is a lexicon of words along with their 'sentiment scores'. A headline will be analysed based on its polarity (positive or negative) and intensity of emotion, which results in a score between -1 (very negative) and +1 (very positive). We can then make trade decisions based on these scores.
This project uses the lemon.markets API and the OpenFIGI API.
lemon.markets is a brokerage API by developers for developers that allows you to build your own experience at the stock market. We will use the Market Data API and Trading API to retrieve the ISIN (unique identifier) that belongs to a particular financial instrument and to place trades. If you do not have a lemon.markets account yet, you can sign up here. š
OpenFIGI allows the mapping of third-party symbologies to FIGIs, which is a universal naming convention for financial instruments. We will use the API to map a ticker (American standard) to an ISIN (European standard). You can check out this article to learn more. If you do not have an OpenFIGI account yet, you can sign up here.
The script uses several environment variables, configure your .env file as follows:
ENV Variable | Explanation |
---|---|
DATA_API_KEY | Your market data API key |
TRADING_API_KEY | Your paper/money trading API key |
MIC | Market Identifier Code of Trading Venue |
OPENFIGI_URL | https://api.openfigi.com/v3/search/ |
OPENFIGI_KEY | Your Open FIGI API Key |
For this project, we are collecting data from MarketWatch because the data is presented in an easily digestible format. For each headline, we are given its date and the ticker(s) corresponding to the headline. To collect the headlines, we use a simple GET request against the desired URL:
import requests
page = requests.get("https://marketwatch.com/investing/technology")
Then, to parse the data, we use BeautifulSoup, which is a Python package that can extract data from HTML documents. We collect the headline, the date of publication and the associated ticker(s).
At this stage, it's likely your data needs some (additional) pre-processing before it's ready for sentiment analysis and trading. Luckily, in our case, we don't have to do a lot of pre-processing. We removed any headlines without tickers and headlines with tickers that we know are not tradable on lemon.markets (to make the dataset smaller). To do this, we created a list of non-tradable tickers and constructed a new DataFrame of the collected headlines, filtered by the negation of the above list. Additionally, to trade on lemon.markets, we need to obtain the instrument's ISIN. Because we trade on a German exchange, querying for a US ticker will not (always) result in the correct instrument. Therefore, to ensure that there are no compatibility issues, we suggest mapping a ticker to its ISIN before trading (using OpenFIGI).
We use VADER to perform sentiment analysis on all collected headlines as follows:
from nltk.sentiment.vader import SentimentIntensityAnalyzer
vader = SentimentIntensityAnalyzer()
scores = []
for headline in headlines_df.loc[:,"headline"]:
score = vader.polarity_scores(headline).get("compound")
scores.append(score)
headlines_df.loc[:,"score"] = scores
Our base project works with a very simple trade rule: buy any instrument with a score above 0.5 and sell any instrument with a score below -0.5 (see if you can come up with something a bit more complex š):
buy = []
sell = []
for index, row in headlines_df.iterrows():
if row['score'] > 0.5 and row['isin'] != 'No ISIN found':
buy.append(row['isin'])
if row['score'] < -0.5 and row['isin'] != 'No ISIN found':
sell.append(row['isin'])
We can then feed this list of ISINs to the lemon.markets API to place and activate our trades.
This (and all lemon.markets open source projects) is(are) a work in progress. If you are interested in contributing to this repository, simply create a PR and/or contact us at support@lemon.markets.
Looking forward to building lemon.markets with you š