🚀 AI 一键生成 ptrade 策略代码

如何在 PTrade 平台实现一个基于布林带的均值回归策略?

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

问题描述

请帮我编写一个布林带交易策略,当价格跌破下轨时买入,突破上轨时卖出。

解决方案

这是一个基于布林带(Bollinger Bands)的均值回归交易策略。

策略逻辑

  1. 计算指标:利用过去 N 天(通常为20天)的收盘价计算移动平均线(中轨)和标准差。
    • 中轨 = N日收盘价均值
    • 上轨 = 中轨 + K * 标准差
    • 下轨 = 中轨 - K * 标准差
  2. 买入信号:当当前价格跌破下轨时,认为股价超卖,执行买入。
  3. 卖出信号:当当前价格突破上轨时,认为股价超买,执行卖出(清仓)。

PTrade 策略代码

import numpy as np

def initialize(context):
    """
    初始化函数,设置策略参数和股票池
    """
    # 设置我们要操作的股票,这里以贵州茅台(600519.SS)为例
    # 实际使用时可修改为其他股票代码
    g.security = '600519.SS'
    set_universe([g.security])
    
    # 设置基准指数,默认为沪深300
    set_benchmark('000300.SS')
    
    # 布林带参数设置
    g.n = 20  # 计算均值的周期,通常为20日
    g.k = 2   # 标准差的倍数,通常为2倍
    
    # 设置滑点和手续费(可选,根据实际情况调整)
    set_commission(commission_ratio=0.0003, min_commission=5.0, type='STOCK')
    set_slippage(slippage=0.002)

def handle_data(context, data):
    """
    盘中运行函数,每个单位时间(如每天或每分钟)调用一次
    """
    security = g.security
    
    # 获取该股票的历史收盘价数据
    # count=g.n 表示获取过去N个时间单位的数据
    # include=False 表示不包含当前时间点的数据(避免未来函数)
    hist = get_history(count=g.n, frequency='1d', field='close', security_list=security, include=False)
    
    # 检查数据长度是否足够,如果是新股可能数据不足
    if len(hist) < g.n:
        log.info("历史数据不足,跳过计算")
        return
    
    # 提取收盘价数组
    close_prices = hist['close'].values
    
    # 计算布林带指标
    # 1. 计算中轨(移动平均线)
    mid_band = np.mean(close_prices)
    
    # 2. 计算标准差
    std_dev = np.std(close_prices)
    
    # 3. 计算上轨和下轨
    upper_band = mid_band + g.k * std_dev
    lower_band = mid_band - g.k * std_dev
    
    # 获取当前最新价格
    current_price = data[security]['close']
    
    # 获取当前持仓数量
    position = context.portfolio.positions[security].amount
    
    # 获取当前可用资金
    cash = context.portfolio.cash
    
    # --- 交易逻辑 ---
    
    # 1. 买入逻辑:价格跌破下轨 且 当前无持仓
    if current_price < lower_band and position == 0:
        # 全仓买入
        order_value(security, cash)
        log.info("价格跌破下轨,买入 %s,价格: %.2f,下轨: %.2f" % (security, current_price, lower_band))
        
    # 2. 卖出逻辑:价格突破上轨 且 当前有持仓
    elif current_price > upper_band and position > 0:
        # 清仓卖出
        order_target(security, 0)
        log.info("价格突破上轨,卖出 %s,价格: %.2f,上轨: %.2f" % (security, current_price, upper_band))

    # 打印调试信息(可选)
    # log.info("当前价格: %.2f, 上轨: %.2f, 中轨: %.2f, 下轨: %.2f" % (current_price, upper_band, mid_band, lower_band))

代码说明

  1. initialize:
    • 使用 set_universe 设置股票池。
    • 定义了全局变量 g.n (周期) 和 g.k (标准差倍数),方便后续调整。
  2. handle_data:
    • 使用 get_history 获取过去20天的收盘价。注意 include=False,这意味着我们使用昨天及之前的20天数据来计算指标,用来指导今天的交易。
    • 使用 numpy (np.mean, np.std) 计算均值和标准差。
    • 买入条件: current_price < lower_band。使用 order_value 将所有现金买入股票。
    • 卖出条件: current_price > upper_band。使用 order_target(security, 0) 将持仓调整为0,即清仓。

常见问题 (Q&A)

Q: 如何修改布林带的周期,比如改成26天?
A: 在 initialize 函数中,将 g.n = 20 修改为 g.n = 26 即可。

Q: 这个策略可以用于分钟级别回测吗?
A: 可以。代码中的 get_history 参数 frequency='1d' 是日线级别。如果需要分钟级回测,请将回测频率设置为分钟,并将代码中的 '1d' 改为 '1m' (1分钟) 或 '5m' (5分钟) 等。

Q: 为什么使用 include=False
A: 在日线回测中,如果在盘中(比如上午10点)计算当天的均线,当天的收盘价还没确定,这会导致数据偏差。通常做法是利用截止到昨天的历史数据计算出轨道,然后观察今天的实时价格是否触碰这些轨道。

Q: 如何让策略交易多只股票?
A: 目前代码针对单只股票。如果要交易多只股票,需要在 handle_data 中使用 for 循环遍历 g.security (需将其设为列表),并对每只股票分别计算指标和下单。同时需要考虑资金分配问题(例如每只股票分配总资金的1/N)。