Goal
Given daily stock prices, compute:
- Daily returns
- Rolling averages
- Volatility
- Compare multiple stocks
Analysis pipeline
flowchart LR A["Raw prices
(date, close)"] --> B["Returns
(pct_change)"] B --> C["Smooth
(20/50-day MA)"] C --> D["Visualize
(price + MA lines)"] D --> E["Volatility
(rolling std)"]
Dataset columns
date,close(and optionally open/high/low/volume)
Step 1: Load and parse
import pandas as pd
df = pd.read_csv("data/stock.csv")
df["date"] = pd.to_datetime(df["date"], errors="coerce")
df = df.sort_values("date")
print(df.head())Step 2: Daily returns
df["return"] = df["close"].pct_change()
print(df[["date", "close", "return"]].head(10))Step 3: Moving averages
df["ma20"] = df["close"].rolling(20).mean()
df["ma50"] = df["close"].rolling(50).mean()Step 4: Plot
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 4))
plt.plot(df["date"], df["close"], label="close")
plt.plot(df["date"], df["ma20"], label="MA20")
plt.plot(df["date"], df["ma50"], label="MA50")
plt.title("Price and moving averages")
plt.legend()
plt.xticks(rotation=20)
plt.tight_layout()
plt.show()Step 5: Volatility (rolling std)
df["volatility_20"] = df["return"].rolling(20).std()Visualize it
Deliverable
Summarize:
- Trend periods
- High-volatility periods and possible reasons
- Compare performance across stocks (optional)
Check your understanding
What does df["close"].pct_change() compute?
It is a vectorized comparison of today to yesterday, with no loop needed.
Show answer
A — The percentage change from the previous day's close, the daily return — It is a vectorized comparison of today to yesterday, with no loop needed.
Why sort_values("date") before computing returns and rolling windows?
pct_change and rolling use the previous rows, so unordered data gives wrong results.
Show answer
A — Both depend on rows being in chronological order — pct_change and rolling use the previous rows, so unordered data gives wrong results.
How is volatility_20 defined in the project?
Volatility is measured as the spread of returns, using rolling(20).std() on return, not on price.
Show answer
A — The 20-day rolling standard deviation of daily returns — Volatility is measured as the spread of returns, using rolling(20).std() on return, not on price.
What does ma50 (rolling(50).mean()) reveal compared with ma20?
A longer window averages more days, so it reacts more slowly and smooths more.
Show answer
A — A smoother, slower-moving long-term trend — A longer window averages more days, so it reacts more slowly and smooths more.
🧪 Try It Yourself
Exercise 1 – Daily returns
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – Moving average
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – Rolling volatility
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.