Please correct this code it is giving error:
Error:
---------------------------------------------------------------------------
NotFittedError                            Traceback (most recent call last)
<ipython-input-12-191d51d54b2c> in <cell line: 3>()
      1 # Evaluate the model
      2 scaler = MinMaxScaler(feature_range=(0, 1))
----> 3 mae, mse = evaluate_model(model, X_test, y_test, scaler)
      4 print(f"Mean Absolute Error: {mae}")
      5 print(f"Mean Squared Error: {mse}")

2 frames
/usr/local/lib/python3.10/dist-packages/sklearn/utils/validation.py in check_is_fitted(estimator, attributes, msg, all_or_any)
   1388 
   1389     if not fitted:
-> 1390         raise NotFittedError(msg % {"name": type(estimator).__name__})
   1391 
   1392 

NotFittedError: This MinMaxScaler instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.

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)

# Evaluate the model
scaler = MinMaxScaler(feature_range=(0, 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)