The Quest Begins (The "Why")
Honestly, I was staring at a candlestick chart one late night, coffee gone cold, wondering why my “gut feeling” trades kept blowing up like a poorly timed meme stock. I’d read a few blog posts that said “just follow the trend,” but whenever I tried to eyeball it, I kept getting whipsawed left and right. It felt like trying to defeat a boss in Dark Souls without learning its attack pattern — frustrating, expensive, and frankly embarrassing.
I realized I needed a repeatable way to spot when price was actually gaining momentum versus just making noise. That’s when I dove into technical analysis, specifically moving averages and the Relative Strength Index (RSI). If you’ve ever felt like you’re guessing in the dark, trust me — there’s a light at the end of the tunnel, and it’s brighter than a lightsaber in a Jedi temple.
The Revelation (The Insight)
Here’s the thing: price alone is a noisy storyteller. Moving averages smooth out that story by giving you a constantly updated average price over a set period. Think of it as the “training montage” where the hero filters out distractions and focuses on what truly matters.
- Simple Moving Average (SMA) – adds up the last n closing prices and divides by n. It’s reliable but lags because every point weighs the same.
- Exponential Moving Average (EMA) – gives more weight to recent prices, so it reacts faster to new information. It’s like switching from a heavy sword to a agile lightsaber: quicker, more responsive.
The RSI, on the other hand, is a momentum oscillator that measures the speed and change of price movements on a scale of 0 to 100. Traditionally, readings above 70 suggest overbought conditions (price might be due for a pullback), while readings below 30 hint at oversold conditions (price could bounce). It’s not a crystal ball, but when paired with a moving average crossover, it becomes a powerful filter — like using the Force to sense disturbances before they happen.
The “aha!” moment for me was seeing how a bullish EMA crossover (short‑term EMA crossing above long‑term EMA) combined with an RSI climbing out of oversold territory often preceded a solid upward move. Conversely, a bearish crossover with RSI dropping from overbought warned of impending selling pressure. Suddenly, the chart stopped looking like abstract art and started revealing a script I could actually follow.
Wielding the Power (Code & Examples)
Let’s get our hands dirty. I’ll walk you through a quick Python script that pulls price data, calculates SMA/EMA, computes RSI, and plots the signals. If you’ve ever felt like you’re wrestling with a spreadsheet, this will feel like discovering a cheat code.
First, the imports and data fetch (using yfinance for free historic data):
import yfinance as fin
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Grab 6 months of daily data for a popular ticker
df = fin.download("AAPL", period="6mo", interval="1d")
df = df[['Close']].copy()
df.rename(columns={'Close': 'price'}, inplace=True)
df.head()
1. Moving Averages
# 20‑day SMA and 50‑day SMA (classic crossover window)
df['SMA_20'] = df['price'].rolling(window=20).mean()
df['SMA_50'] = df['price'].rolling(window=50).mean()
# 20‑day EMA and 50‑day EMA (more responsive)
df['EMA_20'] = df['price'].ewm(span=20, adjust=False).mean()
df['EMA_50'] = df['price'].ewm(span=50, adjust=False).mean()
Trap #1: Forgetting to handle the NaN values that appear at the start of the roll‑up windows. If you plot or trade on those early rows, you’ll get garbage signals. Always .dropna() or slice after the longest window.
df = df.dropna() # clean house before we signal
2. RSI Calculation
The classic 14‑period RSI:
def compute_rsi(series, period=14):
delta = series.diff()
up = delta.clip(lower=0)
down = -delta.clip(upper=0)
ma_up = up.ewm(com=period-1, adjust=False).mean()
ma_down = down.ewm(com=period-1, adjust=False).mean()
rs = ma_up / ma_down
rsi = 100 - (100 / (1 + rs))
return rsi
df['RSI'] = compute_rsi(df['price'])
Trap #2: Using a simple moving average for the up/down swings instead of the exponential version. The original Wilder’s RSI uses a smoothed average (EMA‑like). Using SMA can make the indicator overly choppy and give false extremes. Stick with the EMA version above unless you have a specific reason to deviate.
3. Generating Signals
# Bullish: short EMA crosses above long EMA AND RSI rises from <30
df['signal'] = np.where(
(df['EMA_20'] > df['EMA_50']) &
(df['EMA_20'].shift(1) <= df['EMA_50'].shift(1)) &
(df['RSI'] > 30) &
(df['RSI'].shift(1) <= 30),
1, # buy
np.where(
(df['EMA_20'] < df['EMA_50']) &
(df['EMA_20'].shift(1) >= df['EMA_50'].shift(1)) &
(df['RSI'] < 70) &
(df['RSI'].shift(1) >= 70),
-1, # sell
0 # hold
)
)
# Plot price with EMAs and highlight signals
plt.figure(figsize=(12,6))
plt.plot(df['price'], label='Price', color='black')
plt.plot(df['EMA_20'], label='EMA 20', color='blue')
plt.plot(df['EMA_50'], label='EMA 50', color='orange')
plt.scatter(df.index[df['signal']==1], df['price'][df['signal']==1],
marker='^', color='green', s=100, label='Buy')
plt.scatter(df.index[df['signal']==-1], df['price'][df['signal']==-1],
marker='v', color='red', s=100, label='Sell')
plt.title('AAPL – EMA Crossover + RSI Filter')
plt.legend()
plt.show()
Run that, and you’ll see green triangles where the short EMA nudges above the long EMA while the RSI is climbing out of oversold territory, and red triangles for the opposite. It’s not a guarantee, but it’s a far cry from guessing based on a gut feeling.
Why This New Power Matters
Now you’ve got a repeatable, rule‑based way to spot potential entries and exits. Imagine building a bot that scans dozens of tickers each night, fires off alerts when those conditions line up, and lets you focus on the strategy instead of staring at charts all day. Or maybe you just want to feel more confident when you manually place a trade — knowing you’re not chasing a random spike but riding a wave backed by momentum and trend.
The best part? These tools are lightweight. You don’t need a PhD in quantitative finance; a few lines of pandas and a clear understanding of what the numbers mean will get you 80 % of the way there. And once you’re comfortable with SMA/EMA and RSI, you can layer on other indicators (MACD, Bollinger Bands) or even experiment with machine‑learning filters — but you’ll always have this solid foundation to fall back on.
Your Turn – The Challenge
I dare you: pick any stock or crypto you like, copy the script above, tweak the windows (maybe try 10/30 EMAs or a 21‑period RSI), and see how the signals change. Post your chart in the comments and tell me what surprised you. Did the RSI filter cut out false crossovers? Did you miss a move because you were too strict? Share your findings — let’s turn this into a mini‑quest party where we all level up together.
May your averages be smooth and your RSI ever in your favor! 🚀
Top comments (0)