Hello, take a look at my strategy. It does really bad. Do you think I should use a completely different strat or should I perfect this one instead? import numpy as np
import pandas as pd
import vectorbt as vbt
import yfinance as yf
from datetime import datetime, timedelta

class IntradayStatArb:
    def __init__(self, coin1, coin2, window=60, entry_threshold=2, exit_threshold=0, risk_per_trade=0.02, interval='5m'):
        self.coin1 = coin1
        self.coin2 = coin2
        self.window = window
        self.entry_threshold = entry_threshold
        self.exit_threshold = exit_threshold
        self.risk_per_trade = risk_per_trade
        self.interval = interval

    def fetch_data(self, period='1mo'):
        end_date = datetime.now()
        start_date = end_date - timedelta(days=30) if period == '1mo' else end_date - timedelta(weeks=1) if period == '1wk' else end_date - timedelta(days=int(period[:-1]))

        coin1_data = yf.download(f'{self.coin1}-USD', start=start_date, end=end_date, interval=self.interval)
        coin2_data = yf.download(f'{self.coin2}-USD', start=start_date, end=end_date, interval=self.interval)

        df = pd.DataFrame(index=coin1_data.index.union(coin2_data.index))
        df[self.coin1] = coin1_data['Close']
        df[self.coin2] = coin2_data['Close']
        df = df.dropna()

        df['ratio'] = df[self.coin1] / df[self.coin2]
        df['zscore'] = (df['ratio'] - df['ratio'].rolling(window=self.window).mean()) / df['ratio'].rolling(window=self.window).std()
        return df

    def generate_signals(self, data):
        long_entries = data['zscore'] < -self.entry_threshold
        long_exits = data['zscore'] >= -self.exit_threshold
        short_entries = data['zscore'] > self.entry_threshold
        short_exits = data['zscore'] <= self.exit_threshold

        return pd.DataFrame({
            'long_entries': long_entries,
            'long_exits': long_exits,
            'short_entries': short_entries,
            'short_exits': short_exits
        }, index=data.index)

    def backtest(self, initial_capital, fee_rate, period):
        data = self.fetch_data(period=period)
        signals = self.generate_signals(data)

        long_entries = signals['long_entries']
        long_exits = signals['long_exits'] | signals['short_entries']  # Exit longs if short signal appears
        short_entries = signals['short_entries']
        short_exits = signals['short_exits'] | signals['long_entries'] # Exit shorts if long signal appears
        
        # Calculate entry prices
        entry_prices = pd.DataFrame(np.nan, index=data.index, columns=[self.coin1, self.coin2])
        entry_prices.loc[long_entries, self.coin1] = data.loc[long_entries, self.coin1]  # Coin 1 entry price
        entry_prices.loc[short_entries, self.coin2] = data.loc[short_entries, self.coin2] # Coin 2 entry price


        # Calculate stop-loss prices SEPARATELY
        long_stop_prices = pd.Series(np.nan, index=data.index)
        short_stop_prices = pd.Series(np.nan, index=data.index)

        long_stop_prices.loc[long_entries] = entry_prices.loc[long_entries, self.coin1] * (1 - self.risk_per_trade)
        short_stop_prices.loc[short_entries] = entry_prices.loc[short_entries, self.coin2] * (1 + self.risk_per_trade)



        # Fixed fractional size for each trade (adjust as needed)
        size = initial_capital / 2 / data[self.coin1].iloc[0]

        coin1_pf = vbt.Portfolio.from_signals(
            data[self.coin1],
            entries=long_entries,
            exits=long_exits,  # Use combined exit signal
            sl_stop=long_stop_prices,
            init_cash=initial_capital / 2,
            fees=fee_rate,
            size=size,
            accumulate=True,
            sl_trail=False
        )

        coin2_pf = vbt.Portfolio.from_signals(
            data[self.coin2],
            entries=short_entries,
            exits=short_exits,  # Use combined exit signal
            sl_stop=short_stop_prices,
            init_cash=initial_capital / 2,
            fees=fee_rate,
            size=size,
            accumulate=True,
            sl_trail=False,
        )
            
        # Calculate combined returns and metrics
        total_returns = coin1_pf.returns() + coin2_pf.returns()
        sharpe_ratio = total_returns.mean() / total_returns.std() * np.sqrt(252)  # Annualized
        max_drawdown = (coin1_pf.drawdown().min() + coin2_pf.drawdown().min()) / 2
        
        # Get trade counts
        coin1_trade_count = coin1_pf.trades.count()
        coin2_trade_count = coin2_pf.trades.count()
        total_trades = coin1_trade_count + coin2_trade_count
        
        # Calculate win rates
        coin1_win_rate = (coin1_pf.trades.win_rate() * 100) if coin1_trade_count > 0 else 0
        coin2_win_rate = (coin2_pf.trades.win_rate() * 100) if coin2_trade_count > 0 else 0
        
        # Calculate combined win rate
        combined_win_rate = (
            (coin1_win_rate * coin1_trade_count + coin2_win_rate * coin2_trade_count) / total_trades
        ) if total_trades > 0 else 0
        
        metrics = {
            'Total Return (%)': (total_returns.sum() * 100),
            'Sharpe Ratio': sharpe_ratio,
            'Max Drawdown (%)': max_drawdown * 100,
            'Number of Trades': total_trades,
            'Win Rate (%)': combined_win_rate,
            coin1 + ' Trades': coin1_trade_count,
            coin2 + ' Trades': coin2_trade_count,
            coin1 + ' Win Rate (%)': coin1_win_rate,
            coin2 + ' Win Rate (%)': coin2_win_rate,
            'Average Return per Trade (%)': (total_returns.sum() * 100) / total_trades if total_trades > 0 else 0
        }
        
        return metrics, coin1_pf, coin2_pf, data

# Example Usage (Intraday):
coin1 = 'BTC'
coin2 = 'ETH'

strategy = IntradayStatArb(
    coin1=coin1,
    coin2=coin2,
    window=120,
    entry_threshold=2,
    exit_threshold=-2,
    risk_per_trade=0.02,
    interval='5m'     
)

metrics, coin1_pf, coin2_pf, data = strategy.backtest(initial_capital=6000, fee_rate=0.001, period='60d')

print("\nBacktest Results:")
for metric, value in metrics.items():
    print(f"{metric}: {value:.2f}")

# Plot results
import matplotlib.pyplot as plt

fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(15, 15))

# Plot z-score
data['zscore'].plot(ax=ax1)
ax1.axhline(y=strategy.entry_threshold, color='r', linestyle='--', label='Entry Threshold')
ax1.axhline(y=-strategy.entry_threshold, color='r', linestyle='--')
ax1.axhline(y=0, color='black', linestyle='-', label='Mean')
ax1.set_title('Z-Score of ' + coin1 + '/' + coin2 + ' Ratio')
ax1.legend()

# Plot price ratio
data['ratio'].plot(ax=ax2)
ax2.set_title(coin1 + '/' + coin2 + ' Price Ratio')

# Plot cumulative returns
cumulative_returns = (1 + coin1_pf.returns() + coin2_pf.returns()).cumprod()
cumulative_returns.plot(ax=ax3)
ax3.set_title('Cumulative Strategy Returns')

plt.tight_layout()
plt.show()