查看全课大纲(第 8 / 59 节)
  1. 1.量化投资必备基础知识
  2. 2.趋势型策略及模型原理
  3. 3.均值回复型策略及模型原理
  4. 4.配对交易策略及模型原理
  5. 5.量化策略研发流程与基本技能
  6. 6.常用的量化平台概述及如何选择
  7. 7.如何量化一个主观策略思路
  8. 8.常用技术指标及指标计算过程
  9. 9.如何编写指标代码
  10. 10.指标的物理意义
  11. 11.技术指标的应用技巧
  12. 12.更多的交易决策
  13. 13.编写程序去量化一个趋势型技术指标
  14. 14.编写趋势型技术指标的性能评价
  15. 15.策略对交易成本和持仓周期的影响
  16. 16.股票池策略的原理及基本框架
  17. 17.基于多因子分析的股票池设计与实现
  18. 18.股票池的性能评估
  19. 19.使用定制化财务因子构建股票池
  20. 20.趋势型策略原理及股票池机制的设计
  21. 21.趋势型择时信号的设计方法与编程实现
  22. 22.趋势型策略的回测与性能评估
  23. 23.优化趋势型策略的思路及方法
  24. 24.量化体系中的风险控制思想
  25. 25.风险的度量-波动率
  26. 26.常用的风险控制方法
  27. 27.实现止盈止损模块以提高策略性能
  28. 28.策略性能的评估与优化
  29. 29.探讨波动率与风险的关系
  30. 30.量化策略中的经典资金管理模型
  31. 31.用python编程实现资金管理模块
  32. 32.构建一个完善的量化交易策略
  33. 33.趋势型量化策略必备的期货知识
  34. 34.期货量化工具介绍
  35. 35.商品期货趋势型策略原理
  36. 36.用TB编写商品期货趋势型策略(上)
  37. 37.用TB编写商品期货趋势型策略(下)
  38. 38.分析优化商品期货趋势型策略的方法思路
  39. 39.期货交易策略的注意事项
  40. 40.均值回复型策略的原理
  41. 41.A股市场有没有稳定的均值回复效应?
  42. 42.编写一个均值回复型股票量化策略
  43. 43.编写多空组合策略进行策略改进
  44. 44.在策略中实现头寸管理进行策略优化
  45. 45.套利策略原理及常见套利类型
  46. 46.用MC开发一个跨品种套利交易策略(上)
  47. 47.用MC开发一个跨品种套利交易策略(下)
  48. 48.统计套利之股票配对交易策略
  49. 49.实盘中的细节问题:加减仓
  50. 50.关于高频交易
  51. 51.如何评价实盘量化策略的性能
  52. 52.量化系统的工作过程及研发流程
  53. 53.运气or实力
  54. 54.量化实盘交易需要满足什么条件
  55. 55.未来函数的坑
  56. 56.实盘数据接口异常的自动报警
  57. 57.交易系统的压力测试
  58. 58.自动运行的交易策略,什么时候需要人工干预
  59. 59.预案准备和实盘心理建设

常用技术指标及指标计算过程

约 9 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 进阶量化交易实战:迭代式的量化策略研发 本讲义仅用于编程与量化方法教学,不构成任何投资建议。

在量化交易与金融时间序列分析中,技术指标是提取市场特征、过滤高频噪音与刻画资产运行规律的核心数学工具。从简单的移动平均线到复杂的多周期振荡器,技术指标本质上是对开盘价、最高价、最低价、收盘价与成交量(OHLCV)等基础行情序列进行的非线性或线性数学变换。本讲系统梳理常用技术指标的数学机理、移动平均线家族的权重衰减特性,并建立工业级 Python 向量化指标计算管线。


