In this tutorial, we’ll be using Alpaca, Python, Docker, and AWS to create a fully scalable algorithmic crypto trading bot that can execute in your sleep. The strategy that will be used is based on the popular
Without further ado, let’s get started!
In order to create the algorithmic trading bot system used in this article, the first step is to create an Alpaca account. If you don’t have an account yet, you can
After creating an account, you will need to create your API credentials to access Alpaca data via Python. Save both the API Key as well as the Secret Key into a safe place on your computer. These keys will allow us to retrieve live price data for cryptocurrencies as well as execute trades in our paper trading account.
In order to deploy the trading bot, we’ll need an AWS account. You can
Now that we have the accounts necessary to get started, we can start building the trading bot in Python. For this tutorial, we’ll be creating a bot that trades Bitcoin based on the signals of the Supertrend indicator. The Supertrend indicator is a popular tool for crypto swing trading as well as trend following systems but can be adapted to any timeframe. It’s calculated by using the difference between the current average true range and the average price from the most recent price bar.
First, we’ll need to import all of the required dependencies we’ll be using in the bot including smtplib for email communication, pandas-ta for the calculation of the supertrend indicator, and alpaca-trade-api for live market data and paper trading account access. If you have not yet installed some of these dependencies, you can go ahead and pip install them in your terminal.
# Import Dependencies
import smtplib
import pandas as pd
import pandas_ta as ta
import alpaca_trade_api as tradeapi
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
The next step is to define most of the general variables we’ll be needing throughout the program. For the API and Secret keys, you can paste the values you stored from step 1 of this tutorial when creating an Alpaca account.
For the trading strategy, we’ll be buying and selling Bitcoin and each transaction will consist of 1 quantity.
# API Credentials
API_KEY='********'
SECRET_KEY='********'
api = tradeapi.REST(API_KEY, SECRET_KEY,'https://paper-api.alpaca.markets')
# Define crypto related variables
symbol = 'BTCUSD'
qty_per_trade = 1
Next, we have to create a function to check whether the trading account currently holds any Bitcoin. If it does, we can return the quantity of Bitcoin that is being held. If there is no Bitcoin, then the function will just return 0.
This is important because, in the next function which handles the buying and selling, we can focus on buying only if there is currently no Bitcoin 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 = api.list_positions()
for p in positions:
if p.symbol == symbol:
return float(p.qty)
return 0
Finally, we can create a function to retrieve the data, calculate the supertrend indicator signals, and execute the buy/sell orders. First, the function takes in an input of bar data which is used for the live current close price. Using the pandas-ta module discussed earlier, we can calculate the supertrend indicator as a column and concatenate it to the dataframe with pricing information.
If the closing price is above the supertrend indicator, then a buy signal is issued. If the closing price is below the supertrend indicator, then a sell signal is issued. So by using the latest values from the dataframe, we can create boolean values for buy and sell signals.
We can set the code to buy 1 quantity of Bitcoin if there is currently no position and if a buy signal is true. Likewise, we can set the code to sell 1 quantity of Bitcoin if there is currently a position and if a sell signal is true.
Wrapping the entire function in a try/except block ensures that the program will not break due to errors, and will simply print out the error message. Since this is a trading bot and is intended to run throughout market hours, it’s best if the program is continuously running.
# Supertrend Indicator Bot Function
def supertrend_bot(bar):
try:
# Get the Latest Data
dataframe = api.get_crypto_bars(symbol, tradeapi.TimeFrame(1, tradeapi.TimeFrameUnit.Minute)).df
dataframe = dataframe[dataframe.exchange == 'CBSE']
sti = ta.supertrend(dataframe['high'], dataframe['low'], dataframe['close'], 7, 3)
dataframe = pd.concat([dataframe, sti], axis=1)
position = check_positions(symbol=symbol)
should_buy = bar["c"] > dataframe["SUPERT_7_3.0"][-1]
should_sell = bar["c"] < dataframe["SUPERT_7_3.0"][-1]
print(f"Price: {bar["c"]}")
print("Super Trend Indicator: {}".format(dataframe["SUPERT_7_3.0"][-1]))
print(f"Position: {position} | Should Buy: {should_buy}")
# Check if No Position and Buy Signal is True
if position == 0 and should_buy == True:
api.submit_order(symbol, qty=qty_per_trade, side='buy')
message = f'Symbol: {symbol} | Side: Buy | Quantity: {qty_per_trade}'
print(message)
# send_mail(message)
# Check if Long Position and Sell Signal is True
elif position > 0 and should_sell == True:
api.submit_order(symbol, qty=qty_per_trade, side='sell')
message = f'Symbol: {symbol} | Side: Sell | Quantity: {qty_per_trade}'
print(message)
# send_mail(message)
print("-"*20)
except Exception as e:
print (e)
# send_mail(f"Trading Bot failed due to {e}")
A critical aspect of any algorithmic trading system is having a built-in communication system where updates can be sent about any potential errors, transactions, or status. With Python, it’s extremely easy to set up email messaging using the packages email and smtplib.
The first step is to set the variables for the sending and receiving emails. The email that is sending the messages must have the setting
Next, we can set the “from” tag equal to the algorithm name, subject title equal to our bot, and mail content using the input of text for the function. Using smtplib, we can access the gmail server, log in using the credentials given, and send the email message. You can now uncomment all of the send_mail function calls from the previous step!
# Send an Update Email After Every Trade
def send_mail(message_text):
# Define email related variables
sender_email = '**************'
sender_password = '**************'
receiver_email = '**************'
# Create a multipart message and set headers
message = MIMEMultipart()
message['From'] = 'Crypto Trading Algorithm'
message['To'] = receiver_email
message['Subject'] = 'Supertrend Indicator Bot'
# Add body to email and send
mail_content = message_text
message.attach(MIMEText(mail_content, 'plain'))
session = smtplib.SMTP('smtp.gmail.com', 587)
session.starttls()
session.login(sender_email, sender_password)
text = message.as_string()
session.sendmail(sender_email, receiver_email, text)
session.quit()
print ('Mail Sent')
return {"Success": True}
The last step of building the Python bot is to start streaming live market data for Bitcoin from Alpaca. Fortunately, Alpaca makes this process extremely easy.
First, we have to create an instance of the data streaming API by calling the Stream method in which we pass the API keys. We can also specify that we want raw data only from the Coinbase exchange. Then, we can create an asynchronous function to receive the live bar data and within this function, we can call the supertrend_bot function we made in step 2.
Here, we can send an email that the trading bot is now live, subscribe to crypto data, and start streaming live data!
# Create instance of Alpaca data streaming API
alpaca_stream = tradeapi.Stream(API_KEY, SECRET_KEY, raw_data=True, crypto_exchanges=['CBSE'])
# Create handler for receiving live bar data
async def on_crypto_bar(bar):
print(bar)
supertrend_bot(bar)
send_mail("Trading Bot is Live")
# Subscribe to data and assign handler
alpaca_stream.subscribe_crypto_bars(on_crypto_bar, symbol)
# Start streaming of data
alpaca_stream.run()
In the next step, we’ll be deploying the code to AWS Elastic Container Services. To do that, we must first dockerize the python program we have just created.
If you have not already done so, the first step is to
docker -v
Next, you must enter into your project directory in which you have the python program we have created and then create a Dockerfile. Using the terminal, you can simply run the command below!
touch Dockerfile
So far, the project directory should be something similar to what’s below.
.
├── crypto_bot.py
├── Dockerfile
Now, we can start populating the Dockerfile with the information it needs to containerize the application. First, we should pull down a tagged Python base image using the FROM command. The version 3.7.6 can be changed to suit your needs.
Then, we can ADD the source file to the container’s base folder which in this case is crypto_bot.py.
In order to use third-party libraries like alpaca-trade-api and pandas-ta in our docker app, we have to install them using the RUN pip install command.
Lastly, we can add the final command that Docker will run once it’s fully set up. At this point, our Dockerfile is complete and we just have to build it within our terminal.
FROM python:3.7.6
ADD crypto_bot.py .
RUN pip install alpaca-trade-api pandas-ta
CMD [ "python", "./crypto_bot.py" ]
In order to build the docker app, we can return to our terminal in the same project directory and run the following command. You can replace “python-imagename” with whatever name you’d like to call this docker app!
docker build -t python-imagename .
In order to build the docker app, we can return to our terminal in the same project directory and run the following command. You can replace “python-imagename” with whatever name you’d like to call this docker image!
Once the docker app is done building, you can run the following command to run it and you should see that the Python program will run as usual. Hopefully, you should have received an email that the trading bot is live and that trades can be executed.
Keep in mind that with any changes you make to the program, you must rebuild the docker app using the previous command and run it again with the command below. And that’s it, our Python program has been fully dockerized!
docker run -t python-imagename
In order to get our docker app up and running in the cloud, we first need to
Once the CLI is installed, we can run the following command in our terminal to log in to our AWS account and get started with the deployment.
aws configure
After running this command, your terminal will ask you to provide your AWS Access Key ID and your AWS Secret Access Keys. Both of these can be found within your AWS account within security credentials. You can leave the default region name and output format as they currently are.
Now that we’ve logged into our account in the terminal, the next step is to get our local docker app into an ECS repository in AWS. To do that, type in “ECS Repositories” in the search bar and click on the first Features link.
On the ECS repositories screen, you can go ahead and create a new repository, give it a name, and leave the rest of the settings as their default state. Now, you should have a screen that’s similar to the one below.
If you open up the repository and click on the “View push commands” button, you’ll be able to see the commands that are needed to push our local docker app into this repository. Follow the instructions on your screen (similar to the one below) in your local terminal. Your app should now be pushed to AWS!
In the AWS console, navigate to AWS ECS and click the “create cluster” button. For the cluster template, click on “EC2 Linux + Networking” and continue to the next step.
On the next page, you can configure the cluster to suit your specific needs. In this particular case, you only need to change six things.
After these steps, you can go ahead and create the cluster. Once, the process has been completed you should see the ECS cluster has been created, the ECS Instance IAM Policy was attached, and the CloudFormation Stack was created.
Once your cluster has been created, click on the “Task Definitions” button under Clusters in the left-hand sidebar.
Click on create a new task definition, pick EC2 as the launch type compatibility and continue on to the next step.
Enter a task name and scroll down to the section named Task size. Here, you can enter whatever memory and CPU values you are comfortable with.
Then, click on Add container under “Container definitions.” Enter a name once again and for the image, paste the container image URL that you received from AWS. It should be similar to “https://public.ecr.aws/g9l6a0m7/crypto-bot:latest.”
Then, you can scroll to the bottom of the page and create the task definition.
Finally, return back to the main clusters page so that you can see a screen similar to the one below.
Enter into your cluster, and navigate to the Tasks tab. There, you should see an option to run a new task. Click on that button and a new popup wIll appear like the one below.
Select EC2 as the launch type, and under task definition, select the name of the task you created in the previous step. Enter in the name of the cluster you just created under the Cluster dropdown. Then, go ahead and run the task.
At this point, the app should be up and running on AWS!
In this tutorial, we covered everything from creating a live trading bot and implementing email communication to dockerizing a Python program and deploying it onto AWS ECS. While the strategy in the article was basic and not intended to be used as a full trading system, the processes to build a fully scalable system around a Python bot are the same so you can now automate anything you’d like!
Thanks for reading, and I hope you learned something about creating algorithmic trading bots with the Alpaca Crypto API!
Please note that this article is for general informational purposes only. All screenshots are for illustrative purposes only. Alpaca does not recommend any specific cryptocurrencies.
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. Depending on your location, cryptocurrency services may be provided by West Realm Shires Services, Inc., d/b/a FTX US (NMLS #1957771).
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, or FTX US respectively, are not registered or licensed, as applicable.
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
Please see alpaca.markets and Alpaca’s Disclosure Library for more information.