0
$\begingroup$

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.

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.