Algorithmic Trading with Twitter Sentiment Analysis
Cryptocurrencies are already known to move heavily based on perception, so it could be that there is an edge to monitoring the sentiment on platforms like Twitter.
Introduction
When it comes to trading and cryptocurrency in particular, Twitter is the place where the community shares its thoughts. Cryptocurrencies are already known to move heavily based on perception, so it could be that there is an edge to monitoring the sentiment on platforms like Twitter. Today, we’ll be building a bot that fetches the most recent tweets regarding ETHUSD, performs sentiment analysis on those tweets, and places trades based on the polarity scores.
Before we go any further, it’s important to understand how the sentiment analysis algorithm will work. We’ll be using the python package NLTK to score each tweet based on whether it seems positive, negative, or neutral. If the average polarity score for all the tweets is positive, we’ll initiate a long trade on ethereum. Likewise, if the average polarity score for all the tweets is negative, we’ll sell any current position in ethereum.
Using Alpaca to Trade Crypto Based on Tweet Sentiment
Download Dependencies
First, we must use the Python package installer (pip) to install all the required dependencies for the program. In this case, we have to install alpaca-py, tweepy, and nltk. In order to perform sentiment analysis, we’ll need to also download the vader_lexicon package within nltk.
%%capture
!pip install alpaca-py
!pip install tweepy
!pip install nltk
nltk.download('vader_lexicon')
Import Dependencies
We’ll need the python package re to clean the tweets we retrieve using regular expression operations. Tweepy will allow us to access the tweets and alpaca-py will let us both trade crypto and access live crypto prices. Finally, for the sentiment analysis, we can use nltk’s vader sentiment intensity analyzer.
# Import dependencies
import re
import tweepy
import pandas as pd
from alpaca.data import CryptoDataStream
from alpaca.trading.client import TradingClient
from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce
from nltk.sentiment.vader import SentimentIntensityAnalyzer
Define API Credentials and Variables
The next step is to define most of the general variables we’ll be needing throughout the program. For the Alpaca API and Secret keys, you can access those on the main dashboard of your paper trading account overview. Using these keys, we can access the trading client as well as the live crypto pricing data stream object.
In order to access the Twitter API, you have to sign up for a developer account. Then, you can create a new app within the developer dashboard, and then you will be able to access the consumer keys and authentication tokens.
Lastly, we can define the number of tweets we want to use to 50 and the asset for us to trade as ETHUSD or ethereum. On twitter’s platform, all cryptocurrency symbols begin with a dollar sign so that is the keyword we will be scanning for.
# Alpaca API Credentials
APCA_API_KEY = '********************'
APCA_SECRET_KEY = '****************************************'
trading_client = TradingClient(APCA_API_KEY, APCA_SECRET_KEY, paper=True)
crypto_stream = CryptoDataStream(APCA_API_KEY, APCA_SECRET_KEY, raw_data=True)
# Twitter API Credentials
consumer_key = '*************************'
consumer_secret = '**************************************************'
access_token = '**************************************************'
access_token_secret = '*********************************************'
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
# Define variables
num_tweets = 50
keyword = '$ETHUSD'
keyword_to_asset = {
'$ETHUSD': 'ETHUSD'
}
Create Function to Check Account Positions
Next, we have to create a function to check whether the trading account currently holds any of the cryptocurrency. If it does, we can return a 1 indicating true. In this case, if there is no ethereum, then the function will just return 0.
This is important because, in an upcoming function that handles the buying and selling, we can focus on buying only if there is currently no ethereum in the account. Otherwise, we’ll monitor the sell signal to see if the position should be closed.
# Check whether account currently holds symbol
def check_positions(symbol):
positions = trading_client.get_all_positions()
if symbol in str(positions):
return 1
return 0
Create Function to Clean the Tweets
In the next function, we’ll be fetching the tweets that we’ll be performing sentiment analysis on. However, before the tweets are ready to be analyzed, they have to be cleaned to remove mentions, links, and special characters.
# Clean the tweet content using regex
def clean_tweet(tweet):
return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", tweet).split())
Use Tweepy to Retrieve Tweets Containing Keyword
We can create a set to collect all 50 of the tweets we fetch. Then we can use tweepy to fetch the tweets and our previous clean_tweet function to remove unnecessary wording. In order to make sure we’re not including retweets, we can quickly check if the tweet’s text is not already in our tweet’s set.
# Retrieve tweets from Twitter using keyword
def get_tweets(query, count):
tweets = set()
fetched_tweets = api.search(q=query, count=count)
for tweet in fetched_tweets:
cleaned_tweet = clean_tweet(tweet.text)
if cleaned_tweet not in tweets:
tweets.add(cleaned_tweet)
return tweets
Calculating Sentiment Polarity Score for Tweets
Using nltk, we can quickly gather the polarity scores for each tweet and append them into an array. The pol_score includes the negative, positive, neutral, and compound scores.
# Calculating the polarity of each tweet using nltk
def calculate_polarity(tweets):
scores = []
for tweet in tweets:
pol_score = SentimentIntensityAnalyzer().polarity_scores(tweet)
pol_score['tweet'] = tweet
scores.append(pol_score)
return scores
Trading Crypto Based on Tweet Sentiment
Finally, we can begin to place trades based on the sentiment of the tweets we fetched. The first step is to check if our account currently holds any ethereum. Based on this, we will direct the program to focus on either buying or selling.
Next, we can gather the tweets using the get_tweets function and start to perform sentiment analysis using the calculate_polarity function. The compound score takes into account the positive, negative, and neutral scores and is what we’ll be using to generate buy and sell signals.
If the compound score is above 0.05 and there is currently no position in the account, we’ll buy 10 ETHUSD at the current price. If there is currently ethereum in the account and the compound score is below negative 0.05, then we’ll close out the position altogether.
# Placing trades based on the polarity of the tweets
def twitter_bot(symbol, close, qty=10):
position = check_positions(symbol=symbol)
tweets = get_tweets(keyword, num_tweets)
scores = calculate_polarity(tweets)
mean = pd.DataFrame.from_records(scores).mean()
compound_score = mean['compound']
print (f"Sentiment score: {round(compound_score, 3)}")
if compound_score >= 0.05 and position==0:
market_order_data = MarketOrderRequest(
symbol=symbol,
qty=qty,
side=OrderSide.BUY,
time_in_force=TimeInForce.GTC)
trading_client.submit_order(
order_data=market_order_data)
print(f"Bought {symbol} at approx. {close}")
elif compound_score <= -0.05 and position==1:
trading_client.close_position(symbol_or_asset_id=symbol)
print(f"Sold {symbol} at approx. {close}")
return True
Stream Live Crypto Data from Alpaca
The last step of building the Python bot is to start streaming live market data for ethereum from Alpaca. Fortunately, Alpaca makes this process extremely easy.
First, we have to create an instance of the data streaming API by calling the CryptoDataStream method in which we pass the API keys. Then, we can create an asynchronous function to receive the live bar data and within this function, we can call the twitter_bot function.
Here, we can subscribe to crypto data, and start streaming live data!
# Live streaming of crypto pricing data
async def quote_data_handler(data):
close = data['c']
twitter_bot(keyword_to_asset[keyword], close, qty=10)
crypto_stream.subscribe_bars(quote_data_handler, keyword_to_asset[keyword])
crypto_stream.run()
Conclusion
In this tutorial, we built a fully-functional live trading bot that trades ethereum based on recent tweet sentiment. This involved fetching tweets using tweepy, cleaning the tweets using regex, calculating polarity using nltk, and placing trades using Alpaca-py! To access and run the code from this article in a Google Colab Notebook, check out this link!
Thanks for reading, and I hope you learned something about using the building bots with Alpaca-py!
Please note that this article is for informational purposes only. The example above is for illustrative purposes only. Actual crypto prices may vary depending on the market price at that particular time. Alpaca Crypto LLC does not recommend any specific cryptocurrencies.
Cryptocurrency is highly speculative in nature, involves a high degree of risks, such as volatile market price swings, market manipulation, flash crashes, and cybersecurity risks. Cryptocurrency is not regulated or is lightly regulated in most countries. Cryptocurrency trading can lead to large, immediate and permanent loss of financial value. You should have appropriate knowledge and experience before engaging in cryptocurrency trading. For additional information please click here.
Cryptocurrency services are made available by Alpaca Crypto LLC ("Alpaca Crypto"), a FinCEN registered money services business (NMLS # 2160858), and a wholly-owned subsidiary of AlpacaDB, Inc. Alpaca Crypto is not a member of SIPC or FINRA. Cryptocurrencies are not stocks and your cryptocurrency investments are not protected by either FDIC or SIPC. Please see the Disclosure Library for more information.
This is not an offer, solicitation of an offer, or advice to buy or sell cryptocurrencies, or open a cryptocurrency account in any jurisdiction where Alpaca Crypto is not registered or licensed, as applicable.