3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 Elder-Ray Index (艾达透视指标) 的量化策略设计与代码实现。
Elder-Ray 指标由 Alexander Elder 博士开发,用于衡量市场中多头(买方)和空头(卖方)的力量。它由三个部分组成:
最高价 - EMA。衡量多头将价格推高至平均价值之上的能力。最低价 - EMA。衡量空头将价格压低至平均价值之下的能力。交易逻辑设计:
以下代码是一个完整的单标的策略示例。它使用了 pandas 计算 EMA,并使用 order_target_percent 进行仓位管理。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
'''
策略名称:Elder-Ray (艾达透视指标) 交易策略
策略逻辑:
1. 计算 13周期 EMA。
2. 计算 Bull Power = High - EMA。
3. 计算 Bear Power = Low - EMA。
4. 买入:收盘价 > EMA (趋势向上) 且 Bear Power < 0 (有回调) 且 Bear Power 上升 (回调结束迹象)。
5. 卖出:收盘价 < EMA (趋势破坏)。
'''
def init(ContextInfo):
# 1. 设置策略参数
ContextInfo.N = 13 # EMA 周期,Elder 建议 13
ContextInfo.trade_code = '600000.SH' # 示例标的:浦发银行
ContextInfo.account_id = 'YOUR_ACCOUNT_ID' # 请替换为您的资金账号
# 2. 设置股票池
ContextInfo.set_universe([ContextInfo.trade_code])
# 3. 设置交易账号 (实盘/回测都需要)
ContextInfo.set_account(ContextInfo.account_id)
# 4. 初始化全局变量
ContextInfo.holding = False # 简单的持仓标记
def handlebar(ContextInfo):
# 获取当前正在处理的 K 线位置
index = ContextInfo.barpos
# 获取当前图表的代码
stock_code = ContextInfo.trade_code
# 1. 获取历史行情数据
# 我们需要 High, Low, Close 来计算指标
# 获取足够长的数据以确保 EMA 计算准确,这里取 N + 50 根
data_len = ContextInfo.N + 50
# 使用 get_market_data_ex 获取数据 (效率更高)
# 注意:period='1d' 表示日线,根据实际运行周期调整
market_data = ContextInfo.get_market_data_ex(
['high', 'low', 'close'],
[stock_code],
period='1d',
count=data_len,
dividend_type='front' # 前复权
)
if stock_code not in market_data:
return
df = market_data[stock_code]
# 确保数据量足够
if len(df) < ContextInfo.N:
return
# 2. 计算 Elder-Ray 指标
# 计算 EMA (Exponential Moving Average)
df['ema'] = df['close'].ewm(span=ContextInfo.N, adjust=False).mean()
# 计算 Bull Power 和 Bear Power
df['bull_power'] = df['high'] - df['ema']
df['bear_power'] = df['low'] - df['ema']
# 3. 获取信号判断所需的数值
# 我们基于上一根 K 线收盘后的数据来决定当下的操作 (避免未来函数)
# iloc[-1] 是当前正在走的 K 线(如果是盘中),iloc[-2] 是上一根走完的 K 线
# 在回测模式下,handlebar 也是逐根运行,通常取 -1 代表当前回测时间点的数据
# 为了稳健,我们取最近两根数据进行比较
current_close = df['close'].iloc[-1]
current_ema = df['ema'].iloc[-1]
current_bear = df['bear_power'].iloc[-1]
prev_bear = df['bear_power'].iloc[-2]
# 4. 生成交易信号
# --- 买入逻辑 ---
# 条件 A: 价格在 EMA 之上 (趋势向上)
condition_trend_up = current_close > current_ema
# 条件 B: Bear Power 为负 (价格处于回调区域,非追高)
condition_dip = current_bear < 0
# 条件 C: Bear Power 正在增强 (空头力量减弱,柱状图向上)
condition_momentum = current_bear > prev_bear
buy_signal = condition_trend_up and condition_dip and condition_momentum
# --- 卖出逻辑 ---
# 条件: 收盘价跌破 EMA (趋势反转)
sell_signal = current_close < current_ema
# 5. 执行交易
# 获取当前持仓 (这里使用简单的 ContextInfo.holding 标记,实盘建议用 get_trade_detail_data 查询真实持仓)
# 如果是最后一根K线(实盘) 或者 回测模式
if not ContextInfo.is_last_bar() and not ContextInfo.do_back_test:
# 如果不是回测且不是最新K线,为了加快速度可以跳过,或者只计算指标不交易
return
# 执行买入
if buy_signal and not ContextInfo.holding:
print(f"[{stock_code}] 触发买入信号: Close={current_close:.2f}, EMA={current_ema:.2f}, Bear={current_bear:.2f}")
# 全仓买入 (目标仓位 100%)
order_target_percent(stock_code, 1.0, ContextInfo, ContextInfo.account_id)
ContextInfo.holding = True
# 执行卖出
elif sell_signal and ContextInfo.holding:
print(f"[{stock_code}] 触发卖出信号: Close={current_close:.2f}, EMA={current_ema:.2f}")
# 清仓 (目标仓位 0%)
order_target_percent(stock_code, 0.0, ContextInfo, ContextInfo.account_id)
ContextInfo.holding = False
数据获取 (get_market_data_ex):
get_market_data_ex 接口,这是 QMT 中获取历史数据最高效的方式。high (最高价), low (最低价), close (收盘价) 三个字段。dividend_type='front' 设置为前复权,这对于技术指标计算非常重要,避免分红除权导致 EMA 出现断层。指标计算 (pandas):
pandas 库。df['close'].ewm(span=N, adjust=False).mean():这是计算 EMA 的标准 Pandas 写法。span 对应 EMA 的周期。信号逻辑:
current_close > current_ema 保证大方向是向上的。current_bear < 0 保证当前价格并没有偏离均线过高,甚至可能低于均线(因为 Bear Power 是 Low - EMA),这是一个相对安全的买点。current_bear > prev_bear 是关键,意味着空头打压的力量正在减弱,价格可能即将反弹。交易执行 (order_target_percent):
order_target_percent 函数。1.0 代表买入至满仓(根据可用资金)。0.0 代表清仓。order_lots 更方便,因为它自动计算需要买卖的数量。YOUR_ACCOUNT_ID 替换为您真实的资金账号。ContextInfo.is_last_bar() 的判断,这是为了在实盘运行时,只在最新的 K 线数据更新时触发逻辑,避免对历史 K 线重复下单。Q: 如何在 QMT 中查看 Bear Power 和 Bull Power 的数值?
A: 您可以使用 ContextInfo.paint() 函数在 handlebar 中将计算出的数值画在副图上。例如:
ContextInfo.paint('BearPower', current_bear, -1, 0)
ContextInfo.paint('BullPower', current_bull, -1, 0)
Q: 这个策略适合什么类型的股票?
A: Elder-Ray 是一种趋势跟随策略,适合波动率适中且有明显趋势的个股或 ETF。在横盘震荡市中,EMA 会走平,导致价格频繁穿梭于 EMA 上下,从而产生虚假信号。
Q: 如何修改 EMA 的周期?
A: 在 init 函数中修改 ContextInfo.N = 13 这一行,将 13 改为您想要的数字即可。