Python 量化入门
技术指标实战
手撕 MA / MACD / RSI / KDJ / 布林带,对比 talib 库
技术指标是技术分析的语言。这一篇我们手撕几个最常用的指标,搞懂它们的计算原理,然后再用专业库 talib 做对照。
为什么要手撕
直接用库不香吗?香,但不知道指标怎么算出来的,就没办法在策略里灵活运用。手撕一遍后你就知道:
- MA 不是魔法,就是简单平均
- MACD 是两条均线的差再平滑
- RSI 是涨跌幅的比例
理解后,调参、改造、组合都游刃有余。
准备数据
pythonimport akshare as ak import pandas as pd import numpy as np import matplotlib.pyplot as plt df = ak.stock_us_daily(symbol="AAPL", adjust="qfq") df['date'] = pd.to_datetime(df['date']) df = df[df['date'] >= '2024-01-01'].set_index('date')
1. 移动平均线 MA
最简单的指标,就是 N 日收盘价的算术平均。
pythondf['MA5'] = df['close'].rolling(5).mean() df['MA20'] = df['close'].rolling(20).mean() df['MA60'] = df['close'].rolling(60).mean()
EMA(指数移动平均)
EMA 给最近的价格更高权重,对趋势变化更敏感:
pythondf['EMA12'] = df['close'].ewm(span=12, adjust=False).mean() df['EMA26'] = df['close'].ewm(span=26, adjust=False).mean()
💡
span=N等价于α = 2/(N+1),是约定俗成的写法。
2. MACD(指数平滑异同移动平均)
MACD 由三个部分组成:
- DIF(快线)= EMA12 - EMA26
- DEA(慢线)= DIF 的 9 日 EMA
- MACD 柱= 2 × (DIF - DEA)
pythondef calc_macd(close, fast=12, slow=26, signal=9): ema_fast = close.ewm(span=fast, adjust=False).mean() ema_slow = close.ewm(span=slow, adjust=False).mean() dif = ema_fast - ema_slow dea = dif.ewm(span=signal, adjust=False).mean() macd = 2 * (dif - dea) return dif, dea, macd df['DIF'], df['DEA'], df['MACD'] = calc_macd(df['close'])
信号判定
- DIF 上穿 DEA → 金叉,看多
- DIF 下穿 DEA → 死叉,看空
- MACD 柱由负转正 → 多头势能增强
pythondf['macd_golden'] = (df['DIF'] > df['DEA']) & (df['DIF'].shift(1) <= df['DEA'].shift(1)) df['macd_death'] = (df['DIF'] < df['DEA']) & (df['DIF'].shift(1) >= df['DEA'].shift(1))
3. RSI(相对强弱指数)
衡量价格涨跌的相对强度,输出 0-100 的值。
pythondef calc_rsi(close, period=14): delta = close.diff() gain = delta.where(delta > 0, 0) loss = -delta.where(delta < 0, 0) avg_gain = gain.rolling(period).mean() avg_loss = loss.rolling(period).mean() rs = avg_gain / avg_loss rsi = 100 - (100 / (1 + rs)) return rsi df['RSI14'] = calc_rsi(df['close'])
信号判定
- RSI > 70 → 超买区,警惕回调
- RSI < 30 → 超卖区,可能反弹
pythondf['rsi_overbought'] = df['RSI14'] > 70 df['rsi_oversold'] = df['RSI14'] < 30
4. KDJ
KDJ 由 K、D、J 三条线组成,对短线反转更敏感。
pythondef calc_kdj(df, n=9): low_n = df['low'].rolling(n).min() high_n = df['high'].rolling(n).max() rsv = (df['close'] - low_n) / (high_n - low_n) * 100 k = rsv.ewm(alpha=1/3, adjust=False).mean() d = k.ewm(alpha=1/3, adjust=False).mean() j = 3 * k - 2 * d return k, d, j df['K'], df['D'], df['J'] = calc_kdj(df)
信号判定
- K 上穿 D 且都在 20 以下 → 强买入
- K 下穿 D 且都在 80 以上 → 强卖出
- J 跌破 0 → 极度超卖
- J 突破 100 → 极度超买
5. 布林带(Bollinger Bands)
布林带由三条线组成:中轨(MA20) + 上下轨(中轨 ± 2 倍标准差)。
pythondef calc_boll(close, period=20, num_std=2): mid = close.rolling(period).mean() std = close.rolling(period).std() upper = mid + num_std * std lower = mid - num_std * std return upper, mid, lower df['BOLL_UP'], df['BOLL_MID'], df['BOLL_DOWN'] = calc_boll(df['close'])
用法
- 价格触及上轨 → 可能超买
- 价格触及下轨 → 可能超卖
- 带宽收窄 → 即将爆发
- 带宽扩张 → 趋势行情
6. ATR(真实波幅)
衡量市场波动率,常用于设置止损位。
pythondef calc_atr(df, period=14): high_low = df['high'] - df['low'] high_close = (df['high'] - df['close'].shift()).abs() low_close = (df['low'] - df['close'].shift()).abs() tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1) atr = tr.rolling(period).mean() return atr df['ATR14'] = calc_atr(df)
应用:基于 ATR 的动态止损
python# 入场后,止损位 = 入场价 - 2 × ATR df['stop_loss'] = df['close'] - 2 * df['ATR14']
用 talib 偷懒
手撕一遍后,正式写策略可以直接用 talib,几百个指标都现成的。
bashuv pip install ta-lib # macOS 可能需要先 brew install ta-lib
pythonimport talib df['SMA20'] = talib.SMA(df['close'], timeperiod=20) df['EMA12'] = talib.EMA(df['close'], timeperiod=12) df['RSI14'] = talib.RSI(df['close'], timeperiod=14) dif, dea, macd = talib.MACD(df['close'], fastperiod=12, slowperiod=26, signalperiod=9) df['DIF'], df['DEA'], df['MACD'] = dif, dea, macd upper, mid, lower = talib.BBANDS(df['close'], timeperiod=20) df['BOLL_UP'], df['BOLL_MID'], df['BOLL_DOWN'] = upper, mid, lower
⚠️ talib 安装坑 talib 是 C 语言库,安装可能需要先装系统依赖:
- macOS:
brew install ta-lib- Ubuntu:
apt install ta-lib- Windows: 下载预编译的 wheel 文件
如果嫌 talib 装起来麻烦,可以用纯 Python 的替代品:
bashuv pip install pandas-ta
pythonimport pandas_ta as ta df['RSI14'] = ta.rsi(df['close'], length=14) df['MACD'] = ta.macd(df['close'])
可视化技术指标
把 MACD 和价格放在一起看:
pythonimport mplfinance as mpf df_mpf = df.rename(columns={ 'open':'Open', 'high':'High', 'low':'Low', 'close':'Close', 'volume':'Volume' }) apds = [ mpf.make_addplot(df['DIF'], panel=2, color='#3b82f6', ylabel='MACD'), mpf.make_addplot(df['DEA'], panel=2, color='#ef4444'), mpf.make_addplot(df['MACD'], panel=2, type='bar', color='gray'), ] mpf.plot( df_mpf, type='candle', addplot=apds, volume=True, mav=(5, 20), panel_ratios=(3, 1, 2), figratio=(16, 10), style='yahoo', )
小结
到这里你已经会:
- ✅ 手算 MA / EMA / MACD / RSI / KDJ / 布林带 / ATR
- ✅ 用 talib 快速获取指标
- ✅ 在 K 线图上叠加指标
下一篇 双均线策略实战,我们把这些指标用到具体的策略里,写出你的第一个完整量化策略。
📌 学习建议 不要追求记住所有指标。常用的就 MA、MACD、RSI、布林带这几个。选 1-2 个吃透,比知道 50 个但都不熟有用得多。
本页导读