3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于PTrade平台的简单期货均线策略。
rb2410.XSGE)。def initialize(context):
"""
初始化函数,设置全局变量和股票池
"""
# 设置要操作的期货合约代码,这里以螺纹钢2410为例
# 注意:实盘或回测时请确保合约代码在有效期内
g.security = 'rb2410.XSGE'
# 设置股票池(虽然是期货,也需要设置universe以便获取数据)
set_universe(g.security)
# 设定均线周期
g.short_window = 5 # 短期均线周期
g.long_window = 10 # 长期均线周期
# 设定交易数量(手)
g.trade_amount = 1
def handle_data(context, data):
"""
盘中运行函数,每个周期(如每天或每分钟)运行一次
"""
# 获取历史收盘价数据
# 获取长度为 长周期 + 2,确保有足够的数据计算均线和前一时刻的值
# count建议设置稍大一些,避免计算指标时数据不足
hist = get_history(count=g.long_window + 5, frequency='1d', field='close', security_list=g.security)
# 如果数据获取失败或长度不足,则直接返回
if hist is None or len(hist) < g.long_window + 2:
log.info("数据不足,跳过本次计算")
return
# 获取收盘价序列
close_prices = hist['close']
# 计算短期均线 (MA5)
ma_short = close_prices.rolling(window=g.short_window).mean()
# 计算长期均线 (MA10)
ma_long = close_prices.rolling(window=g.long_window).mean()
# 获取当前时刻(最新)的均线值
current_ma_short = ma_short.iloc[-1]
current_ma_long = ma_long.iloc[-1]
# 获取上一时刻的均线值(用于判断交叉)
prev_ma_short = ma_short.iloc[-2]
prev_ma_long = ma_long.iloc[-2]
# 获取当前持仓信息
position = get_position(g.security)
# 多头持仓数量
long_amount = position.long_amount
# --- 交易逻辑 ---
# 判断金叉:短期均线 上穿 长期均线
# 逻辑:上一时刻短线<=长线,且当前时刻短线>长线
golden_cross = (prev_ma_short <= prev_ma_long) and (current_ma_short > current_ma_long)
# 判断死叉:短期均线 下穿 长期均线
# 逻辑:上一时刻短线>=长线,且当前时刻短线<长线
death_cross = (prev_ma_short >= prev_ma_long) and (current_ma_short < current_ma_long)
# 执行交易
if golden_cross:
# 如果金叉且当前没有多头持仓,则买入开仓
if long_amount == 0:
log.info("金叉出现 (MA5: %.2f, MA10: %.2f),买入开仓 %s" % (current_ma_short, current_ma_long, g.security))
# 买入开仓
buy_open(g.security, g.trade_amount)
elif death_cross:
# 如果死叉且当前有多头持仓,则卖出平仓
if long_amount > 0:
log.info("死叉出现 (MA5: %.2f, MA10: %.2f),卖出平仓 %s" % (current_ma_short, current_ma_long, g.security))
# 卖出平仓
# 注意:上期所品种(如螺纹钢XSGE)区分平今和平昨,此处使用默认设置
# 若需优先平今仓,可设置 close_today=True
sell_close(g.security, long_amount)
get_history:
g.long_window + 5),是为了确保计算滚动平均值(rolling mean)时前面有足够的数据填充,避免计算结果为NaN。frequency='1d' 表示日线级别回测。如果需要分钟级别,可改为 '1m' 等。均线计算:
pandas 的 rolling(window=...).mean() 方法,这是计算移动平均线最标准、最高效的方法。交叉判断:
当前短线 > 当前长线 是不够的,这只能说明当前处于多头排列。期货特有API:
buy_open(合约, 数量): 买入开仓(做多)。sell_close(合约, 数量): 卖出平仓(平多头)。get_position(合约).long_amount: 获取多头持仓数量。期货持仓分为多头(long)和空头(short),与股票不同。Python兼容性:
% 格式化字符串(如 "MA5: %.2f" % value),这是为了兼容 Python 3.5 及更早版本,避免使用 f-string 导致报错。Q: 如何将策略改为分钟级别运行?
A: 在回测设置中将频率选为“分钟”,并将代码中 get_history 的 frequency 参数从 '1d' 改为 '1m' 或 '5m' 等即可。
Q: 如果我想做空(死叉开空单,金叉平空单)怎么改?
A: 需要使用 sell_open (卖出开仓) 和 buy_close (买入平仓)。同时通过 position.short_amount 获取空头持仓。
Q: 为什么代码里没有 import pandas?
A: PTrade 策略环境通常预置了 pandas、numpy 等常用库,且 get_history 返回的本身就是类似 DataFrame 的结构,可以直接调用 rolling 方法。如果报错,可以在文件开头添加 import pandas as pd。
Q: 上期所(XSGE)的平今仓和平昨仓有什么区别?
A: 上期所(如螺纹钢、铜)对平今仓(平掉当天开的仓位)和平昨仓(平掉昨天以前的仓位)的手续费规定可能不同。PTrade 的 sell_close 函数有一个 close_today 参数。默认为 False(优先平昨),如果设为 True 则仅平今仓。对于简单的策略,默认设置通常足够。