Questions about charts

Why “Trading Signals for Strategy” chart had different time period as compared to “Returns of One Data Point” & “Cumulative Returns” charts? Understand that the strategy signals are based on 15 min chart & 15 min csv data. Does this means that “Returns of One Data Point” & “Cumulative Returns” charts are wrong? Please help.

Course Name: Technical Indicators Strategies in Python, Section No: 10, Unit No: 11, Unit type: Notebook

Great question. In the notebook, we are using get_strategy_returns() function from the utils. You can see the function definition by running get_strategy_returns?? in the last line of the notebook. There is a parameter called bars_to_plot and it is set to 1500. We are passing this while plotting trading signals for the strategy. There are more than 1500 values for trading signals and that is why you are not able to see the full data like you see with returns and cumulative plot.

The trading signals chart is limited to show only the most recent 1500 bars for better visibility of the signals, while the returns and cumulative returns charts show the complete dataset.

Here is the get_strategy_returns()


def get_strategy_returns(data, col_names=['close', 'signal', 'strategy_returns'], bars_to_plot=1500):
    """
    Plots the close prices, trading signals, returns, cumulative returns, and drawdowns of a trading strategy.
    Also calculates and prints performance metrics like Sharpe Ratio and Maximum Drawdown.

    Args:
        data (pd.DataFrame): DataFrame containing close prices, trading signals, and strategy returns.
        col_names (list, optional): List of column names corresponding to close prices, signals, and strategy returns. Defaults to ['close', 'signal', 'strategy_returns'].
        bars_to_plot (int, optional): Number of bars to plot. Defaults to 1500.
    """

    close = col_names[0]
    signal = col_names[1]
    strategy_returns = col_names[2]
    
    # Plot the close prices of the stock
    close_plot = data[close][-bars_to_plot:].plot(figsize=(15, 7), color='blue')

    # Plot the signal
    signal_plot = data[signal][-bars_to_plot:].plot(
        figsize=(15, 7), secondary_y=True, ax=close_plot, style='green')

    # Highlight the holding periods of the long positions
    plt.fill_between(data[close][-bars_to_plot:].index, 0, 1, where=(data[signal][-bars_to_plot:] > 0),
                     color='green', alpha=0.1, lw=0)

    # Highlight the holding periods of the short positions
    plt.fill_between(data[close][-bars_to_plot:].index, 0, -1, where=(data[signal][-bars_to_plot:] < 0),
                     color='red', alpha=0.1, lw=0)

    # Set title
    plt.title('Signals for Strategy', fontsize=14)

    # Plot xlabel
    close_plot.set_xlabel('Date', fontsize=12)

    # Plot ylabels
    close_plot.set_ylabel('Price ($)', fontsize=12)
    signal_plot.set_ylabel('Signal', fontsize=12)

    # Set title
    plt.title('Trading Signals for the Strategy', fontsize=14)

    # Display the graph
    plt.show()

    # Plot returns
    data[strategy_returns].plot(figsize=(15, 7), color='green')
    plt.title('Returns of One Data Point', fontsize=14)
    plt.ylabel('Returns', fontsize=12)
    plt.xlabel('Year', fontsize=12)
    plt.show()

    # Plot cumulative returns
    (data[strategy_returns]+1).cumprod().plot(figsize=(15, 7), color='black')
    plt.title('Cumulative Returns', fontsize=14)
    plt.ylabel('Returns (in times)', fontsize=12)
    plt.xlabel('Year', fontsize=12)
    plt.show()

    # Create a data to store performance metrics
    performance_metrics = pd.DataFrame(index=['Strategy'])

    candle_difference = data.index.to_series().diff().mean().days
    # Number of trading candles per day
    if candle_difference >= 1:
        n = np.floor(candle_difference)
    else:
        n = data.loc[datetime.datetime.strftime(
            data.index[-1].date(), '%Y-%m-%d')].shape[0]

    # Set a risk-free rate
    risk_free_rate = 0.02/(252*n)
    # Calculate Sharpe ratio
    performance_metrics['Sharpe Ratio'] = round(np.sqrt(252*n)*(np.mean(data[strategy_returns]) -
                                                                (risk_free_rate))/np.std(data[strategy_returns]), 2)

    # Compute the cumulative maximum
    data['Peak'] = (data[strategy_returns]+1).cumprod().cummax()
    # Compute the Drawdown
    data['Drawdown'] = (
        ((data[strategy_returns]+1).cumprod()-data['Peak'])/data['Peak'])*100
    # Compute the maximum drawdown
    performance_metrics['Maximum Drawdown'] = "{0:.2f}%".format(
        (data['Drawdown'].min()))

    # Plot maximum drawdown
    data['Drawdown'].plot(figsize=(15, 7), color='red')
    # Set the title and axis labels
    plt.title('Drawdowns', fontsize=14)
    plt.ylabel('Drawdown(%)', fontsize=12)
    plt.xlabel('Year', fontsize=12)
    plt.fill_between(data['Drawdown'].index,
                     data['Drawdown'].values, color='red')
    plt.show()

    # Display performance metrics
    print(performance_metrics.T)

Let me know if something is not clear.

Noted & thanks.