3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 ADX (Average Directional Index) 和 DMI (Directional Movement Index) 指标的趋势跟踪策略。
ADX 指标主要用于判断趋势的强度,而不是方向。通常结合 DMI 指标中的 +DI (PDI) 和 -DI (MDI) 来判断方向。
指标定义:
交易信号:
参数设置:
# -*- coding: utf-8 -*-
import jqdata
import talib
import numpy as np
def initialize(context):
"""
初始化函数,设定基准、股票池、参数等
"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设定操作的股票,这里以平安银行为例
g.security = '000001.XSHE'
# 策略参数
g.N = 14 # ADX计算周期
g.adx_threshold = 25 # ADX趋势强度阈值
# 每天开盘时运行
run_daily(market_open, time='09:30')
def market_open(context):
"""
每日交易逻辑
"""
security = g.security
# 1. 获取历史数据
# talib计算ADX通常需要比周期更多的数据以保证平滑后的准确性,这里取 N * 3 天
lookback = g.N * 3
# 获取最高价、最低价、收盘价
data = attribute_history(security, lookback, '1d', ['high', 'low', 'close'])
# 如果数据不足,直接返回
if len(data) < lookback:
return
# 转换数据格式为 numpy array,talib 需要 float 类型
high_prices = data['high'].values.astype(float)
low_prices = data['low'].values.astype(float)
close_prices = data['close'].values.astype(float)
# 2. 计算指标
# 计算 ADX
adx = talib.ADX(high_prices, low_prices, close_prices, timeperiod=g.N)
# 计算 +DI (PDI)
pdi = talib.PLUS_DI(high_prices, low_prices, close_prices, timeperiod=g.N)
# 计算 -DI (MDI)
mdi = talib.MINUS_DI(high_prices, low_prices, close_prices, timeperiod=g.N)
# 获取最新的指标值(数组的最后一个元素)
current_adx = adx[-1]
current_pdi = pdi[-1]
current_mdi = mdi[-1]
# 获取当前持仓
position = context.portfolio.positions[security]
# 3. 交易逻辑
# 买入逻辑:ADX大于阈值(趋势强) 且 PDI大于MDI(多头趋势)
if current_adx > g.adx_threshold and current_pdi > current_mdi:
if position.total_amount == 0:
# 全仓买入
order_value(security, context.portfolio.available_cash)
log.info("买入信号触发: ADX={:.2f}, +DI={:.2f}, -DI={:.2f}".format(current_adx, current_pdi, current_mdi))
# 卖出逻辑:ADX小于阈值(趋势减弱) 或者 PDI小于MDI(空头反转)
elif current_adx < g.adx_threshold or current_pdi < current_mdi:
if position.closeable_amount > 0:
# 清仓卖出
order_target(security, 0)
log.info("卖出信号触发: ADX={:.2f}, +DI={:.2f}, -DI={:.2f}".format(current_adx, current_pdi, current_mdi))
# 4. 记录数据用于画图
record(ADX=current_adx, PDI=current_pdi, MDI=current_mdi)
talib 库,这是金融量化中计算技术指标最常用的库,计算效率高且准确。attribute_history):
high)、最低价 (low) 和收盘价 (close)。g.N * 3 天的数据。虽然参数是 14 天,但 ADX 算法内部包含平滑移动平均,获取更多历史数据可以减少计算初期的误差,使指标值更稳定。talib.ADX(...): 计算趋势强度。talib.PLUS_DI(...): 计算正向指标(多头力量)。talib.MINUS_DI(...): 计算负向指标(空头力量)。order_value 进行全仓买入。order_target 调整仓位至 0 进行平仓。position.closeable_amount > 0 判断,确保有可卖出的持仓(T+1 规则)。Q1: 为什么 ADX 指标有时候反应比较滞后?
A: ADX 是对价格波动的平滑处理,本质上是均线的一种衍生。任何基于均线的指标都会有滞后性。为了减少滞后,可以尝试减小计算周期 g.N(例如改为 10 或 7),但这可能会增加假信号(噪音)。
Q2: 如何在多只股票上运行这个策略?
A: 可以将 g.security 改为一个列表(例如 get_index_stocks('000300.XSHG')),然后在 market_open 函数中使用 for 循环遍历每只股票,分别计算指标并独立下单。同时需要注意资金分配(例如每只股票分配总资金的 1/10)。
Q3: 为什么代码中要获取 g.N * 3 天的数据?
A: talib 计算 ADX 时使用了 Wilder's Smoothing(威尔德平滑),这种算法对起始数据敏感。如果只获取 14 天数据,计算出的第一个 ADX 值可能不准确。获取更多历史数据可以让指标“预热”,使最终的计算结果与看盘软件一致。
Q4: 这个策略适合震荡市吗?
A: 不适合。ADX 本身就是为了区分趋势和震荡而设计的。当 ADX < 25 时,策略会选择空仓观望,从而避免在震荡市中反复止损。这是该策略的核心优势之一。