Project: Stock Price Forecasting with LSTM and Prophet
Forecasting prices is a good way to practise time series modelling, and an honest way to learn how hard markets are to predict. Treat this as a modelling exercise, not trading advice.
Disclaimer and setup
This project is educational. Forecasts of prices are uncertain and are not financial advice. Past performance does not predict future returns.
# pip install yfinance prophet scikit-learn torch pandas
import yfinance as yf, pandas as pd
raw = yf.download("RELIANCE.NS", start="2018-01-01", progress=False, auto_adjust=True)
close = raw["Close"].squeeze().dropna()
df = close.reset_index()
df.columns = ["ds", "y"]
print(df.tail())Baseline first
On daily prices, 'tomorrow equals today' is surprisingly hard to beat. Any model must clear this bar.
import numpy as np
split = int(len(df) * 0.85)
train, test = df.iloc[:split], df.iloc[split:]
naive = test["y"].shift(1).fillna(train["y"].iloc[-1])
mae = lambda a, b: float(np.mean(np.abs(a - b)))
print("naive MAE:", round(mae(test["y"], naive), 2))Forecast with Prophet
Prophet fits trend and seasonality and gives uncertainty intervals. It suits business time series better than efficient financial prices, which makes it a useful comparison.
from prophet import Prophet
m = Prophet(daily_seasonality=False, weekly_seasonality=True, yearly_seasonality=True)
m.fit(train)
future = m.make_future_dataframe(periods=len(test), freq="B")
fc = m.predict(future)
pred = fc.set_index("ds").loc[test["ds"], "yhat"].values
print("Prophet MAE:", round(mae(test["y"].values, pred), 2))Forecast with an LSTM
Predict the next day's return from the previous 30 returns. Modelling returns instead of raw prices makes the series closer to stationary.
import torch, torch.nn as nn
ret = np.log(df["y"]).diff().dropna().values.astype("float32")
mu, sd = ret[:split].mean(), ret[:split].std()
r = (ret - mu) / sd
W = 30
X = np.stack([r[i:i+W] for i in range(len(r) - W)])[..., None]
y = r[W:]
Xt, yt = torch.tensor(X[:split-W]), torch.tensor(y[:split-W])
Xv, yv = torch.tensor(X[split-W:]), torch.tensor(y[split-W:])
class Net(nn.Module):
def __init__(s):
super().__init__(); s.l = nn.LSTM(1, 32, batch_first=True); s.o = nn.Linear(32, 1)
def forward(s, x): return s.o(s.l(x)[0][:, -1]).squeeze(-1)
net = Net(); opt = torch.optim.Adam(net.parameters(), 1e-3)
for ep in range(10):
for i in range(0, len(Xt), 64):
opt.zero_grad()
loss = nn.functional.mse_loss(net(Xt[i:i+64]), yt[i:i+64]); loss.backward(); opt.step()
with torch.no_grad():
print("LSTM val MSE:", float(nn.functional.mse_loss(net(Xv), yv)),
"| zero-return baseline:", float((yv ** 2).mean()))Interpret results honestly
If the LSTM error is not lower than the zero-return baseline on unseen data, it has learned nothing useful. Use walk-forward validation, include transaction costs before drawing conclusions about strategies, and be cautious about backtests that look too good, since overfitting is the usual cause.
Hands-on practice
Run the examples in the downloadable Jupyter notebook. The extra checks below focus on mistakes that appear in real projects, not just syntax.
Use walk-forward splits
series=list(range(12))
for cut in [6,8,10]:
train=series[:cut]; test=series[cut:cut+2]
print(len(train),test)6 [6, 7] 8 [8, 9] 10 [10, 11]
Time-series validation must preserve chronology.
Compare against a naive baseline
y=[101,103,102,106]
pred=[100,101,103,102]
mae=sum(abs(a-b) for a,b in zip(y,pred))/len(y)
print('MAE',mae)MAE 2.0
Complex models should beat simple persistence or seasonal baselines.
Self-check
- Can you explain why the first practice result is trustworthy rather than just plausible?
- What would you monitor or test before using this Forecasting Project workflow in production?
- Which assumption in the example would break first on a larger or messier dataset?
Frequently asked questions
Can LSTM predict stock prices accurately?
Not reliably. Prices are noisy and efficient markets leave little predictable signal, so always compare with a naive baseline.
Prophet or LSTM?
Prophet is quick and interpretable for trend and seasonality. LSTMs can model more complex patterns but need more data and careful validation.
Is this financial advice?
No. It is an educational modelling exercise only.
Primary references
Use these official sources when exact syntax, defaults or definitions matter beyond the examples here.




















































































































































