🚀 AI 一键生成 ptrade 策略代码

PTrade 策略风控教程:如何编写一个动态追踪止损(Trailing Stop-Loss)策略?

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

问题描述

如何实现一个动态追踪止损策略?

解决方案

在PTrade中实现动态追踪止损(Trailing Stop)策略,核心逻辑是记录持仓后的最高价格,并根据设定的回撤比例(如5%)计算动态止损线。当当前价格跌破该止损线时触发卖出,否则如果价格创新高,则上调止损线。

以下是该策略的详细逻辑与代码实现。

策略逻辑说明

  1. 初始化 (initialize):

    • 设置标的股票。
    • 设定回撤阈值(例如 5%)。
    • 初始化一个全局变量(如 g.highest_price)用于记录持仓期间出现的最高价。
  2. 盘中运行 (handle_data):

    • 持仓判断: 检查当前是否有持仓。
    • 更新最高价: 如果有持仓,对比当前价格与 g.highest_price。如果当前价格更高,则更新 g.highest_price
    • 计算止损线: 止损价 = 最高价 * (1 - 回撤阈值)
    • 触发止损: 如果 当前价格 < 止损价,则清仓卖出,并重置最高价变量。
    • 开仓逻辑: (为了演示完整性) 如果无持仓,则买入,并将当前价格设为初始最高价。

PTrade 策略代码实现

def initialize(context):
    """
    策略初始化函数
    """
    # 1. 设置要操作的股票,这里以恒生电子为例
    g.security = '600570.SS'
    set_universe(g.security)
    
    # 2. 设置追踪止损的回撤比例 (例如 5%)
    g.trailing_gap = 0.05
    
    # 3. 用于记录持仓期间的最高价格,初始化为0
    g.highest_price = 0

def before_trading_start(context, data):
    """
    盘前处理
    """
    pass

def handle_data(context, data):
    """
    盘中每个时间单位(分钟或日)运行一次
    """
    security = g.security
    
    # 获取当前价格
    # 注意:data[security] 返回的是 SecurityUnitData 对象
    current_price = data[security].close
    
    # 获取当前持仓数量
    position = get_position(security)
    curr_amount = position.amount
    
    # --- 止损逻辑 (有持仓时执行) ---
    if curr_amount > 0:
        # 1. 更新持仓期间的最高价
        # 如果当前价格大于记录的最高价,或者刚买入尚未记录最高价
        if current_price > g.highest_price:
            g.highest_price = current_price
            log.info("股价创新高,更新最高价为: %.2f" % g.highest_price)
            
        # 2. 计算动态止损线
        stop_price = g.highest_price * (1 - g.trailing_gap)
        
        # 3. 判断是否触发止损
        if current_price < stop_price:
            log.info("触发追踪止损!当前价: %.2f, 历史最高: %.2f, 止损线: %.2f" % (current_price, g.highest_price, stop_price))
            
            # 卖出所有持仓
            order_target(security, 0)
            
            # 卖出后重置最高价,以便下次开仓重新计算
            g.highest_price = 0
            
    # --- 开仓逻辑 (无持仓时执行,仅作演示用) ---
    else:
        # 这里简单演示:如果没有持仓就全仓买入
        # 实际策略中,这里应该是你的买入信号逻辑(如均线金叉等)
        cash = context.portfolio.cash
        if cash > 0:
            # 买入
            order_value(security, cash)
            
            # 买入成交后,立即初始化最高价为当前价格
            g.highest_price = current_price
            log.info("开仓买入,初始最高价设定为: %.2f" % g.highest_price)

代码关键点解析

  1. g.highest_price 的维护:

    • 这是追踪止损的核心。它必须是全局变量(使用 g. 前缀),这样它的值才能在不同的 handle_data 周期之间保存。
    • 重要: 每次卖出清仓后,必须将 g.highest_price 重置为 0,否则下次买入时会错误地使用旧的(可能很高的)价格作为基准,导致瞬间止损。
  2. 止损线计算:

    • 公式:stop_price = g.highest_price * (1 - g.trailing_gap)
    • 这意味着止损线会随着股价上涨而不断上移,锁住利润;但股价下跌时,止损线保持不变。
  3. Python 版本兼容性:

    • 代码中使用了 % 格式化字符串(如 "%.2f" % var),这是为了兼容 Python 3.5 及更早版本,避免使用 PTrade 可能不支持的 f-string。
  4. API 使用:

    • get_position(security): 获取持仓对象,通过 .amount 属性判断是否持有。
    • order_target(security, 0): 这是一个方便的函数,用于将仓位调整为 0(即清仓),无需手动计算要卖多少股。

常见问题 (Q&A)

Q: 这个策略可以在分钟级别回测吗?
A: 可以。如果在 initialize 中设置回测频率为分钟级,handle_data 会每分钟执行一次,这样能更灵敏地捕捉盘中波动进行止损。

Q: 如果我有多个股票,怎么管理最高价?
A: 如果操作多只股票,建议将 g.highest_price 改为一个字典。例如:

# 初始化
g.highest_prices = {} 

# 盘中逻辑
if security not in g.highest_prices:
    g.highest_prices[security] = current_price
# 更新逻辑
if current_price > g.highest_prices[security]:
    g.highest_prices[security] = current_price

Q: 为什么卖出后要重置 g.highest_price = 0
A: 如果不重置,假设你以 100 元卖出,下次以 80 元买回。如果不重置,系统仍认为最高价是 100 元,止损线可能是 95 元。现价 80 元远低于 95 元,会导致刚买入就立即被卖出。