AKShare Technical Indicators¶
This documentation is an English translation of the original AKShare documentation.
Back to original Chinese documentation →
Technical Indicators¶
AKShare provides various technical indicators for financial analysis.
Moving Averages¶
Simple Moving Average (SMA)¶
import akshare as ak
import pandas as pd
def calculate_sma(df, window=20):
"""Calculate Simple Moving Average."""
return df['close'].rolling(window=window).mean()
# Example
df = ak.stock_zh_a_daily(symbol="600519")
df['SMA20'] = calculate_sma(df, 20)
print(df[['date', 'close', 'SMA20']].tail())
Exponential Moving Average (EMA)¶
def calculate_ema(df, span=20):
"""Calculate Exponential Moving Average."""
return df['close'].ewm(span=span, adjust=False).mean()
df['EMA20'] = calculate_ema(df, 20)
Weighted Moving Average (WMA)¶
def calculate_wma(df, window=20):
"""Calculate Weighted Moving Average."""
weights = pd.Series(range(1, window + 1))
return df['close'].rolling(window).apply(lambda prices: pd.Series(prices).dot(weights) / weights.sum(), raw=True)
df['WMA20'] = calculate_wma(df, 20)
Momentum Indicators¶
RSI (Relative Strength Index)¶
def calculate_rsi(df, period=14):
"""Calculate RSI."""
delta = df['close'].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))
df['RSI'] = calculate_rsi(df)
MACD (Moving Average Convergence Divergence)¶
def calculate_macd(df, fast=12, slow=26, signal=9):
"""Calculate MACD."""
ema_fast = df['close'].ewm(span=fast, adjust=False).mean()
ema_slow = df['close'].ewm(span=slow, adjust=False).mean()
macd = ema_fast - ema_slow
signal_line = macd.ewm(span=signal, adjust=False).mean()
histogram = macd - signal_line
return macd, signal_line, histogram
df['MACD'], df['Signal'], df['Histogram'] = calculate_macd(df)
Volatility Indicators¶
Bollinger Bands¶
def calculate_bollinger_bands(df, window=20, std_dev=2):
"""Calculate Bollinger Bands."""
middle = df['close'].rolling(window=window).mean()
std = df['close'].rolling(window=window).std()
upper = middle + (std_dev * std)
lower = middle - (std_dev * std)
return upper, middle, lower
df['Upper'], df['Middle'], df['Lower'] = calculate_bollinger_bands(df)
ATR (Average True Range)¶
def calculate_atr(df, period=14):
"""Calculate ATR."""
high_low = df['high'] - df['low']
high_close = abs(df['high'] - df['close'].shift())
low_close = abs(df['low'] - df['close'].shift())
tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
return tr.rolling(window=period).mean()
df['ATR'] = calculate_atr(df)
Trend Indicators¶
ADX (Average Directional Index)¶
def calculate_adx(df, period=14):
"""Calculate ADX."""
# Calculate +DI and -DI
high_diff = df['high'].diff()
low_diff = -df['low'].diff()
plus_di = 100 * (high_diff.rolling(window=period).mean() / df['close'].rolling(window=period).mean())
minus_di = 100 * (low_diff.rolling(window=period).mean() / df['close'].rolling(window=period).mean())
# Calculate ADX
dx = abs(plus_di - minus_di) / (plus_di + minus_di)
adx = dx.rolling(window=period).mean() * 100
return plus_di, minus_di, adx
df['Plus_DI'], df['Minus_DI'], df['ADX'] = calculate_adx(df)
Parabolic SAR¶
def calculate_psar(df, af=0.02, max_af=0.2):
"""Calculate Parabolic SAR."""
# Implementation requires iterative calculation
# This is a simplified version
return None # Requires more complex implementation
Volume Indicators¶
OBV (On-Balance Volume)¶
def calculate_obv(df):
"""Calculate On-Balance Volume."""
obv = [0]
for i in range(1, len(df)):
if df['close'].iloc[i] > df['close'].iloc[i-1]:
obv.append(obv[-1] + df['volume'].iloc[i])
elif df['close'].iloc[i] < df['close'].iloc[i-1]:
obv.append(obv[-1] - df['volume'].iloc[i])
else:
obv.append(obv[-1])
return obv
df['OBV'] = calculate_obv(df)
VWAP (Volume Weighted Average Price)¶
def calculate_vwap(df):
"""Calculate VWAP."""
return (df['close'] * df['volume']).cumsum() / df['volume'].cumsum()
df['VWAP'] = calculate_vwap(df)
Complete Example¶
import akshare as ak
import pandas as pd
import matplotlib.pyplot as plt
# Get data
df = ak.stock_zh_a_daily(symbol="600519", start_date="2024-01-01")
# Calculate indicators
df['SMA20'] = df['close'].rolling(20).mean()
df['SMA60'] = df['close'].rolling(60).mean()
df['RSI'] = calculate_rsi(df)
df['MACD'], df['Signal'], df['Histogram'] = calculate_macd(df)
# Plot
fig, axes = plt.subplots(4, 1, figsize=(12, 16))
# Price with SMA
axes[0].plot(df['date'], df['close'], label='Close')
axes[0].plot(df['date'], df['SMA20'], label='SMA20')
axes[0].plot(df['date'], df['SMA60'], label='SMA60')
axes[0].legend()
# RSI
axes[1].plot(df['date'], df['RSI'], label='RSI')
axes[1].axhline(y=70, color='r', linestyle='--')
axes[1].axhline(y=30, color='g', linestyle='--')
# MACD
axes[2].plot(df['date'], df['MACD'], label='MACD')
axes[2].plot(df['date'], df['Signal'], label='Signal')
# Volume
axes[3].bar(df['date'], df['volume'])
plt.tight_layout()
plt.show()
**AKShare** | *Open Data. Open Minds.*
[GitHub](https://github.com/akfamily/akshare) • [Documentation](https://akshare.akfamily.xyz)