img

Backtesting Crypto Arbitrage Strategy: Trading Bot Research Idea For 2023 with Python

img
valuezone 10 January 2023

Backtesting Crypto Arbitrage Strategy: Trading Bot Research Idea For 2023 with Python

Hello Dear Readers! Thank you for being part of my community! 🙂

Most people understand crypto arbitrage as the buying and selling of cryptocurrency on different exchanges or platforms in order to take advantage of price differences. This strategy has been lucrative however, now everybody knows about it and it is no longer viable. But, that is not the only way to create an arbitrage strategy within crypto.

We may try to employ an old arbitrage strategy widely used in stock trading. Specifically, looking to capture the spread between two assets, in the crypto case I think It makes sense to start with Bitcoin and Ethereum. But before we employ any strategy or build a software program to automate execution and create a trading bot, we have to do one of the most crucial parts of the work, which is strategy research and development! In this article, we will explore the idea of using the correlation between Bitcoin and Ethereum in combination with a simple technical indicator and explore if there are viable opportunities to screen for in the year 2023.

Project Key Features

  • Download daily prices for BTC and ETH from 1st January 2019 up to 1st January 2023.
  • Calculate: log returns for both coins, then 30-day rolling correlation. Then calculate the daily change in this rolling correlation. Next, estimate BTC RSI indicator with a length of 20 days.
  • Visualize the rolling correlation and analyze for a potential idea.
  • Create an Entry Signal from the available columns and information.
  • Then, calculate the 7-day future return for both coins. Print the average and cumulative return for all potential positions triggered by the signal.
  • Finally, create the arbitrage strategy portfolio.

Before getting started, you’ll need the following :

  • Python: Install the 3.9.7 version.
  • Jupyter Notebook: Install the Individual version of Anaconda for your operating system, it comes up with Jupyter already installed.

Let’s Get Started

Let’s load the packages we would need for the whole project.

import matplotlib.pyplot as plt
import yfinance as yf
import pandas as pd
import numpy as np
import pandas_ta

1. Download Daily Prices For Bitcoin and Ethereum and Calculate Log Returns.

df = yf.download(tickers=['BTC-USD', 'ETH-USD'], start='2019-01-01', end='2023-01-01')['Adj Close']

df.columns = ['btc_close_price', 'eth_close_price']

df['btc_log_ret'] = (np.log(df['btc_close_price']) - np.log(df['btc_close_price'].shift(1)))

df['eth_log_ret'] = (np.log(df['eth_close_price']) - np.log(df['eth_close_price'].shift(1)))

df

Here we first download the prices of bitcoin and ethereum from yahoo finance and select the Adj Close column. Then we rename the columns and calculate log returns.

2. Calculate The Rolling Correlation Between Log Returns And Then Calculate The Daily Change In This Rolling Correlation. Furthermore, Calculate Bitcoin RSI.
df['roll_corr'] = df['btc_log_ret'].rolling(30).corr(df['eth_log_ret'])

df['roll_corr_chg'] = df['roll_corr'].diff()

df['btc_rsi'] = pandas_ta.rsi(close=df['btc_close_price'], length=20)

df['roll_corr'].plot(figsize=(16,4))

plt.title('30-Day Rolling Correlation Looks More Stable After Mid 2021')

plt.show()

After calculating the 30-day rolling correlation, there is an interesting observation, looks like the correlation is really high throughout the whole period, however, there are big drops here or there. But, the correlation is stabilizing after the middle of 2021.

My idea for a signal here is the following:

  • Rolling Correlation to be below 0.8.
  • Positive Change In Rolling Correlation Of 5%.
  • Bitcoin RSI To Be Above 45

When we have those 3 conditions met we will generate a signal. Let’s do it!

3. Create An Entry Signal From The Available Information And Columns We Estimated.

df['entry_signal'] = df.apply(lambda x: 1 if (x['roll_corr']<.8) & (x['roll_corr_chg']>.05) & (x['btc_rsi']>45) else 0, axis=1)

signals_df = df[df['entry_signal']==1]

signals_df

After visualizing all the rows where we have a signal, we can see that they are quite spread. However, there is a small overlap between two specific dates(because we know we are going to use a 7-day look forwardholding period, which means that we need to have at least 7 days between each signal).

