🚀 AI 一键生成 ptrade 策略代码

PTrade 期货交易实战:如何编写一个简单的期货趋势跟踪策略?

ptrade | 发布时间: 2025/12/5
以下内容由 EasyQuant 生成。

问题描述

请帮我写一个简单的期货策略,比如跟踪均线,金叉就做多,死叉就平仓。

解决方案

这是一个基于PTrade平台的简单期货均线策略。

策略逻辑

  1. 标的:设定一个期货合约(例如螺纹钢 rb2410.XSGE)。
  2. 指标:使用两条均线,短期均线(5日)和长期均线(10日)。
  3. 开仓(做多):当短期均线上穿长期均线(金叉),且当前无持仓时,买入开仓。
  4. 平仓:当短期均线下穿长期均线(死叉),且当前有多头持仓时,卖出平仓。

策略代码

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)

代码关键点解析

  1. get_history:

    • 用于获取K线数据。这里我们获取了比长期均线周期稍多一点的数据(g.long_window + 5),是为了确保计算滚动平均值(rolling mean)时前面有足够的数据填充,避免计算结果为NaN。
    • frequency='1d' 表示日线级别回测。如果需要分钟级别,可改为 '1m' 等。
  2. 均线计算:

    • 使用了 pandasrolling(window=...).mean() 方法,这是计算移动平均线最标准、最高效的方法。
  3. 交叉判断:

    • 仅仅判断 当前短线 > 当前长线 是不够的,这只能说明当前处于多头排列。
    • 为了捕捉“交叉”动作,必须对比“上一时刻”和“当前时刻”的状态变化。
  4. 期货特有API:

    • buy_open(合约, 数量): 买入开仓(做多)。
    • sell_close(合约, 数量): 卖出平仓(平多头)。
    • get_position(合约).long_amount: 获取多头持仓数量。期货持仓分为多头(long)和空头(short),与股票不同。
  5. Python兼容性:

    • 代码使用了 % 格式化字符串(如 "MA5: %.2f" % value),这是为了兼容 Python 3.5 及更早版本,避免使用 f-string 导致报错。

Q&A

Q: 如何将策略改为分钟级别运行?
A: 在回测设置中将频率选为“分钟”,并将代码中 get_historyfrequency 参数从 '1d' 改为 '1m''5m' 等即可。

Q: 如果我想做空(死叉开空单,金叉平空单)怎么改?
A: 需要使用 sell_open (卖出开仓) 和 buy_close (买入平仓)。同时通过 position.short_amount 获取空头持仓。

Q: 为什么代码里没有 import pandas
A: PTrade 策略环境通常预置了 pandasnumpy 等常用库,且 get_history 返回的本身就是类似 DataFrame 的结构,可以直接调用 rolling 方法。如果报错,可以在文件开头添加 import pandas as pd

Q: 上期所(XSGE)的平今仓和平昨仓有什么区别?
A: 上期所(如螺纹钢、铜)对平今仓(平掉当天开的仓位)和平昨仓(平掉昨天以前的仓位)的手续费规定可能不同。PTrade 的 sell_close 函数有一个 close_today 参数。默认为 False(优先平昨),如果设为 True 则仅平今仓。对于简单的策略,默认设置通常足够。