3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 TRIX(三重指数平滑移动平均) 指标的量化交易策略。
TRIX 指标是一种研究股价趋势的长期技术分析工具。它过滤掉了短期波动的干扰,主要用于判断中长期的趋势。
计算方法:
交易逻辑:
# -*- coding: utf-8 -*-
import pandas as pd
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')
# 设定股票类每笔交易时的手续费
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# --- 策略参数设置 ---
# 要操作的标的(这里以平安银行为例,可修改为其他股票或ETF)
g.security = '000001.XSHE'
# TRIX指标参数
g.N = 12 # EMA的周期
g.M = 9 # TRIX均线(MATRIX)的周期
# 运行频率:每天开盘时运行
run_daily(market_open, time='09:30')
def market_open(context):
"""
每日开盘运行的逻辑
"""
security = g.security
# 1. 获取历史数据
# TRIX需要三重平滑,需要较长的历史数据才能使计算稳定
# 获取长度建议为 N * 5 + M 以上
fetch_len = g.N * 10 + g.M
# 获取收盘价数据
# 注意:include_now=True 在回测中如果是按天运行,取不到当天收盘价,只能取到昨天及之前的
# 这里我们取过去 fetch_len 天的数据(不含今天)
h_data = attribute_history(security, fetch_len, '1d', ['close'], df=True)
if len(h_data) < fetch_len:
log.info("数据不足,跳过当日")
return
close_prices = h_data['close']
# 2. 计算 TRIX 指标
# 计算三重指数移动平均 (EMA3)
# span=g.N 对应 alpha=2/(N+1)
ema1 = close_prices.ewm(span=g.N, adjust=False).mean()
ema2 = ema1.ewm(span=g.N, adjust=False).mean()
ema3 = ema2.ewm(span=g.N, adjust=False).mean()
# 计算 TRIX: (EMA3 - Ref(EMA3, 1)) / Ref(EMA3, 1) * 100
# pct_change() 计算的是 (curr - prev) / prev,正好符合公式,再乘以100
trix = ema3.pct_change() * 100
# 计算 MATRIX (TRIX的M日简单移动平均)
matrix = trix.rolling(window=g.M).mean()
# 3. 获取信号判断所需的数值
# 当前时刻(昨天收盘)的指标值
curr_trix = trix.iloc[-1]
curr_matrix = matrix.iloc[-1]
# 前一时刻(前天收盘)的指标值
prev_trix = trix.iloc[-2]
prev_matrix = matrix.iloc[-2]
# 检查是否有 NaN 值(数据计算初期可能产生NaN)
if np.isnan(curr_trix) or np.isnan(curr_matrix) or np.isnan(prev_trix) or np.isnan(prev_matrix):
return
# 4. 交易逻辑判断
# 获取当前仓位
position = context.portfolio.positions[security]
cash = context.portfolio.available_cash
# 金叉:TRIX 上穿 MATRIX
is_golden_cross = (prev_trix < prev_matrix) and (curr_trix > curr_matrix)
# 死叉:TRIX 下穿 MATRIX
is_death_cross = (prev_trix > prev_matrix) and (curr_trix < curr_matrix)
# 执行交易
if is_golden_cross:
# 如果有资金且未持仓(或根据策略加仓),则买入
if cash > 0:
log.info("TRIX金叉 (TRIX:%.3f, MATRIX:%.3f),买入 %s" % (curr_trix, curr_matrix, security))
order_value(security, cash)
elif is_death_cross:
# 如果持有仓位,则卖出
if position.closeable_amount > 0:
log.info("TRIX死叉 (TRIX:%.3f, MATRIX:%.3f),卖出 %s" % (curr_trix, curr_matrix, security))
order_target(security, 0)
# 记录指标值以便在回测图中查看
record(TRIX=curr_trix, MATRIX=curr_matrix)
数据获取 (attribute_history):
fetch_len = g.N * 10 + g.M,获取足够多的历史数据以确保指标收敛。指标计算 (pandas.ewm):
ewm(span=N, adjust=False) 来计算指数移动平均。adjust=False 是为了更贴近传统股票软件(如通达信、同花顺)的递归计算方式。trix = ema3.pct_change() * 100:利用 pct_change 快速计算变化率。信号判断:
prev_trix < prev_matrix 且 curr_trix > curr_matrix 判定为金叉。交易执行:
order_value 全仓买入(可根据需求调整仓位管理逻辑)。order_target 清仓卖出。Q: 如何更换要操作的股票?
A: 修改 initialize 函数中的 g.security = '000001.XSHE',将其改为你想要回测的股票代码(例如贵州茅台 '600519.XSHG')。
Q: 如何调整 TRIX 的灵敏度?
A: 修改 g.N 和 g.M。
g.N(如改为 20或30),指标会更平滑,过滤更多噪音,但信号会更滞后(适合长线)。g.N(如改为 5或8),指标会更敏感,信号更多,但假信号也可能增加(适合短线)。Q: 为什么回测初期没有交易?
A: 因为 TRIX 需要较长的历史数据来计算 EMA3。虽然我们获取了历史数据,但如果回测开始日期对应的历史数据不足以让 EMA 收敛,或者指标在初期没有发生交叉,就不会产生交易。