here is a program description and the code provided below, fix issue you find:

### EMA Crossover Backtesting Application

This Streamlit application allows users to backtest an Exponential Moving Average (EMA) crossover trading strategy on a specified stock ticker. The application provides performance metrics for both the EMA crossover strategy and a simple buy-and-hold strategy. Here's a detailed breakdown of the functionality:

#### User Inputs:
1. **Stock Ticker**: Users can input the stock ticker symbol (e.g., AAPL).
2. **Candle Interval**: Users can select the interval for the candlestick data (e.g., 1h, 1d, 1wk, 1mo).
3. **Short EMA Period**: Users can specify the period for the short EMA.
4. **Long EMA Period**: Users can specify the period for the long EMA.
5. **Start Date**: Users can select the start date for the backtest.
6. **End Date**: Users can select the end date for the backtest.

#### Functionality:
1. **Download Data**: The application downloads historical stock data from Yahoo Finance based on the user inputs.
2. **Calculate EMAs**: It calculates the short and long EMAs for the specified periods.
3. **Generate Trading Signals**: The application generates buy and sell signals based on the crossover of the short and long EMAs.
4. **Track Trades**: It records trade entries and exits, calculates drawdowns, and keeps track of the holding period.
5. **Calculate Performance Metrics**:
   - **Total Return**: The total return of the EMA crossover strategy.
   - **Win Rate**: The percentage of profitable trades.
   - **Sharpe Ratio**: A measure of risk-adjusted return.
   - **Max Drawdown**: The maximum observed loss from a peak to a trough.
6. **Buy and Hold Metrics**: It also calculates performance metrics for a buy-and-hold strategy for comparison.
7. **Plotting**: The application uses `mplfinance` to plot a candlestick chart with the short and long EMAs, and buy/sell signals. The legend is manually added to the chart for clarity.
8. **Display Results**: The results, including performance metrics and trade logs, are displayed in the Streamlit application.

#### Output:
- **Candlestick Chart**: A visual representation of the stock price, EMAs, and trading signals.
- **Performance Metrics**: Detailed metrics for both the EMA crossover strategy and the buy-and-hold strategy.
- **Trade Logs**: A table displaying the details of each trade executed by the EMA crossover strategy.

This application provides a comprehensive tool for backtesting an EMA crossover strategy and comparing its performance to a buy-and-hold approach.

Code:
import streamlit as st
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
import warnings
import mplfinance as mpf
warnings.filterwarnings('ignore')

# Streamlit frontend
st.title('EMA Crossover Backtesting Application')

# User inputs
ticker = st.text_input('Enter Stock Ticker (e.g., AAPL):', 'AAPL')

interval_options = ['1h', '1d', '1wk', '1mo']
interval = st.selectbox('Select Candle Interval:', interval_options, index=1)

ema_short = st.number_input('Short EMA Period:', min_value=1, value=12)
ema_long = st.number_input('Long EMA Period:', min_value=2, value=26)

# Set default start and end dates
default_start_date = datetime(2020, 1, 1)
default_end_date = datetime.today()

start_date = st.date_input('Start Date:', value=default_start_date, min_value=datetime(2000, 1, 1), max_value=default_end_date)
end_date = st.date_input('End Date:', value=default_end_date, min_value=start_date, max_value=default_end_date)