💡 核心导读

  • 技术指标的数学本质与降维思想:
    • 降维与滤波:原始 K 线行情充斥着微观流动性冲击与随机游走噪音,技术指标通过滑动窗口(Rolling Window)与卷积平滑提取低频趋势与周期特征;
    • 状态映射:将连续的价格序列转化为具有统计学上下界(如 RSI、KDJ 的 [0, 100] 区间)或相对零轴对称的偏离度分布。
  • 移动平均线(MA)家族三大流派数学对比:
    • 简单移动平均(SMA):等权重算术平均,对历史与最新价格一视同仁,存在明显的滞后性与“尾部剔除效应”; SMAt=1N∑i=0N−1Pricet−iSMA_t = \frac{1}{N} \sum_{i=0}^{N-1} Price_{t-i}
    • 加权移动平均(WMA):线性递减权重,近期价格赋予更高权重: WMAt=∑i=0N−1(N−i)Pricet−i∑i=0N−1(N−i)WMA_t = \frac{\sum_{i=0}^{N-1} (N-i) Price_{t-i}}{\sum_{i=0}^{N-1} (N-i)}
    • 指数移动平均(EMA):无限冲激响应(IIR)平滑,近期权重呈几何级数衰减,天然消除尾部跳变: EMAt=αPricet+(1−α)EMAt−1,α=2N+1EMA_t = \alpha Price_t + (1-\alpha) EMA_{t-1}, \quad \alpha = \frac{2}{N+1}
  • 指标计算的量化工程铁律:
    • 严格遵循因果律(Causality),计算当前 Bar tt 的指标值时仅允许使用 tt 及历史数据,坚决杜绝未来函数。
┌─────────────────────────────────────────────────────────────┐
│                    技术指标特征提取与信号生成拓扑图         │
└──────────────────────────────┬──────────────────────────────┘
                               │
 原始 OHLCV 行情时序            ▲
 ┌─────────────────────────────┴─────────────────────────────┐
│ • Open, High, Low, Close, Volume, Open Interest             │
 └─────────────────────────────┬─────────────────────────────┘
                               │ (向量化滑动窗口变换)
 ┌───────────────┬─────────────┼─────────────┬───────────────┐
 ▼               ▼             ▼             ▼               ▼
┌─────────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────────┐
│1. 趋势型指标│ │2. 均值回复│ │3. 能量动量│ │4. 成交量型│ │ 5. 波动率型 │
├─────────────┤ ├───────────┤ ├───────────┤ ├───────────┤ ├─────────────┤
│ • SMA / EMA │ │ • 布林带  │ │ • MACD    │ │•OBV 能量潮│ │ • ATR 真实波│
│ • 唐奇安通道│ │ • KDJ / RSI│ │ • CCI / ROC│ │ • 量比 / VWAP││ • 历史波动率 │
└─────────────┘ └───────────┘ └───────────┘ └───────────┘ └─────────────┘

一、移动平均线算法推导与权重响应对比

移动平均线是所有技术指标的基石。不同的平滑权重对突发价格波动的敏感度截然不同:EMA 对最新价格跳空响应最灵敏,而 SMA 相对平缓但滞后性大。

import pandas as pd
import numpy as np

def calculate_ma_family(series, window=20):
    """
    计算移动平均线家族 (SMA, WMA, EMA)
    """
    # 1. 简单移动平均 SMA
    sma = series.rolling(window=window).mean()
    
    # 2. 指数移动平均 EMA
    ema = series.ewm(span=window, adjust=False).mean()
    
    # 3. 线性加权移动平均 WMA
    weights = np.arange(1, window + 1)
    wma = series.rolling(window=window).apply(lambda prices: np.dot(prices, weights) / weights.sum(), raw=True)
    
    return pd.DataFrame({
        'close': series,
        'SMA': sma,
        'EMA': ema,
        'WMA': wma
    })

# 合成价格序列,模拟一段趋势行情
rng = np.random.default_rng(42)
dates = pd.date_range(start='2024-01-01', periods=50, freq='D')
base_price = 100.0
price_series = base_price + np.cumsum(rng.normal(0.1, 0.8, 50))

# 计算移动平均线家族
ma_df = calculate_ma_family(pd.Series(price_series, index=dates), window=10)

print("===== 移动平均线家族计算示例 =====")
print(f"数据周期: {len(ma_df)} 个交易日")
print(f"价格序列范围: {price_series[0]:.2f} ~ {price_series[-1]:.2f}")
print("\n最后5个交易日的价格与移动平均线:")
print(ma_df[['close', 'SMA', 'EMA', 'WMA']].tail())
print("\n指标特性观察:")
print(f"  收盘价 > SMA10: {ma_df['close'].iloc[-1] > ma_df['SMA'].iloc[-1]}")
print(f"  EMA10 > SMA10: {ma_df['EMA'].iloc[-1] > ma_df['SMA'].iloc[-1]} (EMA对近期价格更敏感)")
print(f"  WMA10 > SMA10: {ma_df['WMA'].iloc[-1] > ma_df['SMA'].iloc[-1]} (WMA同样赋予近期更高权重)")
===== 移动平均线家族计算示例 =====
数据周期: 50 个交易日
价格序列范围: 100.34 ~ 108.65

