Using Replit to Build a Bitcoin Trading Bot
We’ll see how we can use Replit to write a paper trading bot that trades Bitcoin using Alpaca’s API. You can fork the code we write below from this Replit template.
One of the issues that may arise when running code locally on your personal computer, and is especially important when running trading bots, is that your network connection may become compromised while your bot is deployed. This can lead to your strategy failing to update your portfolio and may lead to undesired outcomes. To circumvent this issue, people often run their code containerized on cloud computing providers, but doing this can be a daunting task for some.
Replit allows you to code in many different languages with custom library support, and then execute it or share it in a runnable form with others. This format makes it convenient to write code and run it in a cloud environment. Running our code on Replit’s cloud environment may decrease our code’s dependence on the reliability of a specific machine. As an example, we’ll see how we can use Replit to write a paper trading bot that trades Bitcoin using Alpaca’s API. You can fork the code we write below from this Replit template. You can use this template to follow along or as the basis of your own strategy.
Getting Started with Replit
On Replit’s page, open up the side menu and click on “Create a new Repl’. A Repl is a project within Replit that is runnable and shareable with others. We’ll create a Python Repl to house our trading bot code. Once you’ve created your repl, you’ll see that now we’re in an integrated development environment (IDE) where we can run our code.
Let’s start off by adding alpaca-trade-api to our dependencies. Within the IDE, on the left hand side, you’ll see a menu option for a package manager. Inside of the package manager, search for ‘alpaca-trade-api’ and install it. This will allow us to use Alpaca to retrieve market data and place trades.
Streaming Live Market Data
Using Alpaca, we can stream live data as it arrives for both stocks and cryptocurrencies.Let’s import alpaca-trade-api
and initialize an instance of the streaming interface. You’ll need to provide your Alpaca API keys. If you don’t have API keys, you can sign up for them here: https://app.alpaca.markets/signup
import alpaca_trade_api as trade_api
API_KEY="<Your API Key>"
SECRET_KEY= "<Your Secret Key>"
stream_api = trade_api.Stream(API_KEY, SECRET_KEY)
Using the stream api, we can subscribe to live minute bars for BTCUSD
using .subscribe_crypto_bars
. These bars will be passed in as a parameter into our handler function OnMinuteBar
as the bars arrive. Finally, to start, we need to call the .run
method.
async def OnMinuteBar(bar):
"""This function will run once a minute and provide the latest
Bitcoin data through the bar parameter
params:
bar: the latest bitcoin minute bar data"""
pass
# Subscribe to live Bitcoin Bar data
stream_api.subscribe_crypto_bars(OnMinuteBar, "BTCUSD")
# Start streaming data
stream_api.run()
Retrieving Portfolio Information
We may need to retrieve information about our portfolio before placing an order. For example, we may want to check how many Bitcoin we already own, before placing an order for more bitcoin. In this example, we’ll check if we own any bitcoin at all, and if we aren’t invested in bitcoin, we will purchase some.
We’ll need to initialize a REST interface for our alpaca-trade-api
to retrieve portfolio information and place paper trades. Let’s pass in our API keys and also pass in the paper URL for Alpaca, which signals to Alpaca that we want to place orders to our paper trading account.
rest_api = trade_api.REST(API_KEY, SECRET_KEY,'https://paper-api.alpaca.markets')
Alpaca’s API provides a method to retrieve the existing position for a specific symbol with the rest_api.get_position(symbol)
. This will return a position object, which contains information about how many shares we own, our profit and loss (PnL) for that asset, our average entry price, and other information.
Something else we need to keep in mind is that, when we call get_position
on an asset we have no position in, Alpaca will return an error. We can use this to our advantage to check if there is an existing position for an asset. Let’s define a function invested_in
which will take in a symbol and return whether we are invested in it. If the try block successfully runs, this means we have an existing position, otherwise, Alpaca has returned an error for a non-existent position.
def is_invested(symbol):
"""Returns True if we own some Bitcoin"""
try:
rest_api.get_position(symbol)
return True
except:
return False
Placing Paper Trades
Now we’re ready to put everything together. We have data for Bitcoin and we can access our portfolio to check if we are invested in Bitcoin. In this example, if we don’t own any Bitcoin we will buy $500 of Bitcoin and hold on to it forever. Let’s go back to our OnMinuteBar
handler and add in our desired investment logic.
We will call our is_invested
function and pass in BTCUSD
. If this function returns True, we don’t want to purchase any more Bitcoin and if it does, we’ll enter a position. The submit_order
method will let us place an order for a symbol. In this example, it will place the order to our paper trading account. The submit_order
method has many parameters that you can learn about in the documentation. We will be using 2 of them; symbol – the symbol we want to trade , notional – which is the dollar amount we want to trade and side – the side we want to enter our position “buy” or “sell”.
async def OnMinuteBar(bar):
"""This function will run once a minute and provide the latest
Bitcoin data through the bar parameter
params:
bar: the latest bitcoin minute bar data"""
print(f"Most Recent Bitcoin Data: \n {bar}")
# if we haven't bought any bitcoin
if not is_invested("BTCUSD"):
# buy 0.01 bitcoin in our paper trading account
print("\n**** BOUGHT $500 of BITCOIN! ****")
rest_api.submit_order(symbol="BTCUSD", notional=500, side=”buy”)
Conclusion
Replit’s IDE allows you to code in many different languages and use custom libraries. Our code will run on Replit’s cloud environment, which will make our bot more less prone to failing when a specific machine fails. Fork the code we wrote above from this Replit template. You can use this code as the basis of your own strategy. To see what other functions the Alpaca API has to offer, check out the alpaca-trade-api repo and the API documentation.
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.