if st.button('Run Backtest'):
    # Map interval to yfinance valid intervals
    interval_mapping = {'1h': '1h', '1d': '1d', '1wk': '1wk', '1mo': '1mo'}

    data = yf.download(ticker, start=start_date, end=end_date, interval=interval_mapping[interval])
    if data.empty:
        st.error('No data found. Please adjust your inputs.')
        st.stop()

    # Calculate EMAs
    data['EMA_short'] = data['Close'].ewm(span=ema_short, adjust=False).mean()
    data['EMA_long'] = data['Close'].ewm(span=ema_long, adjust=False).mean()

    # Implement the EMA crossover strategy
    data['Position'] = np.where(data['EMA_short'] > data['EMA_long'], 1, -1)

    # Generate trading signals
    data['Signal'] = data['Position'].diff()

    # Initialize lists to store trade entries and exits
    trade_entries = []
    trade_exits = []
    entry_price = []
    exit_price = []
    drawdowns = []

    in_position = False
    entry_index = None

    for i in range(len(data)):
        if data['Signal'].iloc[i] == 2:  # Buy signal
            if not in_position:
                in_position = True
                trade_entries.append(data.index[i])
                entry_price.append(data['Close'].iloc[i])
                entry_index = i
        elif data['Signal'].iloc[i] == -2:  # Sell signal
            if in_position:
                in_position = False
                trade_exits.append(data.index[i])
                exit_price.append(data['Close'].iloc[i])
                
                # Calculate drawdown during the trade
                trade_data = data['Close'].iloc[entry_index:i+1]
                trough_price = trade_data.min()
                drawdown = (trough_price - entry_price[-1]) / entry_price[-1]
                drawdowns.append(drawdown)
        elif in_position:
            # Update drawdown during the holding period
            trade_data = data['Close'].iloc[entry_index:i+1]
            trough_price = trade_data.min()
            drawdown = (trough_price - entry_price[-1]) / entry_price[-1]

    # Handle the case where we are still in position at the end
    if in_position:
        trade_exits.append(data.index[-1])
        exit_price.append(data['Close'].iloc[-1])
        
        # Calculate drawdown during the trade
        trade_data = data['Close'].iloc[entry_index:]
        trough_price = trade_data.min()
        drawdown = (trough_price - entry_price[-1]) / entry_price[-1]
        drawdowns.append(drawdown)

    # Prepare a DataFrame with trade details
    trades = pd.DataFrame({
        'Entry Time': trade_entries,
        'Exit Time': trade_exits,
        'Entry Price': entry_price,
        'Exit Price': exit_price,
        'Drawdown': drawdowns
    })

    # Calculate returns per trade
    trades['Return'] = (trades['Exit Price'] - trades['Entry Price']) / trades['Entry Price']
    trades['Return (%)'] = trades['Return'] * 100

    # Calculate total return of the strategy
    total_return = trades['Return'].sum()

    # Calculate win rate
    win_rate = len(trades[trades['Return'] > 0]) / len(trades) if len(trades) > 0 else 0

    # Calculate Sharpe ratio
    period_return = data['Close'].pct_change().dropna()
    average_return = period_return.mean()
    std_return = period_return.std()

    # Annualization factors based on interval
    if interval == '1d':
        annualization_factor = np.sqrt(252)  # Trading days in a year
    elif interval == '1wk':
        annualization_factor = np.sqrt(52)  # Trading weeks in a year
    elif interval == '1mo':
        annualization_factor = np.sqrt(12)  # Trading months in a year
    elif interval == '1h':
        annualization_factor = np.sqrt(252 * 6.5)  # Trading hours in a year (assuming 6.5 hours per trading day)

    sharpe_ratio = (average_return / std_return) * annualization_factor

    # Calculate max drawdown
    max_drawdown_overall = trades['Drawdown'].min() * 100  # As a percentage

    # Buy and Hold Strategy Metrics
    buy_and_hold_return = (data['Close'].iloc[-1] - data['Close'].iloc[0]) / data['Close'].iloc[0]

    # Calculate max drawdown for buy and hold
    rolling_max = data['Close'].cummax()
    daily_drawdown = (data['Close'] - rolling_max) / rolling_max
    buy_and_hold_max_drawdown = daily_drawdown.min() * 100

    # Calculate Sharpe ratio for buy and hold
    buy_and_hold_sharpe = (average_return / std_return) * annualization_factor

    # Calculate win rate for buy and hold
    buy_and_hold_trades = pd.DataFrame({
        'Entry Time': [data.index[0]],
        'Exit Time': [data.index[-1]],
        'Entry Price': [data['Close'].iloc[0]],
        'Exit Price': [data['Close'].iloc[-1]],
        'Return': [buy_and_hold_return]
    })
    buy_and_hold_win_rate = len(buy_and_hold_trades[buy_and_hold_trades['Return'] > 0]) / len(buy_and_hold_trades) if len(buy_and_hold_trades) > 0 else 0

    # Prepare data for mplfinance
    data_for_plot = data.copy()
    data_for_plot.index.name = 'Date'

    # Create signal columns with NaNs
    data_for_plot['Buy_Signal_Price'] = np.nan
    data_for_plot['Sell_Signal_Price'] = np.nan
    data_for_plot.loc[data['Signal'] == 2, 'Buy_Signal_Price'] = data_for_plot['Close']
    data_for_plot.loc[data['Signal'] == -2, 'Sell_Signal_Price'] = data_for_plot['Close']

    # Create additional plots for EMA and signals
    apds = [
        mpf.make_addplot(data_for_plot['EMA_short'], color='green', width=1),
        mpf.make_addplot(data_for_plot['EMA_long'], color='red', width=1),
        mpf.make_addplot(data_for_plot['Buy_Signal_Price'], type='scatter', markersize=100, marker='^', color='blue'),
        mpf.make_addplot(data_for_plot['Sell_Signal_Price'], type='scatter', markersize=100, marker='v', color='purple')
    ]

    # Plot candlestick chart
    fig, axlist = mpf.plot(
        data_for_plot,
        type='candle',
        addplot=apds,
        returnfig=True,
        title=f'{ticker} EMA Crossover Strategy',
        style='yahoo',
        volume=True
    )

    # Add legend manually
    ax = axlist[0]  # Get the main axis
    ax.plot([], [], color='green', label='Short EMA')
    ax.plot([], [], color='red', label='Long EMA')
    ax.scatter([], [], color='blue', marker='^', label='Buy Signal')
    ax.scatter([], [], color='purple', marker='v', label='Sell Signal')
    ax.legend()

    # Display the plot in Streamlit
    st.pyplot(fig)

    # Display performance metrics for EMA strategy
    st.subheader('EMA Crossover Strategy Performance Metrics')
    st.write(f"Total Strategy Return: {total_return * 100:.2f}%")
    st.write(f"Win Rate: {win_rate * 100:.2f}%")
    st.write(f"Sharpe Ratio: {sharpe_ratio:.2f}")
    st.write(f"Max Drawdown: {max_drawdown_overall:.2f}%")

    # Display performance metrics for Buy and Hold strategy
    st.subheader('Buy and Hold Strategy Performance Metrics')
    st.write(f"Total Return: {buy_and_hold_return * 100:.2f}%")
    st.write(f"Win Rate: {buy_and_hold_win_rate * 100:.2f}%")
    st.write(f"Sharpe Ratio: {buy_and_hold_sharpe:.2f}")
    st.write(f"Max Drawdown: {buy_and_hold_max_drawdown:.2f}%")

    # Display trade logs
    st.subheader('Trade Logs')
    st.dataframe(trades)