最后5个交易日的价格与移动平均线:
                 close         SMA         EMA         WMA
2024-02-15  106.775228  105.870411  105.892271  106.144518
2024-02-16  107.572371  106.054077  106.197743  106.453965
2024-02-17  107.851247  106.322843  106.498380  106.780723
2024-02-18  108.494378  106.711880  106.861289  107.175548
2024-02-19  108.648441  107.054276  107.186226  107.527650

指标特性观察:
  收盘价 > SMA10: True
  EMA10 > SMA10: True (EMA对近期价格更敏感)
  WMA10 > SMA10: True (WMA同样赋予近期更高权重)

二、指标分类工程体系与无未来函数计算管线

在实际回测框架中,技术指标必须通过全向量化矩阵运算完成,以保证大规模股票池与高频数据的回测效率:

import pandas as pd
import numpy as np

def calculate_standard_indicators(df):
    """
    向量化计算典型技术指标矩阵 (严格防范未来函数)
    """
    res = df.copy()
    
    # 趋势指标: 20日均线与通道
    res['ma20'] = res['close'].rolling(20).mean()
    res['upper_channel'] = res['high'].rolling(20).max().shift(1)
    res['lower_channel'] = res['low'].rolling(20).min().shift(1)
    
    # 真实波幅 ATR
    tr1 = res['high'] - res['low']
    tr2 = (res['high'] - res['close'].shift(1)).abs()
    tr3 = (res['low'] - res['close'].shift(1)).abs()
    res['tr'] = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
    # SMA 口径 ATR(教学简化, 第14根才出值、换窗有跳变); Wilder 原版为递归平滑 res['tr'].ewm(alpha=1/14, adjust=False).mean(), TradingView/文华/通达信默认该口径
    res['atr14'] = res['tr'].rolling(14).mean()
    
    return res

# 合成行情数据,包含价格波动与跳空
rng = np.random.default_rng(123)
n_bars = 60
dates = pd.date_range(start='2024-03-01', periods=n_bars, freq='D')
base_close = 50.0
close_prices = base_close + np.cumsum(rng.normal(0.05, 1.2, n_bars))
# 模拟一个跳空缺口
close_prices[40:] += 8.0

df_synth = pd.DataFrame({
    'open': close_prices - rng.uniform(0.1, 0.5, n_bars),
    'high': close_prices + rng.uniform(0.2, 1.0, n_bars),
    'low': close_prices - rng.uniform(0.5, 1.2, n_bars),
    'close': close_prices,
    'volume': rng.integers(10000, 50000, n_bars)
}, index=dates)

# 计算技术指标
df_with_indicators = calculate_standard_indicators(df_synth)

print("===== 常用技术指标向量化计算 =====")
print(f"数据样本数: {len(df_with_indicators)}")
print(f"有效指标样本数 (滚动窗口后): {df_with_indicators['ma20'].notna().sum()}")
print("\n最后交易日的指标值:")
last_idx = -1
print(f"  收盘价: {df_with_indicators['close'].iloc[last_idx]:.2f}")
print(f"  MA20: {df_with_indicators['ma20'].iloc[last_idx]:.2f}")
print(f"  上通道: {df_with_indicators['upper_channel'].iloc[last_idx]:.2f}")
print(f"  下通道: {df_with_indicators['lower_channel'].iloc[last_idx]:.2f}")
print(f"  ATR14: {df_with_indicators['atr14'].iloc[last_idx]:.4f} (平均真实波幅)")
print("\n关键风控点:")
print(f"  价格突破上通道: {df_with_indicators['close'].iloc[last_idx] > df_with_indicators['upper_channel'].iloc[last_idx]}")
print(f"  价格跌破下通道: {df_with_indicators['close'].iloc[last_idx] < df_with_indicators['lower_channel'].iloc[last_idx]}")
print(f"  ATR/收盘价比率: {(df_with_indicators['atr14'].iloc[last_idx] / df_with_indicators['close'].iloc[last_idx])*100:.2f}%")
===== 常用技术指标向量化计算 =====
数据样本数: 60
有效指标样本数 (滚动窗口后): 41

最后交易日的指标值:
  收盘价: 67.87
  MA20: 68.97
  上通道: 71.05
  下通道: 59.55
  ATR14: 1.7918 (平均真实波幅)

