DEV Community

Cover image for Predicting Stock Prices with AI: A Simple Guide to Using LSTM for Nifty50 Forecasting
yaswanthteja
yaswanthteja

Posted on

Predicting Stock Prices with AI: A Simple Guide to Using LSTM for Nifty50 Forecasting

Introduction

Have you ever wondered if computers can predict stock prices? Well, they can—not perfectly, but they can learn from past data to make educated guesses about future prices. In this blog, we’ll explore how we can use a special kind of artificial intelligence (AI) called Long Short-Term Memory (LSTM) to predict the future prices of the Nifty50, India’s leading stock market index.

Don’t worry if you’re not a tech expert—we’ll explain everything in simple terms, just like teaching a friend!

How Does Stock Prediction Work?

Imagine you’re trying to predict the weather. You’d look at past weather patterns—like temperature, humidity, and rainfall—to guess if it’ll rain tomorrow. Similarly, stock prediction works by analyzing past stock prices to forecast future trends.

Here’s how we do it:

  1. Get Historical Data – We download years of Nifty50 stock prices.

  2. Clean the Data – Remove errors or missing values (like a teacher correcting a messy notebook).

  3. Train the AI Model – Teach the computer to recognize patterns in stock prices.

  4. Make Predictions – Ask the AI to predict future prices based on what it learned.

Now, let’s dive deeper into each step!

Step 1: Getting the Data

We use a library called yfinance (Yahoo Finance) to download Nifty50 stock prices from 2005 to 2025. This gives us a big table with daily prices—like a giant Excel sheet with dates and closing prices.

import yfinance as yf

start_date = '2005-05-16'
end_date = '2025-05-15'
nifty_data = yf.download('^NSEI', start=start_date, end=end_date)
Enter fullscreen mode Exit fullscreen mode

Think of this as downloading a history book of stock prices.

Step 2: Cleaning the Data

Sometimes, data has missing or incorrect entries (like a torn page in a book). We fix this by:

  • Sorting dates correctly.

  • Removing or filling missing values.

print(f"Missing values in the dataset: {nifty_data.isnull().sum().sum()}")
nifty_data = nifty_data.sort_index()
Enter fullscreen mode Exit fullscreen mode

This ensures our AI learns from clean, organized data.

Step 3: Scaling the Data (Making Numbers Easier to Work With)

Stock prices can be huge (like ₹20,000), but AI works better with smaller numbers (between 0 and 1). We use MinMaxScaler to shrink the numbers while keeping their relationships intact.

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(nifty_close)  # nifty_close = Closing prices
Enter fullscreen mode Exit fullscreen mode

This is like converting kilometers into meters—same distance, just easier to handle.

Step 4: Preparing the Data for AI Learning

AI learns from sequences. Imagine teaching a child to predict the next number in this sequence:

1, 2, 3, …? (Answer: 4)

Similarly, we give the AI sequences of 60 days’ stock prices and ask it to predict the 61st day.

def create_dataset(dataset, time_step=60):
    X, y = [], []
    for i in range(len(dataset) - time_step - 1):
        X.append(dataset[i:(i + time_step), 0])  # 60 days of data
        y.append(dataset[i + time_step, 0])      # Next day's price
    return np.array(X), np.array(y)

X_train, y_train = create_dataset(train_data, time_step=60)
Enter fullscreen mode Exit fullscreen mode

This way, the AI learns patterns like:

  • If prices rise for 10 days, will they fall soon?

  • Do big drops usually recover?

Step 5: Building the AI (LSTM Model)

Our AI is an LSTM (Long Short-Term Memory) network — a type of neural network great at learning sequences (like stock prices over time).

We build it like this:

  1. First Layer (50 neurons) – Learns basic patterns.

  2. Second Layer (50 neurons) – Learns deeper trends.

  3. Third Layer (50 neurons) – Makes final predictions.

  4. Dropout Layers – Prevents overfitting (like a student who memorizes answers instead of learning concepts).

model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(time_step, 1)))
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))  # Final prediction
Enter fullscreen mode Exit fullscreen mode

We then train the model using past data, just like a student practicing with old exam papers.

