Open Source Crypto Sentiment Trading Bot for Reddit

If you’re familiar with the r/CryptoCurrency subreddit, you’ve probably heard the phrase the phrase “inverse r/cc strategy”.

This is very similar to the inverse Cramer strategy, in that it aims to place trades using the inverted sentiment of the Cryptocurrency subreddit. Basically, if the subreddit says that Solana sucks — we want to go all in.

The collective voice of the subreddit has been so consistently wrong, that even members of the sub are using the aggregated sentiment to buy coins the echochamber swears they’re sacrilege.

Doge, Solana, ShibaInu and Worldcoin are just some of coins this subreddit was singing funeral rites to as if they were a Mariachi band performing at the Day of the Dead festival.

The point of this exercise is not to discuss whether certain tokens have use-cases or are decentralised and safe, as that would be a completely different topic. The point here is purely from a financial perspective. From this perspective all the coins listed above are still alive and doing quite well.

So, in order to test whether this theory still applies today, and whether InverseCC truly deserves its spot next to the iconic InverseCramer indicator — I built a crypto trading bot that buys coins this subreddit hates.

The tool is complete but I still need to build the reporting into it, so the purpose of this article is to explain how I’ve built the tool and more importantly, the way I overcame some of the challenges associated quantifying sentiment for a specific topic.

 You can run it on any subreddit and choose the sentiment threshold — so it doesn’t have to follow the InverseCC trading strategy. I will drop the links at the end of the article.

Prerequisites

To run this tool yourself, you will need:

  • WSL (if on Windows)
  • Docker
  • PG Admin
  • Visual Studio 2022 or similar (optional — for development)
  • .NET 7+ (optional — for development)

Ok let’s get into it.

How is it architected?

Whenever starting a project, I always like have the technology stack figured out. Unless I have a specific preference at that time, I just go with what makes the most sense for that project.

In this case I chose to build the bot using C# as a Worker Service. The Worker Service is great because it lets you spin up new services and works that do completely independent things form each other, meaning we can keep adding logic in this fashion without any mounting complexity.

I also went for Docker so the app can be launched on virtually any machine without any issues.

What does it do?

The app does a few very specific things and currently consists of 4 works, each tasked with a specific workload.

  • The RedditPostsWorker grabs the relevant posts and their description text and drops them in a PSQL database.
  • Then there’s a SentimentLabellerWorker that iterates through each post and gives it a sentiment score. More on this later.
  • After that, a SentimentAggregatorWorker iterates through each post and makes note of its sentiment and coin. It then aggregates sentiment for all instances of a coin. Basically if there are 50 posts about Bitcoin, and each has a sentiment score, the aggregator will just give us the average score Bitcoin.
  • Finally the ExchangeBuyWorker iterates through each coin and its aggreagates sentiment score and buys any coin with an average sentiment score lower than -0.1.

Fetching Reddit Posts

Since reddit leadership decided to decimate its API and ask ridiculous fees to use it, I was stuck with using Reddit’s own frontend API. This is the API that populates the content of the page itself, rather than a client-facing API.

It’s super useful to be aware of it since you can bypass the rate limited mess that their authenticated API is.

The endpoint for that is: https://www.reddit.com/r/[subreddit_name]/[filter].json so for example: https://www.reddit.com/r/CryptoCurrency/hot.json

Adding A sentiment score

To add sentiment to posts title and description, I decided to use NLTK’s Vader Lexicon. This is a pre-trained machine learning algorithm specifically built do sentiment score text.

With that integrated into my C# app, it was fairly easy to iterate through posts and add a score.

Aggregating Sentiment Score

The score itself is not something that we can actually use since we have hundreds of posts, each with their own score and each one talking about a different coin or project.

So the solution is to aggregate these scores. The first step is to determine what coin is being discussed in each particular post.

I also needed a specific coins table and a coin_sentiments. Any post containing a coin of coins will be taken into account for sentiment aggregation. Once the numbers are crunched, they’ll end up back in the database in the coin_sentiments table.

Buying cryptocurrency programmatically

I already have some experience with the ExchangeSharp library and decided to use that. I had to make some adjustments to allow it to automatically convert the USDT amount to the equivalent of whatever coin it’ll end up buying. Exchanges hate conversions and decimals and they are very opinionated so feel free to peek at the source code on how to handle this if you don’t want to lose your mind over it like I did.

All I had to do at this point is run docker compose up -d and the algorithm would run its magic. Here are today’s entries in my database:

As you can see, there are some false positives, meaning that the tool needs some adjustments but I’m extremely happy that it all works.

Over the next few weeks I will work on collecting trade data and adding another worker that will do some reporting for me to see how it’s performing, so make sure to follow me to keep up to date.

Resources

 

Thank you for reading!

Enjoyed this article?

Sign up to the newsletter

You’ll receive more guides, articles and tools via e-mail. All free of course. But if you value this blog and its educational resources, you can subscribe to become a paid member for only $3 a month. This will keep the website open and free.

Leave a Reply

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