Skip to content

Technical Analysis

🎯 Learning Objectives

  • Learn chart patterns and price action
  • Master technical indicators
  • Understand support and resistance
  • Build trading signals from technical analysis

Technical analysis uses historical price and volume data to predict future price movements. This chapter covers essential technical analysis concepts and indicators.

Price Patterns

Trend Patterns

Uptrend: Higher highs and higher lows Downtrend: Lower highs and lower lows Sideways: No clear direction

Chart Patterns

  • Head and Shoulders: Reversal pattern
  • Double Top/Bottom: Reversal patterns
  • Triangles: Continuation patterns
  • Flags and Pennants: Continuation patterns

Moving Averages

Simple Moving Average (SMA)

import pandas as pd
import numpy as np
import yfinance as yf

data = yf.download("AAPL", period="1y")['Close']

# Calculate SMAs
data['SMA_20'] = data.rolling(window=20).mean()
data['SMA_50'] = data.rolling(window=50).mean()
data['SMA_200'] = data.rolling(window=200).mean()

# Trading signal: Golden Cross (SMA_20 > SMA_50)
data['Signal'] = 0
data.loc[data['SMA_20'] > data['SMA_50'], 'Signal'] = 1
data.loc[data['SMA_20'] < data['SMA_50'], 'Signal'] = -1

Exponential Moving Average (EMA)

# EMA gives more weight to recent prices
data['EMA_12'] = data.ewm(span=12, adjust=False).mean()
data['EMA_26'] = data.ewm(span=26, adjust=False).mean()

Technical Indicators

RSI (Relative Strength Index)

def calculate_rsi(prices, period=14):
    delta = prices.diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

data['RSI'] = calculate_rsi(data['Close'])

# Trading signals
# RSI < 30: Oversold (buy signal)
# RSI > 70: Overbought (sell signal)

MACD (Moving Average Convergence Divergence)

exp1 = data['Close'].ewm(span=12, adjust=False).mean()
exp2 = data['Close'].ewm(span=26, adjust=False).mean()
data['MACD'] = exp1 - exp2
data['Signal_Line'] = data['MACD'].ewm(span=9, adjust=False).mean()
data['Histogram'] = data['MACD'] - data['Signal_Line']

# Trading signal: MACD crosses above Signal Line (bullish)

Bollinger Bands

data['BB_Middle'] = data['Close'].rolling(window=20).mean()
bb_std = data['Close'].rolling(window=20).std()
data['BB_Upper'] = data['BB_Middle'] + (bb_std * 2)
data['BB_Lower'] = data['BB_Middle'] - (bb_std * 2)

# Trading signals
# Price touches lower band: Potential buy
# Price touches upper band: Potential sell

Stochastic Oscillator

def stochastic_oscillator(high, low, close, k_period=14, d_period=3):
    lowest_low = low.rolling(window=k_period).min()
    highest_high = high.rolling(window=k_period).max()
    k_percent = 100 * ((close - lowest_low) / (highest_high - lowest_low))
    d_percent = k_percent.rolling(window=d_period).mean()
    return k_percent, d_percent

data['Stoch_K'], data['Stoch_D'] = stochastic_oscillator(
    data['High'], data['Low'], data['Close']
)

Support and Resistance

Identifying Levels

# Support: Price level where buying pressure is strong
# Resistance: Price level where selling pressure is strong

# Find local minima (support) and maxima (resistance)
from scipy.signal import argrelextrema

# Find local minima (potential support)
min_indices = argrelextrema(data['Low'].values, np.less, order=5)[0]
support_levels = data['Low'].iloc[min_indices]

# Find local maxima (potential resistance)
max_indices = argrelextrema(data['High'].values, np.greater, order=5)[0]
resistance_levels = data['High'].iloc[max_indices]

Volume Analysis

Volume Indicators

# On-Balance Volume (OBV)
data['OBV'] = (np.sign(data['Close'].diff()) * data['Volume']).fillna(0).cumsum()

# Volume Moving Average
data['Volume_MA'] = data['Volume'].rolling(window=20).mean()

# Volume Price Trend (VPT)
data['VPT'] = (data['Close'].pct_change() * data['Volume']).fillna(0).cumsum()

Combining Indicators

Multi-Indicator Strategy

def generate_signals(data):
    signals = pd.DataFrame(index=data.index)
    signals['Price'] = data['Close']

    # Moving average signals
    signals['MA_Signal'] = 0
    signals.loc[data['SMA_20'] > data['SMA_50'], 'MA_Signal'] = 1
    signals.loc[data['SMA_20'] < data['SMA_50'], 'MA_Signal'] = -1

    # RSI signals
    signals['RSI_Signal'] = 0
    signals.loc[data['RSI'] < 30, 'RSI_Signal'] = 1  # Oversold
    signals.loc[data['RSI'] > 70, 'RSI_Signal'] = -1  # Overbought

    # MACD signals
    signals['MACD_Signal'] = 0
    signals.loc[data['MACD'] > data['Signal_Line'], 'MACD_Signal'] = 1
    signals.loc[data['MACD'] < data['Signal_Line'], 'MACD_Signal'] = -1

    # Combined signal (majority vote)
    signals['Combined'] = (signals['MA_Signal'] + 
                           signals['RSI_Signal'] + 
                           signals['MACD_Signal']) / 3

    return signals

Key Takeaways

  • Technical analysis uses price and volume patterns
  • Moving averages identify trends
  • Indicators (RSI, MACD, Bollinger Bands) provide trading signals
  • Support and resistance identify key price levels
  • Volume confirms price movements
  • Combining multiple indicators improves signal quality

Previous: Financial Data Analysis | Next: Statistical Concepts for Trading