Step 6: Making Predictions

After training, the AI can predict future prices. We test it on unseen data (like a surprise test) to see how well it performs.

train_predict = model.predict(X_train)
test_predict = model.predict(X_test)
Enter fullscreen mode Exit fullscreen mode

We measure accuracy using:

  • RMSE (Root Mean Square Error) – How far predictions are from real prices.

  • R² Score – How well the model explains price movements (0% = random guess, 100% = perfect prediction).

train_rmse = math.sqrt(mean_squared_error(y_train_actual, train_predict))
test_r2 = r2_score(y_test_actual, test_predict)
Enter fullscreen mode Exit fullscreen mode

If the AI gets ~90% accuracy, it’s doing well!

Step 7: Predicting Future Prices

Finally, we ask the AI: "What will Nifty50 prices be in the next 30 days?"

We feed it the last 60 days’ data and let it predict day by day.

last_60_days = scaled_data[-60:]
future_predictions = []

for _ in range(30):
    X_future = last_60_days.reshape(1, time_step, 1)
    future_pred = model.predict(X_future)
    last_60_days = np.append(last_60_days[1:], future_pred)
    future_predictions.append(future_pred[0, 0])
Enter fullscreen mode Exit fullscreen mode

We then plot the predictions:

Image description

The red line shows what the AI thinks will happen!

  • Here, the sample size is limited to get better accuracy. We need to train them with larger data.

Conclusion: Can AI Really Predict Stocks?

Yes — but with limitations.

✅ Good at:

  • Finding patterns in historical data.

  • Making short-term predictions.

❌ Not perfect at:

  • Predicting sudden crashes (like COVID-19).

  • Accounting for unexpected news (elections, wars).

Try It Yourself!

Want to run this code? Copy the full script from above and try it on Google Colab or Jupyter Notebook.

click below link and run the below code


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Dropout
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import datetime as dt
import math

# Download market data
print("Downloading Nifty50 data...")
start_date = '2005-05-16'
end_date = '2025-05-15'
nifty_data = yf.download('^NSEI', start=start_date, end=end_date)

# Data cleaning and preprocessing
print("\nCleaning and preprocessing data...")
print(f"Missing values in the dataset: {nifty_data.isnull().sum().sum()}")
nifty_data = nifty_data.sort_index()
nifty_close = nifty_data['Close'].values.reshape(-1, 1)

# Scale the data
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(nifty_close)

# Split data into training and testing sets
train_size = int(len(scaled_data) * 0.8)
test_size = len(scaled_data) - train_size
train_data, test_data = scaled_data[0:train_size,:], scaled_data[train_size:len(scaled_data),:]
print(f"\nTraining data size: {train_size}, Testing data size: {test_size}")

def create_dataset(dataset, time_step=60):
    X, y = [], []
    for i in range(len(dataset) - time_step - 1):
        X.append(dataset[i:(i + time_step), 0])
        y.append(dataset[i + time_step, 0])
    return np.array(X), np.array(y)

# Create the dataset with time steps
time_step = 60
X_train, y_train = create_dataset(train_data, time_step)
X_test, y_test = create_dataset(test_data, time_step)

# Reshape input to be [samples, time steps, features] which is required for LSTM
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)

# Build LSTM model
print("\nBuilding LSTM model...")
model = Sequential()
# First LSTM layer with 50 neurons and return sequences=True to stack another LSTM layer
model.add(LSTM(units=50, return_sequences=True, input_shape=(time_step, 1)))
model.add(Dropout(0.2)) # Dropout to prevent overfitting

# Second LSTM layer with 50 neurons
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))

# Third LSTM layer with 50 neurons
model.add(LSTM(units=50))
model.add(Dropout(0.2))

# Output layer
model.add(Dense(units=1))

# Compile the model
model.compile(optimizer='adam', loss='mean_squared_error')

# Early stopping to prevent overfitting
early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)

# Train the model
print("\nTraining the model...")
batch_size = 32
epochs = 50

history = model.fit(
    X_train, y_train,
    epochs=epochs,
    batch_size=batch_size,
    validation_split=0.1,  # Use 10% of training data for validation
    callbacks=[early_stop],
    verbose=1
)

