How to backtest a pair trading strategy using Python?
How to backtest a pair trading strategy using Python?
Backtesting a pair trading strategy with Python is a more complex example, but our backtester should be capable of executing this strategy. The complexity lies in the fact that we need to have the data of two assets in the same DataFrame. First, let's define the strategy. The assets we are trading are Roku (ROKU) and Netflix (NFLX), as they have a cointegration relationship according to our previous articles and analysis. If one stock has risen by 5% or more relative to the other stock over the past five days, we will take a position (buy). We will sell the one with the higher price and buy the one with the lower price until the spread reverses. Let's start setting up and quickly processing the data:
Introduction
Backtesting a pair trading strategy with Python is a more complex example, but our backtester should be capable of executing this strategy. The complexity lies in the fact that we need to have the data of two assets in the same DataFrame. First, let's define the strategy.
The assets we are trading are Roku (ROKU) and Netflix (NFLX), as they have a cointegration relationship according to our previous articles and analysis.
If one stock has risen by 5% or more relative to the other stock over the past five days, we will take a position (buy). We will sell the one with the higher price and buy the one with the lower price until the spread reverses. Let's start setting up and quickly processing the data:
Using the code
import pandas as pd
symbol = "NFLX,ROKU"
start_date = "2023-01-01"
data = DataHandler(
symbol=symbol,
start_date=start_date,
).load_data()
data = pd.merge(
data["NFLX"].reset_index(),
data["ROKU"].reset_index(),
left_index=True,
right_index=True,
suffixes=("_NFLX", "_ROKU"),
)
data = data.rename(columns={"close_ROKU": "close"})
data.head()
Now, we just need to establish the trading logic and then we can run the backtester.
strategy = Strategy(
indicators={
"day_5_lookback_NFLX": lambda row: row["close_NFLX"].shift(5),
"day_5_lookback_ROKU": lambda row: row["close"].shift(5),
},
signal_logic=lambda row: (
1
if row["close_NFLX"] > row["day_5_lookback_NFLX"] * 1.05
else -1 if row["close_NFLX"] < row["day_5_lookback_NFLX"] * 0.95 else 0
),
)
data = strategy.generate_signals(data)
backtester = Backtester()
backtester.backtest(data)
backtester.calculate_performance()
Final Portfolio Value: $14,387.50
Total Return: 43.88%
Annualized Return: 34.80%
Annualized Volatility: 55.77%
Sharpe Ratio: 0.62
Sortino Ratio: 0.74
Maximum Drawdown: -39.86%
Support by Alltick API
留言
發佈留言