This overlap is between 17th May 2019 and 19th May 2019… hmm, what should be our approach here?

Let’s follow the SSOS (Superior State Of Mind) approach and just drop the observation for 19th May 2019. 😁

4. Calculate Future 7-Day Returns For Both Coins And Print Both BTC and ETH Cummulative Return From All Signals.
df['btc_fut_7d_ret'] = df['btc_close_price'].pct_change(7).shift(-7)

df['eth_fut_7d_ret'] = df['eth_close_price'].pct_change(7).shift(-7)

print(f"BTC 7day: {round((signals_df['btc_fut_7d_ret']+1).cumprod()[-1], 3)}")

print(f"ETH 7day: {round((signals_df['eth_fut_7d_ret']+1).cumprod()[-1], 3)}")

In this step, we are calculating the 7-day percent change and then we shift it backward with 7 days, this way we would have it on the same row we want it. Then we are calculating the cumulative return if on each signal we would have gone all-in in the coin and held it for the next 7 days. Looks like that strategy would have made good returns for either of the coins. However! BTC return is 96.7% and ETH return is 146.4%.

💥💥 Here, on the basis of the evidence so far, knowing that I may have a flawed assumption, I would conclude that: On the days of the signal we may construct an Arbitrage Strategy, where we Long Ethereum and Short Bitcoin with the same amount of cash! 💥💥

5. Get A List With All The Dates Corresponding To The Signals Days.

dates_list = (signals_df.index+pd.DateOffset(1)).astype(str).tolist()

dates_list.remove('2019-05-18')

dates_list

In this step, first we create a new dataframe signals_df only for the signals. Then we Move the index of the dataframe with 1 day into the future, so we can use it to select start and end dates for the holding periods. Because the signal would be available to us at the end of a given day, however, the first return would be generated at the end of the next day. Then we create the list of signal dates and remove the overlapping index.

6. Create The Portfolio To Backtest The Arbitrage Strategy And Calculate Daily Returns.

portfolio_df = pd.DataFrame()

for start_date in dates_list:

end_date = (pd.to_datetime(start_date)+pd.DateOffset(7)).strftime('%Y-%m-%d')

temp_df = df[start_date:end_date][['btc_log_ret', 'eth_log_ret']]

portfolio_df = pd.concat([portfolio_df, temp_df])

portfolio_df['portfolio_return'] = portfolio_df['btc_log_ret']*-1 + portfolio_df['eth_log_ret']

df = df.merge(portfolio_df['portfolio_return'], right_index=True, left_index=True, how='left')

df['portfolio_return'].plot(figsize=(16,4))

plt.title('Portfolio Returns When Have Been Invested', fontsize=20)

plt.show()

In this step, we first create an empty dataframe, then for each date in our signal dates list, we estimate the end date to be exactly 7 days in the future. Then, we select from the dataframe we have df the exact period of the position between the start_date and end_date, the we select both log return columns for bitcoin and ethereum. After we have selected that data in the temp_df we just concat it into the portfolio_df. After we have the data selected and sliced and concated together we can move on and calculate the daily portfolio return, which would be bitcoin return multiplied by -1 and ethereum return as it is. (Because we are short bitcoin and long ethereum). Finally, we just merge portfolio_df to our df with a left join, with the goal to have only values where we have a return and elsewhere NaN, so only the 7 holding days after the signal.

7. Calculate Arbitrage Portfolio Cumulative Return And Plot.

np.exp(np.log1p(df['portfolio_return']).cumsum()).plot(figsize=(16,4))

plt.title('Cumulative Return Of Arbitrage Strategy Portfolio', fontsize=20)

plt.show()

Conclusion

In this article, we explored how to re-create and backtest an arbitrage trading strategy based on the Rolling Correlation between Bitcoin and Ethereum.

Our analysis showed that the portfolio of shorting Bitcoin and longing Ethereum with an equal amount of cash yields positive and significant returns over the span of the given study. This suggests that it may be worth considering further research on the potential investment strategy based on this analysis. However, an apparent issue is that the Rolling Correlation itself is stabilizing after the middle of 2021 and the conditions have not been met over the whole of 2022. This may suggest that the strategy is currently out of fashion, however, it may return back in 2023, so keep we may want to keep an eye on it!