# Make predictions and evaluate the model
print("\nMaking predictions...")
train_predict = model.predict(X_train)
test_predict = model.predict(X_test)

# Inverse transform to get actual values
train_predict = scaler.inverse_transform(train_predict)
test_predict = scaler.inverse_transform(test_predict)
y_train_actual = scaler.inverse_transform(y_train.reshape(-1, 1))
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))

# Calculate performance metrics
train_rmse = math.sqrt(mean_squared_error(y_train_actual, train_predict))
test_rmse = math.sqrt(mean_squared_error(y_test_actual, test_predict))
train_mae = mean_absolute_error(y_train_actual, train_predict)
test_mae = mean_absolute_error(y_test_actual, test_predict)
train_r2 = r2_score(y_train_actual, train_predict)
test_r2 = r2_score(y_test_actual, test_predict)

# Display results
print(f"\nTraining RMSE: {train_rmse:.2f}")
print(f"Testing RMSE: {test_rmse:.2f}")
print(f"Training MAE: {train_mae:.2f}")
print(f"Testing MAE: {test_mae:.2f}")
print(f"Training R^2 Score: {train_r2:.2f}")
print(f"Testing R^2 Score: {test_r2:.2f}")

# Calculate accuracy as a percentage (simplified for this context)
def calculate_accuracy(actual, predicted, threshold=0.01):
    within_threshold = np.abs(actual - predicted) <= threshold * actual
    accuracy = np.mean(within_threshold) * 100
    return accuracy

train_accuracy = calculate_accuracy(y_train_actual, train_predict)
test_accuracy = calculate_accuracy(y_test_actual, test_predict)

print(f"\nTraining Accuracy: {train_accuracy:.2f}%")
print(f"Testing Accuracy: {test_accuracy:.2f}%")

# Visualize the results
print("\nVisualizing results...")
train_dates = nifty_data.index[time_step+1:train_size]
test_dates = nifty_data.index[train_size+time_step:-1]

plt.figure(figsize=(14, 6))
plt.plot(train_dates, y_train_actual, label='Actual Training Data')
plt.plot(train_dates, train_predict, label='Training Predictions')
plt.plot(test_dates, y_test_actual, label='Actual Testing Data')
plt.plot(test_dates, test_predict, label='Testing Predictions')
plt.title('Nifty50 Price Prediction')
plt.xlabel('Date')
plt.ylabel('Price (INR)')
plt.legend()
plt.show()

# Future predictions
print("\nMaking future predictions...")
last_60_days = scaled_data[-60:]
future_predictions = []

for _ in range(30):
    # Reshape data for prediction
    X_future = last_60_days.reshape(1, time_step, 1)
    # Make prediction
    future_pred = model.predict(X_future)
    # Append to the input data
    last_60_days = np.append(last_60_days[1:], future_pred)
    last_60_days = last_60_days.reshape(-1, 1)
    # Store the prediction
    future_predictions.append(future_pred[0, 0])

# Inverse transform to get actual values
future_predictions = np.array(future_predictions).reshape(-1, 1)
future_predictions = scaler.inverse_transform(future_predictions)

# Create future dates
last_date = nifty_data.index[-1]
future_dates = [last_date + dt.timedelta(days=i) for i in range(1, 31)]

# Visualize future predictions
plt.figure(figsize=(14, 6))
plt.plot(nifty_data.index[-100:], nifty_data['Close'].values[-100:], label='Historical Data')
plt.plot(future_dates, future_predictions, label='Future Predictions', color='red')
plt.title('Nifty50 Future Price Prediction')
plt.xlabel('Date')
plt.ylabel('Price (INR)')
plt.legend()
plt.show()

# Print model summary
print("\nModel Summary:")
model.summary()
Enter fullscreen mode Exit fullscreen mode

Credits:ezcompounding

Final Thoughts

AI is a powerful tool for stock prediction, but it’s not a crystal ball. It helps investors make educated guesses, not certainties.

Would you trust AI for stock advice? Let us know in the comments! 🚀

Happy investing! 📈

Top comments (0)