Edit product


Hands-on Elixir & OTP: Cryptocurrency trading bot

Want to learn Elixir & OTP by creating a real-world project? With "Hands-on Elixir & OTP: Cryptocurrency trading bot" you will gain hands-on experience by working on an interesting software project. We will explore all the key abstractions and essential principles through iterative implementation improvements.

This book is a loosely written representation of "Hands-on Elixir & OTP: Cryptocurrency trading bot video course released on YouTube(https://www.youtube.com/watch?v=wVYIx7M6o28&list=PLxsE19GnjC5Nv1CbeKOiS5YqGqw35aZFJ).

To keep this book up to date as well as publicly available for people that can't afford to pay for it, it's available in HTML format online free of charge at https://www.elixircryptobot.com

PDF & EPUB formats are available to backers using either GitHub Sponsors(https://github.com/sponsors/frathon) - it supports both one-offs payments as well as "monthly" plans - or here at Gumroad.

It's still an ongoing production and will be continued in the upcoming months, at this moment it contains:

* Chapter 1 - Stream live crypto prices from Binance WSS

Stream live cryptocurrency prices (trade events) from the Binance exchange. Starting grounds up, we will create a new umbrella project and a `streamer` application inside it. The streamer application will use a Websocket client called `WebSockex` to establish a connection with the Binance API and receive a live feed. After receiving the event as JSON string, we will decode it using the `jason` library and convert it to our own data struct. At the end of the chapter, we will see decoded trade events being logged to the terminal.

* Chapter 2 - Create a naive trading strategy - single trader without supervision

In this chapter, we will create our first *naive* trading strategy. We will create another application inside our umbrella called `naive`. We will put data streamed to our `streamer` application to good use by sending it over to the `naive` application. We will start with a very basic solution consisting of a single process called `trader` that will utilize the `GenServer` behavior. It will allow us to go through the full trading cycle and will give us something that "works".

* Chapter 3 - Introduce PubSub as a communication method

To allow our trading strategy to scale to multiple parallel traders, we need to find a way to distribute the latest prices (trade events) to those multiple traders. We will introduce PubSub to broadcast messages from the streamer(s) to the trader(s). PubSub will allow us to break hardcoded references between applications in our umbrella and that will become a pattern that we will utilize moving forward.


* Chapter 4 - Mock the Binance API

Besides historical prices (trade events), to perform backtesting, we need to be able to mock placing orders and get trade events back as they are filled. In this chapter, we will focus on developing the solution that will allow our trader to "trade" without contacting the Binance exchange(for people without Binance accounts), it will also allow us to backtest our trading strategy.

* Chapter 5 - Enable parallel trading on multiple symbols

Our basic strategy implementation from the last chapter is definitely too basic to be used in a "production environment" - it can't be neither scaled nor it is fault-tolerant. In this chapter, we will upgrade our naive strategy to be more resilient. This will require a supervision tree to be created and will allow us to see different supervision strategies in action and understand the motivation behind using and stacking them.

* Chapter 6 - Introduce a `buy_down_interval` to make a single trader more profitable

At this moment our `Naive.Trader` implementation will blindly place a buy order at the price of the last trade event. Whenever the `Naive.Trader` process will finish trade, a new `Naive.Trader` process will be started and it will end up placing a buy order at the same price as the price of the previous sell order. This will cost us double the fee without gaining any advantage and would cause further complications down the line, so we will introduce a `buy_down_interval` which will allow the `Naive.Trader` processes to place a buy order below the current trade event's price.

* Chapter 7 - Introduce a trader budget and calculating the quantity

Since the second chapter, our `Naive.Trader` processes are placing orders with a hardcoded quantity of 100. In this chapter, we will introduce a budget that will be evenly split between the `Naive.Trader` processes using chunks. We will utilize that budget to calculate quantity (to be able to do that we need to fetch further `step_size` information from the Binance API).

* Chapter 8 - Add support for multiple transactions per order

Our `Naive.Trader` implementation assumes that our orders will be filled within a single transaction, but this isn't always the case. In this chapter, we will discuss how could we implement the support for multiple transactions per order and race conditions that could occur between the bot and the Binance API.

* Chapter 9 - Run multiple traders in parallel

With PubSub, supervision tree, buy down and budget in place we can progress with scaling the number of traders. This will require further improvements to our trading strategy like introducing a `rebuy_interval`. At the end of this chapter, our trading strategy will be able to start and run multiple traders in parallel.

* Chapter 10 - Fine-tune trading strategy per symbol

Currently, the naive strategy works based on settings hardcoded in the `leader` module. To allow for fine-tuning the naive trading strategy per symbol we will introduce a new database together with the table that will store trading settings.

* Chapter 11 - Supervise and autostart streaming

In the last chapter, we introduced a new database inside the `naive` application to store default settings, in this chapter we will do the same for the `streamer` application. Inside the settings, there will be a `status` flag that will allow us to implement the autostarting functionality on initialization using Task abstraction.

* Chapter 12 - Start, stop, shutdown, and autostart trading

To follow up after autostarting streaming we will apply the same trick to the trading supervision tree using Task abstraction. We will need to introduce a new supervision level to achieve the correct supervision strategy.

* Chapter 13 - Abstract duplicated supervision code

As both the `naive` and the `streamer` applications contain almost the same copy-pasted code that allows us to start, stop and autostart workers. We will look into how could we abstract the common parts of that implementation into a single module. We will venture into utilizing the `__using__` macro to get rid of the boilerplate.

* Chapter 14 - Store trade events and orders inside the database

To be able to backtest the trading strategy, we need to have historical prices (trade events) and a list of orders that were placed stored in the database, which will be the focus of this chapter. At this moment, the latest prices (trade events) are broadcasted to PubSub topic and traders are subscribing to it. We will create a new application called `data_warehouse` inside our umbrella that will be responsible for subscribing to the same PubSub topics and storing incoming prices (trade events) in the Postgres database. We will update the `Naive.Trader` module to broadcast orders as traders will place them.

Then we will move on to adding supervision similar to the one from the `naive` and the `streamer` applications but this time we will show how we could avoid using both common module and macros by utilizing the `Registry` module.

* Chapter 15 - Backtest trading strategy

In this chapter, we will be backtesting our trading strategy by developing a publisher inside the DataWarehouse application. It will stream trade events from the database to broadcast them to the `TRADE_EVENTS:#{symbol}` PubSub topic. It will use the same topic as data would be streamed directly from the Binance. From the trader's perspective, it won't any difference and will cause normal trading activity that will be stored inside the database to be analyzed later.

Chapter 16 - End-to-End testing

In this chapter, we will implement the end-to-end tests. On the way, we will venture into configuration(introducing test databases), downloading test assets(Protocols consolidation), and finally, getting caught by the dependency cycle between apps in our umbrella.

You've purchased this product

See it in your library

View in Library
Sorry, this item is not available in your location.
Sold out, please go back and pick another option.
-Quantity 1+

Name a fair price:

  • This book is 75% complete - chapters 1-15 are finished but I'm planning to add more content in the near future.


Hands-on Elixir & OTP: Cryptocurrency trading bot

Enter your info to complete your purchase


···· ···· ···· 4242
Test card



Use a different card?


pp paypal

or pay with

We do not keep any of your sensitive credit card information on file with us unless you ask us to after this purchase is complete.

or pay with

You'll be charged US$10.

Your purchase was successful!

We charged your card and sent you a receipt

    Gumroad Library

    Download from the App Store or text yourself a link to the app

    Good news! Since you already have a Gumroad account, it's also been added to your library.

    Powered by Gumroad