You can often come across articles that are called something like this: "10 projects that a programmer needs to implement." Trading bots are often listed in these articles. I believe that developing a trading bot is a worthwhile investment. So I decided to take some time to write a tutorial about this.
But instead of doing a line-by-line parsing of some code, I decided that it would be better to disassemble the concepts that someone who wants to create their own bot should be familiar with. The point of my material is that, after reading it, you would write the code yourself.
Therefore, I will talk about what is useful to know for developing a trading bot, and what is needed for this (from working with exchanges to implementing a simple trading strategy). Here I will touch on the issues related to the architecture and internal structure of simple trading bots, with the ideas that underlie them. I will demonstrate examples written in pseudocode. Therefore, you can read this guide and immediately write your own bot in the programming language of your choice. As a result, you will feel comfortable using a tool that you are familiar with. You will be able to calmly engage in programming, and not spend time setting up the working environment and getting used to a new language. You will choose a weapon, and I will teach you how to use this weapon.
Step 1. Choosing a weapon
In the first step of this tutorial, you will choose the programming language you will be using. You must decide this question yourself.
Some languages like Python may be preferred if you plan to equip your bot with machine learning mechanisms in the future. But my main idea is that you can choose the language that is most convenient for you to work with.
Step 2. Looking for the battlefield
One important topic is often overlooked in tutorials on writing trading bots. It concerns the choice of the exchange. The fact is that in order for a bot to be able to do what it was created for, it needs access to an exchange where you can trade something. Choosing an exchange and knowing how to use it is just as important as programming skills.
So, your first step will be deciding what exactly you are going to trade (stocks, currencies, cryptocurrencies) and deciding where exactly you will trade.
If we talk about exchange-traded assets, then I would advise you to pay attention to cryptocurrencies. The reason for this recommendation is not that I am a supporter of blockchain technologies and cryptocurrencies (I am completely open on this issue), but only that the cryptocurrency markets work around the clock, 7 days a week.
More “traditional” assets can only be traded at certain time intervals, and often only on weekdays. Stock markets, for example, are usually open from 9 am to 4 pm and are closed on weekends. The FOREX markets, although they can operate around the clock, are usually closed on weekends.
In this regard, cryptocurrencies are best suited for us, since the choice of this market will allow our bot to work without interruption. Additionally, cryptocurrencies are known for their high levels of volatility. This means, firstly, that you can lose a lot of money on trading them, and secondly, that they are an excellent tool for studying and testing trading strategies.
We have already talked about exchange assets. Let's now discuss the requirements to consider when choosing an exchange for which a bot will be created. Namely, I am talking about two basic requirements:
- You must be legally able to trade on the selected exchange and work with the trading instruments it offers. If we talk about cryptocurrencies, then in some countries trading in them is prohibited. Consider this when choosing instruments and an exchange.
- API, . , .
After it turns out that a certain exchange meets these two basic requirements, you can analyze it in more depth. For example, to estimate the size of commissions, to assess its reliability and popularity, to look at the quality of documentation for its API.
And yet, which is just as important as everything else, I would recommend evaluating the trading volume of the exchange. Low volume exchanges tend to lag behind price movements. In addition, it is more difficult to execute limit orders on them (we will talk more about this below).
If you finally decide to choose cryptocurrencies, then here is a good list of the leading exchanges. Here you can find various information about them to help you choose an exchange.
Step 3. Building the camp
If the exchange is a battlefield, then now we will talk about the place from which we will send our troops to the battlefield. By the way, perhaps it's time for me to tie up with such analogies.
I'm talking about the server here. The bot code must be executed on some server, which will allow the bot to send requests to the exchange API.
When testing a bot, of course, your computer can act as a server. But if you need a bot to work all the time, a regular computer is definitely not the best choice.
I have two suggestions here:
- The server role can be played by the Raspberry Pi (this approach is more interesting).
- The server can be some kind of cloud service (and this approach is better).
I think that organizing a bot on the basis of your own Raspberry Pi server is an interesting and modern idea, so if you like this idea, you can put it into practice.
But most bot builders will likely opt for a cloud provider like AWS , Azure , GCS, or Digital Ocean .
Most of the major cloud providers have good free plans, so you might be able to host your bot with that provider for free.
This concludes my conversation about servers. You should choose what works best for you. For a small project like the one we are doing, what gets chosen won't have a big impact on the end result.
Step 4. Create a bot
And now the fun begins. But, before starting this part of our project, check if the following has been done:
- You have registered on the exchange and received the necessary permits to work with it.
- You have the ability to work with the exchange API, you have an API key.
- You have chosen hosting for the bot.
If these issues are resolved, it means that we can move on.
▍ Simplest bot
My goal is to help someone who, up to this point, knew absolutely nothing about bots, to rise to the level of creating a simple working bot. Therefore, I will tell you how to create a simple trading bot that you can expand and improve according to your needs.
Our bot will have some limitations:
- The bot will be able to stay in only one of two states: BUY (buy) or SELL (sell). He will not constantly place buy or sell orders at different prices. If the last operation was a sale, then the next operation that the bot will try to perform is a buy.
- The bot will use fixed thresholds to make buy and sell decisions. A more intelligent bot may be able to independently adjust such values based on various indicators, but the strategy and limits of our bot will be set manually.
- He will only trade one currency pair. For example - BTC / USD.
These restrictions make our task easier. The bot will be simple, which means it will be easier to build and maintain. This will also allow us to very quickly deploy its code to the server. Basically, we're talking about the KISS principle here.
▍Decision making mechanism
Here is a simple diagram giving an overview of how our bot is functioning.
Now you can start planning your bot architecture.
To begin with, we need a variable that will store information about the exact state of the bot at the current moment. This is either BUY or SELL. A boolean variable or enumeration is a good choice for storing such information.
Then you need to set thresholds for buy and sell operations. These values are expressed as a percentage and represent the increase or decrease in the price of the asset since the previous transaction.
For example, if I bought something at $ 100 and the current price is $ 102, then we are dealing with a 2% increase in price. If the threshold for the SELL operation is set at a one percent increase in price, then the bot, seeing this 2%, will sell the asset, since it has already made a profit that exceeds the threshold value we set.
In our case, such values will be constants. We need 4 such values - 2 for each bot state.
▍Threshold values for the BUY operation (if the bot is in SELL state)
DIP_THRESHOLD
: the bot performs a buy operation if the price has decreased by a value greater than the specified valueDIP_THRESHOLD
. The rationale behind this is to implement a buy low, sell high strategy. That is, the bot will try to buy an asset at a reduced price, expecting an increase in price and the possibility of a profitable sale of the asset.UPWARD_TREND_THRESHOLD
: the bot buys an asset if the price has increased by a value that is higher than that specified by this constant. This move contradicts the "buy low, sell high" philosophy. Its purpose is to identify an uptrend and not miss a buying opportunity before the price rises even further.
Here is an illustration that can help you understand the meaning of these constants.
If we performed the SELL operation at the moment marked in the figure with the red SELL marker, then after that the bot, when deciding whether to perform the BUY operation, will be guided by the threshold values
DIP_THRESHOLD
and UPWARD_TREND_THRESHOLD
.
If the price goes below the lower green line or above the upper green line, we will perform a BUY operation. In the situation shown in the figure, the price went above the upper limit. Therefore, we, guided by the value
UPWARD_TREND_THRESHOLD
, performed the BUY operation.
▍Threshold values for SELL operation (if the bot is in BUY state)
PROFIT_THRESHOLD
: the bot sells an asset if the price has become higher than the price calculated on the basis of this value, since the asset was previously bought at a lower price. This is how we make a profit. We sell the asset at a price that is higher than the price at the time of purchase.STOP_LOSS_THRESHOLD
: Ideally, we would like the bot to sell assets only when the sale is profitable for us. But, perhaps, there was a strong downward movement of the market. In such a situation, we decide to exit the trade before we incur too large a loss, and later buy the asset at a lower price. This threshold is used to close the position at a loss. The purpose of this operation is to prevent greater losses.
Here's an illustration.
This shows the situation when a purchase was made where the BUY marker is. After that, the price reaches the specified limit
PROFIT_THRESHOLD
and we sell the asset at a profit. This is how bots make money.
Now that we have a general understanding of how a bot functions, it's time to look at the pseudocode.
▍Helpful functions for working with API
The first thing a bot will need is the ability to exchange data with the exchange API. We implement these capabilities using several helper functions:
FUNCTION getBalances():
DO: GET- API
RETURN:
FUNCTION getMarketPrices():
DO: GET- API
RETURN:
FUNCTION placeSellOrder():
DO:
1. (
, ,
50% )
2. POST- API
SELL
RETURN:
FUNCTION placeBuyOrder():
DO:
1. (
, ,
50% )
2. POST- API
BUY
RETURN:
// ,
//
FUNCTION getOperationDetails():
DO: GET- API
RETURN:
The above code should be self-explanatory without much explanation. But, implementing this functionality, you must know exactly what data you need to transfer to the API when making POST requests that initiate the purchase or sale of something.
Often, for example, when trading the XAU / USD pair (gold and US dollars), when executing a request, you can specify either how much gold you need to buy, or how many dollars you need to sell. When performing such requests, it is very important to clearly understand the meaning of the actions being performed.
▍Main Bot Loop
Now that we have prepared the helper functions, let's start describing the bot's actions. First, we need to create an endless loop that runs at regular intervals. Suppose we want a bot to try to perform an operation every 30 seconds. This is what a loop like this might look like:
FUNCTION startBot():
INFINITE LOOP:
attemptToMakeTrade()
sleep(30 seconds)
Next, we will configure the variables and constants that we talked about above, and write the bot logic that allows it to make decisions. As a result, in addition to the auxiliary functions and the main loop, the main bot code will look like this:
bool isNextOperationBuy = True
const UPWARD_TREND_THRESHOLD = 1.50
const DIP_THRESHOLD = -2.25
const PROFIT_THRESHOLD = 1.25
const STOP_LOSS_THRESHOLD = -2.00
float lastOpPrice = 100.00
FUNCTION attemptToMakeTrade():
float currentPrice = getMarketPrice()
float percentageDiff = (currentPrice - lastOpPrice)/lastOpPrice*100
IF isNextOperationBuy:
tryToBuy(percentageDiff)
ELSE:
tryToSell(percentageDiff)
FUNCTION tryToBuy(float percentageDiff):
IF percentageDiff >= UPWARD_TREND_THRESHOLD OR percentageDiff <= DIP_THRESHOLD:
lastOpPrice = placeBuyOrder()
isNextOperationBuy = False
FUNCTION tryToSell(float percentageDiff):
IF percentageDiff >= PROFIT_THRESHOLD OR percentageDiff <= STOP_LOSS_THRESHOLD:
lastOpPrice = placeSellOrder()
isNextOperationBuy = True
Note that the thresholds in this code are randomly selected. You should choose these values yourself, in accordance with your trading strategy.
Combining the above code with the helper functions and with the main bot loop, which can be represented by something like a function
main
, this means that we now have a very simple working bot with the basic capabilities typical of bots.
At each iteration of the cycle, the bot will check its current state (BUY or SELL) and will try to perform a trade operation, using threshold values that are hard-coded in its code when analyzing the current situation. Then, if the operation is completed, the bot will update information about its current state and data about the price at which the last operation was performed.
Step 5. Improving the bot
The basic architecture of our bot is ready. But we can probably improve it a bit by equipping it with some additional features.
▍Magazines
When I started to create one of the variants of this bot, it was very important for me that the bot would constantly log information about its actions, outputting them to the terminal and to a separate log file.
Each step of the program was to be accompanied by approximately the following records:
[BALANCE] USD Balance = 22.15$
[BUY] Bought 0.002 BTC for 22.15 USD
[PRICE] Last Operation Price updated to 11,171.40 (BTC/USD)
[ERROR] Could not perform SELL operation - Insufficient balance
What goes into the log file is time stamped. As a result, if I connect to the server once a day and see, for example, an error message, I can find out exactly when the error occurred and what the bot was doing all this time.
Equipping a bot with these capabilities means writing a function that can be named
createLog
. This function should be called at every step of the main bot loop. This is what this function might look like:
FUNCTION createLog(string msg):
DO:
1. msg
2. msg ,
▍Identification of trends
The main goal of our bot is to buy assets cheaply and sell them, making a profit. But in his code there are two constants, symbolizing two threshold values, which partly contradict this goal. This
UPWARD_TREND_THRESHOLD
and STOP_LOSS_THRESHOLD
.
These values are intended to limit losses by selling the asset when the price falls and to organize the purchase of the asset when the price rises. The point here is that with their help we try to predict trends, prices, when they appear, go beyond the limits of the usual strategy, but can either harm us or give us money. Both that and another provide for some actions on our part.
The way the price analysis works now limits us very much. Price analysis, carried out by comparing a pair of indicators, is far from a mechanism for identifying trends.
But we, fortunately, can, without too much trouble, make our trend detection system more reliable.
We just need to organize the observation of more price values than before. And before, we stored information about only one price indicator - about the value of the asset at the time of the last operation (
lastOpPrice
). For example, you can store information about prices for the last 10 or 20 iterations of the bot cycle and compare them with the current price, and not only lastOpPrice
. This is likely to allow for better identification of trends, since with this approach we can capture short-term price fluctuations rather than fluctuations that occur over a long time.
▍Database?
A simple bot doesn't really need a database. After all, he operates with very small amounts of data and stores all the information he needs in memory.
But what happens if, for example, the bot is abnormally stopped? How can he know, without human intervention, what the meaning was
lastOpPrice
?
In order to eliminate the need for manual intervention in the bot code when it is restarted, we may need some simple database in which we can store some indicators like
lastOpPrice
.
With this approach, the bot, when launched, may not use the values that are hardcoded in the code. Instead, it accesses the stored data and resumes where it left off.
Depending on how simple you think this "database" should be, you may even decide to use regular .txt or .json files as such, since, in any case, we are talking about storing very limited data set.
▍Control Panel
If you want to organize the visualization of the bot's activity, as well as manage it without editing its code, then you may want to connect the bot to some kind of control panel.
This will require the bot to have its own server API for managing its functionality.
This approach, for example, makes it easy to change the thresholds.
There are many dashboard templates available, which means that if you decide to do something like this, you don't even have to create one from scratch. Take a look at Start Bootstrap and Creative Tim , for example .
▍Testing strategies on historical data
Many exchanges give clients access to historical price data. In addition, if you need such data, it is usually easy to obtain.
Their use is very useful for testing trading strategies before actually applying them. This allows a simulation to run using historical data and fake money. This allows you to know how well the thresholds would perform and, if necessary, change these values.
▍Additional information on thresholds and claims
There are several things to keep in mind when placing orders.
First, you need to know that there are two types of orders: limit and market orders. If you do not know anything about this at all, you should definitely read special literature. I'll explain these ideas in just a few words.
Market orders are orders that are executed at the current market price. In most cases, this means their immediate implementation.
Limit orders, on the other hand, are orders that are placed indicating a price that is below the market (in the case of buy orders) or above the market (in the case of sell orders). At the same time, there is no guarantee that these orders will be executed, since the price may not reach the specified value.
The strength of limit orders is that they allow, anticipating market movements, to place orders where, in the trader's opinion, the price may be.
In addition, lower commissions are usually applied to such orders than to market ones. This is due to the fact that what is called a "taker fee" is usually applied to market orders, and what is usually called a "maker fee" is applicable to limit orders.
The reasons these commissions are named this way are because whoever places a market order is simply “taking” the current market price. And limit orders are outside of market prices, they add liquidity to the market and, as a result, “create a market”, for which their creators are rewarded with lower commissions.
Please note that the bot we are considering here is best suited for working with market orders.
And, concluding the conversation about commissions, I want to note that when setting the value
PROFIT_THRESHOLD
, commissions should also be taken into account.
In order to make a profit, the bot must first perform a BUY operation, and then a SELL operation. This means that the commission will be charged twice.
As a result, the bot needs to be configured so that the profit received from sales would at least cover the commissions. Otherwise, the bot will trade at a loss.
Let's think about it, proceeding from the assumption of the use of commissions that do not depend on the amount of the application and on the type of operation. So, the commission for buying an asset for $ 100.00 is $ 0.50. If this asset is sold for $ 100.75 and the same commission is charged, then it turns out that the gross profit is 0.75%. But, in fact, here we are dealing with a net loss of 0.25%.
Now imagine that your bot always closes trades with a net loss. In such a situation, you can quickly lose a lot of money.
Outcome
My main goal was to reveal the concepts you need to know about when developing trading bots. I tried to describe everything in such a way that it was understandable even to those who had never traded on the exchange before. At the same time, I did not tie the narration to any specific programming language.
I have assumed that readers of this material are aware of how to make HTTP requests using their programming language of choice. Therefore, I did not go into the details of programming, focusing on other things.
I told you everything I wanted about developing trading bots. Hopefully you can now create your own bot.
Do you use trading bots?