Module 6 · Lesson 6
Capstone: Analyzing a Stock Price Series
We’ll model a daily closing-price series as a random walk: start at some price, then repeatedly add a small random daily change. This is synthetic data (seeded, so it’s reproducible), but the analysis below is exactly what you’d run on a real price series.
One technique here hasn’t been taught yet: a rolling mean without
pandas. np.convolve(prices, kernel, mode="valid"), with
kernel = np.ones(window) / window, slides a length-window averaging
kernel across the series and keeps only the positions where the kernel
fully overlaps the data (mode="valid") — so the result has length
len(prices) - window + 1. It’s a vectorized way to compute a moving
average with zero explicit loops.
rng = np.random.default_rng(seed=42)
n_days = 250
daily_changes = rng.normal(loc=0.05, scale=1.0, size=n_days)
prices = 100 + np.cumsum(daily_changes)
plt.plot(prices)
plt.title("Synthetic daily closing price")
plt.xlabel("day")
plt.ylabel("price")
plt.show()
window = 10
kernel = np.ones(window) / window
rolling = np.convolve(prices, kernel, mode="valid")
print("prices:", prices.shape, "rolling mean:", rolling.shape)
Output:
prices: (250,) rolling mean: (241,)
Returns, worst day, and a rolling mean
Write analyze_prices(prices, window) that performs three chained
computations on a 1-D array of daily closing prices:
"daily_returns": a vectorized array of lengthlen(prices) - 1wheredaily_returns[i] = prices[i+1] / prices[i] - 1(no Python loop)."worst_day_index"and"worst_day_return": the index intodaily_returnsof the single worst (most negative) daily return, and that return's value."rolling_mean": the simple moving average ofpricesoverwindowdays, computed withnp.convolveandmode="valid"as described above (lengthlen(prices) - window + 1).
Return a dict with exactly the keys "daily_returns", "worst_day_index",
"worst_day_return", and "rolling_mean".
💡 Hint
daily_returns = prices[1:] / prices[:-1] - 1. Use np.argmin for the worst index, then index back into daily_returns for its value. For the rolling mean, build kernel = np.ones(window) / window and call np.convolve(prices, kernel, mode="valid").
✅ Solution
def analyze_prices(prices, window):
daily_returns = prices[1:] / prices[:-1] - 1
worst_day_index = int(np.argmin(daily_returns))
worst_day_return = float(daily_returns[worst_day_index])
kernel = np.ones(window) / window
rolling_mean = np.convolve(prices, kernel, mode="valid")
return {
"daily_returns": daily_returns,
"worst_day_index": worst_day_index,
"worst_day_return": worst_day_return,
"rolling_mean": rolling_mean,
}
🎯 Key Takeaways
.stridesand C-vs-Fortran order explain why transpose is free and why some operations neednp.ascontiguousarrayfirst.- Avoid hidden allocation costs: preallocate instead of growing arrays,
and use
out=for in-place ops when you don’t need the original. np.save/load,np.savez, andnp.savetxt/loadtxtcover binary, multi-array, and text persistence — all work with in-memory buffers too.- Structured arrays give you named, typed fields without needing
pandas. - Both capstones were just Modules 1-5’s tools — indexing, broadcasting, aggregation, sorting — aimed at a concrete problem.
🎓 Course Complete!
You’ve made it through the whole course:
- NumPy Fundamentals & Array Creation — what an array is, and every way to build one.
- Indexing, Slicing & Views — selecting exactly the data you want, and knowing when you get a view vs. a copy.
- Array Operations & Broadcasting — vectorized math and the broadcasting rules that make it work across shapes.
- Aggregations, Statistics & Sorting — summarizing and ordering data along any axis.
- Linear Algebra & Random — vectors, matrices, and reproducible randomness.
- Performance, I/O & Mini-Projects — memory layout, persistence, and two real mini-projects tying it all together.
Where to go next:
- pandas — labeled, tabular data built on top of NumPy arrays.
- matplotlib / seaborn — deeper, more polished visualization.
- scipy — advanced scientific computing (optimization, signal processing, statistics) that extends what you’ve learned here.
Nicely done — go build something with it. 🎉