# Pairs trading back-test in python

I've been working on this code for weeks now, and I'm still not convinced by the results. I think there's a problem with the computation of the profit and loss, but I'm not sure. I would love some help.

for i in range(0, len(df)):
if i < 1:
prev_signal = 0
else:
prev_signal = signals0[i - 1]

norm_spread, curr_beta = calc_norm_spread(pair, lookback_dict, i)
curr_spread = norm_spread.iloc[-1]  # Extract the last value of the Series

if days_since_trade % 6 == 0:
# Update beta every 5 days
beta = curr_beta
if (curr_spread >= sellth and prev_signal == 0) or (curr_spread <= buyth and prev_signal == 0):
# Enter trade at current_beta
signals0[i] = -1 if curr_spread >= sellth else 1
days_since_trade = 1  # Reset the days since trade
beta = curr_beta  # Set beta to current beta
elif closelong < curr_spread and prev_signal == 1:
signals0[i] = 0
elif closeshort > curr_spread and prev_signal == -1:
signals0[i] = 0
else:
signals0[i] = prev_signal

if days_since_trade > 0:
days_since_trade += 1

if abs(beta) <= 1:
pos0[i] = -signals0[i] * beta
pos1[i] = signals0[i]
else:
pos0[i] = -signals0[i]
pos1[i] = signals0[i] / beta

df['pos0'] = pos0
df['pos1'] = pos1

pos0[-1] = 0
pos1[-1] = 0

df['pos0_diff'] = df['pos0'].diff().abs()
df['pos1_diff'] = df['pos1'].diff().abs() # units buyed or selled for transactions cost

df['logret0'] = np.log(df['open0'] / df['open0'].shift(1))
df['logret1'] = np.log(df['open1'] / df['open1'].shift(1))

df['logret0'] = df['logret0'] * df['pos0'].shift() - (df['pos0_diff'] * fee)
df['logret1'] = df['logret1'] * df['pos1'].shift() - (df['pos1_diff'] * fee)

df['cumulative_return0'] = df['logret0'].dropna().cumsum().apply(np.exp)
df['cumulative_return1'] = df['logret1'].dropna().cumsum().apply(np.exp)

last_cumulative_return0 = df['cumulative_return0'].iloc[-1] -1 # Get the last value
last_cumulative_return1 = df['cumulative_return1'].iloc[-1] -1

total_return = (last_cumulative_return0 + last_cumulative_return1)
pair_returns.append((pair,total_return))

Final_returns = pd.DataFrame(pair_returns, columns=['Pair', 'Last_Cumpair_Return'])
freturn =  Final_returns['Last_Cumpair_Return'].mean() *100


I'm convinced with the beta rebalancing, but I don't know if the simple addition of the last raw return is correctly using the portfolio weights. I also tried this other approach:

        if i > 0:
returns0 = (df['open0'].iloc[i] - df['open0'].iloc[i - 1]) * pos0[i-1] / df['open0'].iloc[i - 1]
returns1 = (df['open1'].iloc[i] - df['open1'].iloc[i - 1]) * pos1[i-1] / df['open1'].iloc[i - 1]
pair_returns.append(returns0 + returns1)
capital += returns0 + returns1


But I saw that linearly combining returns is incorrect in an article of Hudson&Thames, 'The correct vectorized backtesting for pairs trading'. Thanks in advance.