关键风控点:
  价格突破上通道: False
  价格跌破下通道: False
  ATR/收盘价比率: 2.64%

📝 动手练一练

下面我们用 Python 编写一段 常用技术指标向量化计算与响应测试脚本,模拟全时序数据清洗与 SMA/EMA/ATR 指标输出:

import pandas as pd
import numpy as np

def run_indicators_calculation():
    """
    技术指标向量化计算与输出模拟
    """
    rng = np.random.default_rng(42)
    dates = pd.date_range("2023-01-01", periods=60, freq="B")
    
    # 构造含有一段突发脉冲的行情
    p = 100.0 + np.cumsum(rng.normal(0.05, 1.0, 60))
    p[35:] += 5.0  # 模拟跳空突发价格
    
    df = pd.DataFrame({
        'open': p - 0.2,
        'high': p + 0.5,
        'low': p - 0.5,
        'close': p,
        'volume': rng.uniform(1000, 5000, 60)
    }, index=dates)
    
    # 计算 SMA20, EMA20 与 ATR14
    df['sma20'] = df['close'].rolling(20).mean()
    df['ema20'] = df['close'].ewm(span=20, adjust=False).mean()
    
    tr1 = df['high'] - df['low']
    tr2 = (df['high'] - df['close'].shift(1)).abs()
    tr3 = (df['low'] - df['close'].shift(1)).abs()
    # SMA 口径 ATR; Wilder 原版为 TR 的 ewm(alpha=1/14, adjust=False).mean() 递归平滑(主流行情软件默认口径)
    df['atr14'] = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1).rolling(14).mean()
    
    res = {
        "Total_Bars": len(df),
        "Last_Close": f"{df['close'].iloc[-1]:.2f} 元",
        "Last_SMA20": f"{df['sma20'].iloc[-1]:.2f} 元",
        "Last_EMA20": f"{df['ema20'].iloc[-1]:.2f} 元",
        "Last_ATR14": f"{df['atr14'].iloc[-1]:.2f} 元",
        "EMA_vs_SMA_Lead": f"{(df['ema20'].iloc[-1] - df['sma20'].iloc[-1]):.2f} 元 (EMA 响应更快)"
    }
    return res

# 执行计算并输出结果
res = run_indicators_calculation()
print("================ 常用技术指标向量化计算测试 ================")
for k, v in res.items():
    print(f"  - {k:<20}: {v}")
print("----------------------------------------------------------")
print("量化精髓: 熟练掌握指标数学内涵,严格使用向量化滚动计算杜绝未来函数!")
print("==========================================================")

运行结果输出:

================ 常用技术指标向量化计算测试 ================
  - Total_Bars          : 60
  - Last_Close          : 111.92 元
  - Last_SMA20          : 110.93 元
  - Last_EMA20          : 110.26 元
  - Last_ATR14          : 1.26 元
  - EMA_vs_SMA_Lead     : -0.67 元 (EMA 响应更快)
----------------------------------------------------------
量化精髓: 熟练掌握指标数学内涵,严格使用向量化滚动计算杜绝未来函数!
==========================================================

👉 点击查看解析

本练习通过复现常用技术指标的计算过程,重点演示了如何基于历史价格序列进行滚动统计与公式实现,从而加深对指标含义及其计算细节的理解。

本章小结

  1. 领会指标降维本质:技术指标是对市场原始行情的高维特征提取与噪音滤波,服务于定量决策。
  2. 区分均线平滑权重:根据策略对时间敏感度的要求,合理选用 SMA(平稳)或 EMA(灵敏)。
  3. 推行向量化工程实现:利用 pandas.rolling() 与 ewm() 打造高性能、无未来函数的标准指标库。

📋 行动清单 (Action Checklist)

  • 运行本讲技术指标计算代码,观察跳空行情下 EMA 与 SMA 的响应时滞差异;
  • 尝试为自己的量化框架封装通用的 ATR 与真实波幅计算函数;
  • 预习下一节,深入学习趋势型技术指标(MACD、EMA、唐奇安通道)的经典形态量化。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第2章课件:从技术的角度重新认识技术指标
    PDF · 1.8MB
    下载
  • 第2章配套代码包(Python 重构版 · 已实测)
    ZIP · 11KB
    下载
  • 第2章原始代码包(历史资料)
    ZIP · 42KB
    下载