How to Write an Automated Crypto PERP Trading Bot in Python with Less than 100 Lines of Code
Hello again. Time for another groundbreaking tutorial on cool things with Python and DeFi. This time we will build a fully automated PERP Crypto trading bot including risk management and a strategy in less than 100 lines of Python code.
And yes, it is quite simple, so even absolute beginners can follow along, but I just love running bots like this. It is such a satisfying feeling to know that this simple script works for me round the clock and might make money even while I sleep :D
Hint: Of course I never sleep … ;)
What are PERPS?
Long story short PERPS stands for perpetual futures and allow you to trade crypto currencies with leverage and go long and short. I will explain this briefly to you if you have never heard of it:
Leveraged trading means:
You just need 100$ to trade 20.000$ worth of ETH or other tokens. The amount of money you need (100$) is called margin and acts as a security deposit for the PERP provider. And the ratio between the margin (100$) and the amount you can trade (20.000$) is called leverage. Different providers offer different leverage depending on which token you want to trade. For the big ones like BTC or ETH it is usually around 10–20, but some platforms even offer leverage up to 50 or 100.
Example:
If you open an ETH PERP position with 20x leverage and 100$ margin, you have a 20.000$ position size. If the price of ETH moves up 1% you earn 200$ which gives you a total return of 300% on your initial investment.
The caveat: if the price drops by just 1% your initial 100$ deposit is gone.
Which means total loss, 100% down … no chance to recover … and this happens to most beginners quite fast especially when greed and other emotions take over ;)
The second specialty of PERPs is that you can profit when prices fall. In trading if you profit from rising prices it is called “going long” and if you profit from falling prices the term is “going short” or opening a short position.
In theory it works like this: You borrow 1 ETH from the provider, again with a margin amount as a security deposit, with the promise to return it later. Let’s say the price of ETH is 2.000$ at this time. Now you wait a few days and the price drops to 1.500$. In this case, you buy that 1 ETH now for 1.500$, pay back that 1 ETH you already borrowed from the provider, and pocket 500$ in winnings. Again, if the price of Ethereum increases, your initial deposit might be lost.
So that was a very short introduction to the most relevant terms and principles. If you are a beginner to this, I highly recommend reading a trading book for beginners.
The best trading introduction for beginners i found so far is: The Trading Code (available on Amazon).
It is not crypto related but explains in simple terms all the fundamentals including the basics of chart analysis and successful strategies for absolute beginners. You can easily adapt this knowledge to crypto trading later.
Hint: Perps have some very special features, for example how pricing works. Google for Oracle pricing or funding rates. That also opens up a bunch of other opportunities for interesting trading strategies like funding rate arbitrage or oracle price manipulation. This is the beginners tutorial, so we don’t go into the details here, but it is very interesting ;)
Why PERPS?
There is a good chance that most people use them to gamble in order to gain a quick fortune and lose most of their money. But they also offer some real use cases if you trade with proper risk management like I will show you today.
Besides that, they are a way to manage risks. Let’s say you’re staking 1.000 TIA tokens worth 18.000$ at the time of writing. You want to farm possible airdrops and benefit from the staking APY.
Besides all the other risks, you have price risks now. When the TIA price decreases, you lose money. If some bad news comes out, the price might fall very drastically in a short time. However, your money is staked with an unstake period of 21 days… which means, you would have to stand by and watch losing money …
But:
Perps can be an effective tool for risk management in such situations. If the bad news appears, you open a short position worth your 18.000$ … if the price keeps falling, your short position earns money. If the price rises, your staked TIA will profit. And even if the price stays the same, price risk is eliminated.
Essentially, this is called a hedge, a trade that eliminates a certain risk.
Strategies like shorting with a PERP and holding the token at the same time are known as Cash and Carry strategies. They are a subset of Delta neutral strategies. These are strategies where you try to reduce the price risk (delta).
Hint: you can find some of those strategies on the orbitrum marketplace as well.
Another opportunity is to lock in airdrop prices. Let’s assume you know that you will receive an Airdrop of 1.000 Tokens but can only claim it in a month or the tokens are vested / locked. Same platforms like the one we are using today allow you to trade PERPS on not yet launched tokens. So if the price is around 5$, you could lock in that price by opening a short position worth 5.000$. If the price dumps when people sell their Airdrop, you again are delta neutral and just pocket in the profits.
Okay … many new words and i could write books about this … and probably will, but i gave you the most significant terms if you want to dive deeper ;)
Where can you trade PERPS?
There are dozens of platforms. My current favorite is Aevo but you can also check out Hyperliquid or the established ones like GMX and DyDx. This tutorial will use Aevo for special reasons you might already know. But besides that, they have one of the best designed APIs I’ve seen so far in this space. Easy to use, well structured and good documentation of most features. Caveats are that some features are undocumented and their official Python SDK seems unmaintained and broken. But I wrote my own SDK to work with Aevo to simplify our task at hand. This SDK you can find here on pypi or here on github.
Hint: To learn more about Aevo, listen to this podcast: https://blockworks.co/podcast/0xresearch/063be016-be1e-11ee-a7df-73253e4ed8ed i liked it.
What we are building today
Today, we’ll look at a fully automated trading bot. A trading bot always consists of the following components:
Risk Management: Stop Losses, Take Profits, Risk Reward Ratio, etc.
Trading Logic: Finding entries and exits in the chart to decide when to open or close a position
Bot loop: Basically an endless loop monitoring the market and executing trades when the trading logic conditions are satisfied
Bonus: Logging / Monitoring / Telegram Notifications / Backtesting, etc. But as we want to create a bot in less than 100 lines today, I will leave this as homework ;)
You can take the same approach to automate any kind of strategy and also the mentioned delta neutral ones. Just exchange the trading logic or contact me on crjameson.xyz or twitter and let’s discuss your ideas.
The Code 1: Riskmanagement
Our risk management consists of a few variables we define. I will explain them in the code comments:
# define our risk management parameters - adapt this to your needs
# how much leverage do we want to use - this also depends on the asset but for the big ones 20x is the max
LEVERAGE = 20
# how much of our initial balance do we want to risk per trade in percent
# 1% means if we have a balance of 500$ our margin per trade is 10$
# The margin multiplied with the leverage is the position size (eg. 10$ * 20 = 200$)
RISK_PER_TRADE_PERCENT = 2
# what is our risk reward ratio - this is the ratio of the take profit to the stop loss
# eg. 2 means we want to win 2 times more than we are willing to lose and only need to win 33% of the trades to be profitable
RISK_REWARD_RATIO = 2
# what is our stop loss in percent - this is the max we are willing to lose per trade
# this value refers to the entry price of the underlying asset so for example ETH
# so if the ETH price drops by 0.1% we sell the position and limit our losses
STOP_LOSS_PERCENT = 0.1
# what is our take profit in percent - this is the max we want to win per trade
# so if the ETH price rises by 0.2% we sell the position with profits
TAKE_PROFIT_PERCENT = STOP_LOSS_PERCENT * RISK_REWARD_RATIO
And that’s it. These parameters should be defined at least in every trading strategy. You need to limit your losses and know when to take profits.
The Code 2: Trading logic
For the trading logic we are monitoring the prices for so called breakouts. A period in the chart where the price drastically falls or rises.
Hint: I recommend most beginners start with a long only strategy or a short only strategy, depending on the overall market outlook.
Again: Read this book to learn about basic strategies like breakouts: The Trading Code
The strategy we use is based on a simplified version of the Donchian Channels. You can read all the details here.
There are many interesting Python libraries like pandas-ta, pandas, ta-lib, etc. having indicators like this already built in. But you need to know about pandas, dataframes, OHLC data and lots of other details. So, to make things as simple as possible, I will give you a very basic code to implement this for your self.
The basic strategy idea:
We monitor the current price of an asset every REQUEST_INTERVAL_SECONDS seconds.
We store the last DON_MAX_PERIOD prices in a queue.
Then we check for the min and max prices. If our current price is above the maximum, we open a long position and if it is below, we open a short position.
To manage risks, we set appropriate Stop Losses and Take Profits in each case.
This is a bit simplified but a very helpful starting point as some of the most successful trading strategies ever are based on trend-following and breakouts.
Hint: I changed the values of the variables so that you see a result as fast as possible. In practice, you should use this strategy on a higher time frame and check every 15 minutes or even every hour.
# the length of the queue is the period of the donchian channel
# 120 means we look at the last 120 prices, one request every 30 seconds = 1h timeframe
DON_MAX_PERIOD = 12
REQUEST_INTERVAL_SECONDS = 30
def run_trading_strategy(client, instrument, margin_per_position, last_prices):
if positions := client.get_positions():
# we always trade only one position at the same time, so just print the details and start over
print(f"open position: asset: {positions[0].asset} amount: {positions[0].amount} unrealized_pnl: {positions[0].unrealized_pnl}")
print(f"prices: current: {positions[0].mark_price} entry: {positions[0].avg_entry_price} liquidation: {positions[0].liquidation_price}")
time.sleep(60)
return
price = aevopy.get_index(asset=instrument.underlying_asset)
# our strategy only works when we have 120 prices in our queue
if len(last_prices) < DON_MAX_PERIOD:
print(f"collecting data: {price.timestamp}: price: {price.price}")
else:
min,max = min(last_prices),max(last_prices)
print(f"{price.timestamp}: price: {price.price} local min: {min(last_prices)} local max: {max(last_prices)}")
position_size = int(margin_per_position // instrument.index_price)
if price.price > max:
print(f"price: {price.price} is above max: {max} - open long position")
buy(client, instrument, position_size)
# we reset the queue after we opened a position
last_prices.clear()
if price.price < min:
print(f"price: {price.price} is below min: {min} - open short position")
sell(client, instrument, position_size)
last_prices.clear()
last_prices.append(price.price)
And that is how our trading strategy looks like. Quite simple but with a few modifications and the right market, it has potential.
And if you hedge your positions on a different Perp platform … you might see even more interesting opportunities here to make some money while having fun ;)
The Code 3: Bot loop
So the last step is to run that trading strategy in an endless loop and write the buy/sell functions and the functions for take profits and stop losses. For trading related tasks i wrote and published the aevopy library which you can use. I published it in a separate repository on github or it is available on pypi.org as a package.
Hint: The official Aevo Pthon SDK has some bugs and seems to be unmaintaned already and another unofficial one has the same issues. Thats why i wrote my own. Although I do not implement all of the features of the official API in my aevopy library, I will have the ability to fix bugs or add required features when requested.
def buy(client, instrument, position_size):
order = client.buy_market(instrument.instrument_id, amount=position_size)
print(f"order: {order}")
stop_loss_price = order.avg_price * (1 - STOP_LOSS_PERCENT / 100)
order = client.sell_stop_loss(instrument.instrument_id, trigger=stop_loss_price)
take_profit_price = order.avg_price * (1 + TAKE_PROFIT_PERCENT / 100)
order = client.sell_take_profit(instrument.instrument_id, trigger=take_profit_price)
def sell(client, instrument, position_size):
order = client.sell_market(instrument.instrument_id, amount=position_size)
print(f"order: {order}")
stop_loss_price = order.avg_price * (1 + STOP_LOSS_PERCENT / 100)
order = client.buy_stop_loss(instrument.instrument_id, trigger=stop_loss_price)
take_profit_price = order.avg_price * (1 - TAKE_PROFIT_PERCENT / 100)
order = client.buy_take_profit(instrument.instrument_id, trigger=take_profit_price)
if __name__ == "__main__":
# the client takes the API key and secret from the environment
client = aevopy.AevoClient()
print(f"client: {client.account.wallet_address} collecting data and start trading...")
portfolio = client.get_portfolio()
print(f"available portfolio margin balance: {portfolio.user_margin.balance}")
# this is the amount we can spend on each trade including leverage
margin_per_position = portfolio.user_margin.balance / 100 * RISK_PER_TRADE_PERCENT * LEVERAGE
# get the market details about the asset we want to trade - TIA in this example
instrument = aevopy.get_markets(asset="TIA")
print(f"instrument: {instrument}")
last_prices = collections.deque(maxlen=DON_MAX_PERIOD)
while True:
try:
run_trading_strategy(client, instrument, margin_per_position, last_prices)
except Exception as e:
print(f"error: {e} trying again...")
time.sleep(REQUEST_INTERVAL_SECONDS)
Hint: I had a few timeout exceptions when running the loop, Aevo was quite early at that time. Always make sure you catch all exceptions when running your bot loop!
Putting everything together
You will need an Aevo trading account. You can create one here:
https://app.aevo.xyz/r/Tulip-Sturdy-Laffont
Afterwards you can setup and execute the full bot code.
You can find the full source code as always in my Python and DeFi repository here:
https://github.com/crjameson/python-defi-tutorials
Check out the Bots section for perpbot.py.
To get everything up and running, setup a new Python virtual environment and activate it:
python3.11 -m venv pydefi_env
source pydefi_env/bin/activate
and install the required packages:
pip install dotenv
pip install aevopy
Then create the .env file in the same directory where you execute the script with the following content:
AEVO_SIGNING_KEY =
AEVO_WALLET_ADDRESS =
AEVO_API_KEY =
AEVO_API_SECRET =
AEVO_ENV = mainnet
You can get the signing key and the other values from your user settings on Aevo.
And that’s it. You can execute the script now (make sure your virtual env is activated) and your bot will start trading. I configured the parameters so you can see results fast. For production use this is not optimal!
python bots/perpbot/perpbot.py
client: 0xXXXXXXXXXXXXXX collecting data and start trading...
available portfolio margin balance: 299.647778
instrument: Instrument(instrument_id=8588, instrument_name='TIA-PERP', instrument_type='PERPETUAL', underlying_asset='TIA', quote_asset='USDC', price_step=0.0001, amount_step=1.0, min_order_value=10.0, mark_price=17.230582, index_price=17.229975, is_active=True, max_leverage=20.0)
collecting data: 1707226378000018891: price: 17.231074
The bot will request the price every 30 seconds until it has 120 prices in the queue and then begin trading our strategy.
Hint: You could also start with a Testnet account but thats somehow boring imho so i always use a very small amount like 50–100$ to test new things. At least than i know the performance under real circumstances. Testnets might yield different results!
Very important Hint:!!!! Do not trade this with your life savings or even expect positive results. !!! This is meant to be a starting point for developing your own trading strategy and learn the basics. There are some clues in this article on how to make this profitable ;)
Last Hint: To have your bot running 24/7 i recommend running it either at home if you have a stable connection on a Raspberry Pi (around 100 $) or you can rent a dedicated server starting at around 30$ / month. Do not use a cheap VPS as they use shared hardware and memory which might put your private keys at risk. Always use full disc encryption when dealing with sensitive data like private keys.
Where to go from here
Now first things first. Thank you for taking the time to read all this and I hope you find this as exciting as I do ;) If you have any questions or comments, let me know.
Some inspiration for for you:
add notifications / logging / telegram connection
test different parameters for the strategy and optimize the different parts like entry, exit or stop loss
find and test new strategies
write an automatic hedging bot, which scans your wallet for tokens to hedge
farm some Perp protocols which are incentivized
read about statistical arbitrage — i have some very promising strategies running here
read about market making algorithms and how they work
… and many interesting things more … i might be doing a few follow up posts about some of the strategies
Algorithmic trading is a fascinating field and from simple pattern matching algorithms like the one we used here, up to Arbitrage or High Frequency Trading where you have win rates over 99% there is a whole world to be explored.
I use my bots mostly on very niche protocols / chains where there is little or no competition and which are too small for the big smart players. There are hundreds of opportunities, so feel free to join me on this journey.
If you would like to learn more, I would recommend checking out the following resources:
https://www.freqtrade.io/ a complete bot development framework in Python, very well documented, amazing support and includes a user interface, CEX trading connection to over 200+ CEXes, Telegram interface and backtesting. I am using this to backtest and develop strategies, and utilize the hyperoptimizer to automatically find effective parameters for strategies like the one above. For example you can use it to find the perfect trading timeframe and the perfect length of our Donchian channel by backtesting millions of combinations automatically over a chosen period of time. It also offers some interesting AI/ML capabilities to optimize your strategies. I am also using freqtrade to input signals to my PERP trading bots by using the bot call hook.
https://bettersystemtrader.com/ — i regularly listen to this podcast, they have some great episodes on Spotify about breakout trading and other strategies, highly recommended
If you have an exciting trading idea, but don’t know how to implement it, let me know and we can discuss it :)