Make a stock market prediction model indicating up and down trend (use below code just for demonstration your model should be better than this) make use of super trend also use NSETOOLS to get the data insted of yfinance data:

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)


# 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)