|
|
import pandas as pd |
|
|
import numpy as np |
|
|
|
|
|
def calculate_sma(data, period=20): |
|
|
"""Calculate Simple Moving Average.""" |
|
|
return data.rolling(window=period).mean() |
|
|
|
|
|
def calculate_ema(data, period=20): |
|
|
"""Calculate Exponential Moving Average.""" |
|
|
return data.ewm(span=period, adjust=False).mean() |
|
|
|
|
|
def calculate_rsi(data, period=14): |
|
|
"""Calculate Relative Strength Index.""" |
|
|
delta = data.diff() |
|
|
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() |
|
|
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() |
|
|
rs = gain / loss |
|
|
return 100 - (100 / (1 + rs)) |
|
|
|
|
|
def calculate_macd(data): |
|
|
"""Calculate MACD.""" |
|
|
exp1 = data.ewm(span=12, adjust=False).mean() |
|
|
exp2 = data.ewm(span=26, adjust=False).mean() |
|
|
macd = exp1 - exp2 |
|
|
signal = macd.ewm(span=9, adjust=False).mean() |
|
|
hist = macd - signal |
|
|
return pd.DataFrame({ |
|
|
'MACD': macd, |
|
|
'Signal': signal, |
|
|
'Histogram': hist |
|
|
}) |
|
|
|
|
|
def calculate_bollinger_bands(data, period=20, num_std=2): |
|
|
"""Calculate Bollinger Bands.""" |
|
|
sma = data.rolling(window=period).mean() |
|
|
std = data.rolling(window=period).std() |
|
|
upper = sma + (std * num_std) |
|
|
lower = sma - (std * num_std) |
|
|
return pd.DataFrame({ |
|
|
'Upper': upper, |
|
|
'Middle': sma, |
|
|
'Lower': lower |
|
|
}) |
|
|
|
|
|
def add_indicators(df): |
|
|
"""Add all technical indicators to the dataframe.""" |
|
|
df = df.copy() |
|
|
|
|
|
|
|
|
df['SMA_20'] = calculate_sma(df['Close'], 20) |
|
|
df['EMA_20'] = calculate_ema(df['Close'], 20) |
|
|
df['RSI'] = calculate_rsi(df['Close']) |
|
|
|
|
|
|
|
|
macd_data = calculate_macd(df['Close']) |
|
|
df['MACD'] = macd_data['MACD'] |
|
|
df['MACD_Signal'] = macd_data['Signal'] |
|
|
df['MACD_Hist'] = macd_data['Histogram'] |
|
|
|
|
|
|
|
|
bbands = calculate_bollinger_bands(df['Close']) |
|
|
df['BB_Upper'] = bbands['Upper'] |
|
|
df['BB_Middle'] = bbands['Middle'] |
|
|
df['BB_Lower'] = bbands['Lower'] |
|
|
|
|
|
return df |