How to overcome this error in the code:
Error:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-118-8825bf5b363f> in <cell line: 4>()
     11 
     12     new_row = np.concatenate((next_day_input[0, 1:, :], next_day_extended), axis=0)
---> 13     X_test = np.append(X_test, [new_row], axis=0)
     14 
     15 predictions = np.array(predictions).reshape(-1, 1)

2 frames
/usr/local/lib/python3.10/dist-packages/numpy/core/overrides.py in concatenate(*args, **kwargs)

ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 40 and the array at index 1 has size 39

Code:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout

def calculate_atr(data, period):
    data['h-l'] = data['high'] - data['low']
    data['h-pc'] = abs(data['high'] - data['close'].shift(1))
    data['l-pc'] = abs(data['low'] - data['close'].shift(1))
    data['tr'] = data[['h-l', 'h-pc', 'l-pc']].max(axis=1)
    data['atr'] = data['tr'].rolling(window=period).mean()
    return data

def calculate_super_trend(data, period, multiplier):
    data = calculate_atr(data, period)
    data['Upper Basic'] = (data['high'] + data['low']) / 2 + multiplier * data['atr']
    data['Lower Basic'] = (data['high'] + data['low']) / 2 - multiplier * data['atr']
    data['Upper Band'] = data.apply(lambda x: x['Upper Basic'] if x['close'] > x['Upper Basic'] else x['Lower Basic'], axis=1)
    data['Lower Band'] = data.apply(lambda x: x['Lower Basic'] if x['close'] < x['Lower Basic'] else x['Upper Basic'], axis=1)
    data['Super Trend'] = np.where(data['close'] > data['Upper Band'], data['Lower Band'], data['Upper Band'])
    return data.dropna()

def load_preprocess_data(ticker, start_date, end_date, window_size, period=14, multiplier=3):
    stock_data = yf.download(ticker, start=start_date, end=end_date)
    print("Original columns:", stock_data.columns)
    stock_data.columns = [col.lower() for col in stock_data.columns]
    stock_data_with_super_trend = calculate_super_trend(stock_data, period, multiplier)

    columns_to_use = stock_data_with_super_trend[['open', 'high', 'low', 'close', 'Super Trend']].values
    scaler = MinMaxScaler(feature_range=(0, 1))
    data_normalized = scaler.fit_transform(columns_to_use)

    X, y = [], []
    for i in range(window_size, len(data_normalized)):
        X.append(data_normalized[i - window_size:i])
        y.append(data_normalized[i, 3]) # Use Close prices directly as labels

    train_len = int(0.8 * len(X))
    X_train, y_train = np.array(X[:train_len]), np.array(y[:train_len])
    X_test, y_test = np.array(X[train_len:]), np.array(y[train_len:])

    return X_train, y_train, X_test, y_test

def create_lstm_model(input_shape):
    model = Sequential()
    model.add(LSTM(units=50, return_sequences=True, input_shape=input_shape))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(LSTM(units=50))
    model.add(Dense(units=1))

    model.compile(optimizer='adam', loss='mean_squared_error')
    return model


def train_model(model, X_train, y_train, batch_size, epochs):
    history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
    return model, history

def evaluate_model(model, X_test, y_test, scaler):
    y_pred = model.predict(X_test)
    y_pred_inverse = scaler.inverse_transform(np.column_stack((np.zeros(y_pred.shape), y_pred)))[:, 1] # Inverse transform for Close prices
    y_test_inverse = scaler.inverse_transform(np.column_stack((np.zeros(y_test.shape), y_test)))[:, 1]

    mae = np.mean(np.abs(y_pred_inverse - y_test_inverse))
    mse = np.mean(np.square(y_pred_inverse - y_test_inverse))
    return mae, mse


def plot_prediction(model, X_test, y_test, scaler):
    y_pred = model.predict(X_test)
    y_pred_inverse = scaler.inverse_transform(np.column_stack((np.zeros(y_pred.shape), y_pred)))[:, 1] # Inverse transform for Close prices
    y_test_inverse = scaler.inverse_transform(np.column_stack((np.zeros(y_test.shape), y_test)))[:, 1]

    plt.figure(figsize=(14, 6))
    plt.plot(y_test_inverse, label='Actual')
    plt.plot(y_pred_inverse, label='Predicted')
    plt.xlabel('Days')
    plt.ylabel('Close Price')
    plt.title('Stock Price Prediction (Actual vs Predicted)')
    plt.legend()
    plt.show()

# Define the parameters
ticker = '^NSEI'  # Ticker symbol for Nifty
start_date = '2010-01-01'
end_date = '2023-06-01'
window_size = 40  # Number of previous days' data to consider
period = 14  # ATR period
multiplier = 3  # ATR multiplier
batch_size = 32
epochs = 100

X_train, y_train, X_test, y_test = load_preprocess_data(ticker, start_date, end_date, window_size, period, multiplier)

# Create the LSTM model
input_shape = (X_train.shape[1], X_train.shape[2])
model = create_lstm_model(input_shape)


# Train the model
model, history = train_model(model, X_train, y_train, batch_size, epochs)

scaler = MinMaxScaler(feature_range=(0, 1))
scaler.fit_transform(y_train.reshape(-1, 1))
mae, mse = evaluate_model(model, X_test, y_test, scaler)
print(f"Mean Absolute Error: {mae}")
print(f"Mean Squared Error: {mse}")

# Plot the predictions
plot_prediction(model, X_test, y_test, scaler)

upcoming_days = 5
predictions = []

for i in range(upcoming_days):
    next_day_input = np.array([X_test[-1, 1:, :]])
    next_day_pred = model.predict(next_day_input)
    predictions.append(next_day_pred[0, 0])

    next_day_extended = np.zeros((1, next_day_input.shape[2]))
    next_day_extended[:, 3] = next_day_pred.T

    new_row = np.concatenate((next_day_input[0, 1:, :], next_day_extended), axis=0)
    X_test = np.append(X_test, [new_row], axis=0)

predictions = np.array(predictions).reshape(-1, 1)
predictions_inverse = scaler.inverse_transform(np.column_stack((np.zeros(predictions.shape), predictions)))[:, 1] # Inverse transform for Close prices

plt.figure(figsize=(14, 6))
plt.plot(predictions_inverse, marker="o", label='Predicted')
plt.xlabel('Days')
plt.ylabel('Close Price')
plt.title('NIFTY Stock Price Prediction for Upcoming 5 Days')
plt.legend()
plt.show()