Correct this code for the error:
ERROR:
Index(['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'], dtype='object')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   3801             try:
-> 3802                 return self._engine.get_loc(casted_key)
   3803             except KeyError as err:

12 frames
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'Close'

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   3802                 return self._engine.get_loc(casted_key)
   3803             except KeyError as err:
-> 3804                 raise KeyError(key) from err
   3805             except TypeError:
   3806                 # If we have a listlike key, _check_indexing_error will raise

KeyError: 'Close'
CODE:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score, f1_score
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[['Upper Basic', 'Lower Basic']].apply(
        lambda x: x['Upper Basic'] if x['Close'] > x['Upper Basic'] else x['Lower Basic'], axis=1)
    data['Lower Band'] = data[['Upper Basic', 'Lower Basic']].apply(
        lambda x: x['Lower Basic'] if x['Close'] < x['Lower Basic'] else x['Upper Basic'], axis=1)

    data['Super Trend'] = np.nan
    for i in range(period, len(data)):
        if data['Close'][i] <= data['Upper Band'][i - 1]:
            data['Super Trend'][i] = data['Upper Band'][i]
        elif data['Close'][i] > data['Upper Band'][i]:
            data['Super Trend'][i] = data['Lower Band'][i]

    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)
    stock_data.columns = stock_data.columns.astype(str)  # Add this line
    print(stock_data.columns)
    stock_data_with_super_trend = calculate_super_trend(stock_data, period, multiplier)
    
    columns_to_use = stock_data_with_super_trend[['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(1 if data_normalized[i, 0] > data_normalized[i - 1, 0] else 0)

    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(Dropout(0.2))
    model.add(LSTM(units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(units=50))
    model.add(Dropout(0.2))
    model.add(Dense(units=1, activation='sigmoid'))

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    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)
    return model, history

def evaluate_model(model, X_test, y_test):
    y_pred = model.predict(X_test)
    y_pred = np.where(y_pred > 0.5, 1, 0)

    accuracy = accuracy_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred)
    print('Accuracy:', accuracy, 'F1 score:', f1)


def predict_stock_movement(model, X_input):
    y_pred = model.predict(X_input)
    return "up" if y_pred > 0.5 else "down"

ticker = '^NSEI'
start_date = '2010-01-01'
end_date = '2020-12-31'
window_size = 60

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

model = create_lstm_model(X_train.shape[1:])

batch_size = 32
epochs = 20
model, history = train_model(model, X_train, y_train, batch_size, epochs)


# Make predictions
y_pred = model.predict(X_test)
y_pred_direction = np.where(y_pred > 0.5, 1, 0)


import matplotlib.pyplot as plt
# Plot actual and predicted values daywise
plt.figure(figsize=(14, 6))
plt.plot(y_test, label='Actual')
plt.plot(y_pred_direction, label='Predicted')
plt.xlabel('Days')
plt.ylabel('Direction')
plt.title('NIFTY Stock Price Direction Prediction (Actual vs Predicted)')
plt.legend()
plt.show()


# Evaluate the model
accuracy = accuracy_score(y_test, y_pred_direction)
f1 = f1_score(y_test, y_pred_direction)
print('Accuracy:', accuracy, 'F1 score:', f1)