3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT 平台的 ROC(变动率指标)动量策略实现。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
初始化函数,设定策略参数和账号
"""
# 策略参数设置
ContextInfo.N = 12 # ROC指标的周期,通常为12
ContextInfo.account_id = '6000000000' # 请在此处填写您的资金账号
ContextInfo.account_type = 'STOCK' # 账号类型:'STOCK'股票, 'FUTURE'期货
# 绑定账号,用于接收交易回报(实盘必须)
ContextInfo.set_account(ContextInfo.account_id)
print("策略初始化完成,ROC周期: {}".format(ContextInfo.N))
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 获取当前主图的股票代码
stock_code = ContextInfo.stockcode
# 确保是最后一根K线才下单(避免历史回测时的信号闪烁,实盘中通常只在最新K线判断)
# 如果是回测模式,每一根K线都会运行;如果是实盘,ContextInfo.is_last_bar()为True时代表最新行情
# 计算 ROC 需要 N 天前的数据,为了计算上一个 ROC(用于判断穿越),
# 我们至少需要 N + 2 根 K 线的数据。这里取 N + 10 以防万一。
count = ContextInfo.N + 10
# 获取历史行情数据
# 使用 get_market_data_ex 接口获取数据
data_dict = ContextInfo.get_market_data_ex(
['close'], # 获取收盘价
[stock_code], # 股票代码列表
period=ContextInfo.period, # 跟随主图周期
count=count, # 获取数量
dividend_type='front', # 前复权
fill_data=True # 停牌填充
)
# 检查数据是否获取成功
if stock_code not in data_dict:
return
df = data_dict[stock_code]
# 数据长度不足以计算 ROC 时直接返回
if len(df) < ContextInfo.N + 2:
return
# 获取收盘价序列 (转换为 numpy 数组提高计算效率)
closes = df['close'].values
# --- 计算 ROC 指标 ---
# 公式: ROC = (当前价格 - N天前价格) / N天前价格 * 100
# 1. 计算当前的 ROC (对应 closes[-1])
curr_price = closes[-1]
curr_ref_price = closes[-1 - ContextInfo.N] # N天前的价格
roc_curr = (curr_price - curr_ref_price) / curr_ref_price * 100
# 2. 计算上一根K线的 ROC (对应 closes[-2]),用于判断交叉
prev_price = closes[-2]
prev_ref_price = closes[-2 - ContextInfo.N] # (N+1)天前的价格
roc_prev = (prev_price - prev_ref_price) / prev_ref_price * 100
# --- 交易逻辑 ---
# 获取当前持仓
# 注意:回测模式下可用 ContextInfo.get_position() 或类似逻辑,
# 这里使用 order_target_percent 简化仓位管理,它会自动判断买卖方向
# 信号 1: ROC 上穿 0 轴 (金叉) -> 买入
if roc_prev < 0 and roc_curr > 0:
print(f"[{stock_code}] ROC上穿0轴 (前值:{roc_prev:.2f}, 现值:{roc_curr:.2f}) -> 触发买入")
# 调整仓位到 100% (全仓买入)
order_target_percent(stock_code, 1.0, ContextInfo, ContextInfo.account_id)
# 信号 2: ROC 下穿 0 轴 (死叉) -> 卖出
elif roc_prev > 0 and roc_curr < 0:
print(f"[{stock_code}] ROC下穿0轴 (前值:{roc_prev:.2f}, 现值:{roc_curr:.2f}) -> 触发卖出")
# 调整仓位到 0% (清仓卖出)
order_target_percent(stock_code, 0.0, ContextInfo, ContextInfo.account_id)
# (可选) 在图表上画出 ROC 值,方便调试
# ContextInfo.paint('ROC', roc_curr, -1, 0)
# -*- coding: gbk -*- 是 QMT Python 策略必须的,防止中文乱码。ContextInfo.get_market_data_ex,这是 QMT 推荐的高效数据接口。我们获取了 N + 10 条数据,确保有足够的历史数据来计算当前的 ROC 和前一时刻的 ROC。roc_curr:当前 K 线的 ROC 值。roc_prev:前一根 K 线的 ROC 值。order_target_percent。这是一个非常方便的高级函数:
1.0 时,系统会自动计算可用资金,买入直到满仓。0.0 时,系统会自动卖出该股票的所有持仓。init 函数中,请务必将 ContextInfo.account_id 修改为您实际的资金账号。init 函数中的 ContextInfo.account_id 为您的真实或模拟账号。Q: 如何修改 ROC 的周期参数?
A: 在代码的 init 函数中,修改 ContextInfo.N = 12 这一行,将 12 改为您想要的数字(例如 20 或 60)。
Q: 为什么使用 order_target_percent 而不是 passorder?
A: order_target_percent 是封装好的高级函数,它自动处理了“当前持有多少股”、“需要买卖多少股才能达到目标仓位”的计算逻辑,非常适合这种趋势跟踪策略。如果您需要更精细的控制(如指定价格、指定手数),可以使用 passorder。
Q: 这个策略可以用于期货吗?
A: 逻辑上可以,但需要修改下单函数。order_target_percent 主要用于股票。如果是期货,需要使用 buy_open (开多), sell_close (平多), sell_open (开空), buy_close (平空) 等函数,并且需要处理保证金和合约乘数。