【PTrade】PTrade如何实现自动止盈止损?持仓收益率监控代码示例

本方案由 EasyQuant AI量化助手 提供。

问题背景

实盘策略不能只考虑买入信号,还需要定义明确的退出规则。常见做法是:持仓盈利达到目标比例时止盈,持仓亏损达到风险阈值时止损,同时叠加均线或技术指标作为卖出条件。

PTrade 可以通过 get_position() 获取持仓成本和数量,再使用 order_target()order_target_value() 将目标持仓调整为 0,实现自动卖出。order_target_value() 在实盘使用时需要注意持仓同步时滞,避免短时间重复下单。

实现思路

策略每次运行时执行以下步骤:

  1. 获取当前持仓;

  2. 计算最新价格相对持仓成本的收益率;

  3. 判断是否达到止盈或止损线;

  4. 检查是否存在未完成委托;

  5. 满足条件后卖出全部持仓。

完整示例代码

def initialize(context):
    g.security = "510300.SS"

    # 参数可以按策略需求调整
    g.take_profit_rate = 0.08   # 盈利8%止盈
    g.stop_loss_rate = -0.05    # 亏损5%止损

    set_universe([g.security])


def should_sell(position, current_price):
    """判断是否应该卖出。"""
    cost_price = position.cost_basis

    if cost_price <= 0:
        return False, "持仓成本价异常"

    profit_rate = current_price / cost_price - 1

    if profit_rate >= g.take_profit_rate:
        return True, "达到止盈线,当前收益率:%.2f%%" % (profit_rate * 100)

    if profit_rate <= g.stop_loss_rate:
        return True, "触发止损线,当前收益率:%.2f%%" % (profit_rate * 100)

    return False, "未触发止盈止损,当前收益率:%.2f%%" % (profit_rate * 100)


def has_open_order(security):
    """检查是否存在未完成委托,避免重复卖出。"""
    orders = get_open_orders(security)

    if orders:
        log.info("%s 存在未完成委托,暂不重复下单" % security)
        return True

    return False


def handle_data(context, data):
    security = g.security
    current_price = data[security].price

    # 获取当前持仓
    position = get_position(security)

    if position is None or position.amount <= 0:
        log.info("%s 当前无持仓" % security)
        return

    # A股卖出时,应使用可卖数量判断
    if position.enable_amount <= 0:
        log.info("%s 当前没有可卖持仓,可能受T+1限制" % security)
        return

    need_sell, reason = should_sell(position, current_price)

    log.info(
        "标的=%s,现价=%.3f,成本=%.3f,持仓=%s,可卖=%s,%s"
        % (
            security,
            current_price,
            position.cost_basis,
            position.amount,
            position.enable_amount,
            reason
        )
    )

    if not need_sell:
        return

    if has_open_order(security):
        return

    # 调整目标持仓为0,即卖出全部可处理持仓
    order_id = order_target(security, 0)

    if order_id:
        log.info("止盈止损委托已提交,订单号:%s,原因:%s" % (
            order_id, reason
        ))
    else:
        log.info("卖出委托提交失败,请检查账户、交易状态和日志")

如何增加均线保护卖出?

除了固定比例止盈止损,也可以把趋势条件加入卖出规则。例如,价格跌破 20 日均线时卖出:

def check_ma_exit(data, security):
    close_list = data.history(
        security,
        "close",
        20,
        "1d"
    )

    ma20 = close_list.mean()
    current_price = data[security].price

    return current_price < ma20

然后在 handle_data() 中增加判断:

if check_ma_exit(data, security):
    order_target(g.security, 0)
    log.info("价格跌破20日均线,执行卖出")

注意事项

  • cost_basis 是持仓成本价,收益率计算应基于成本价而非昨日收盘价。

  • 卖出前要检查 enable_amount,避免因 T+1 或冻结持仓导致卖出失败。

  • 下单前检查 get_open_orders(),可减少重复委托和重复撤单。

  • order_target() 返回订单编号不代表一定成交,仍需继续查询订单和成交状态。

  • 止损线并不能保证按理论价格成交,真实交易还会受到滑点、流动性、跌停等因素影响。

总结

PTrade 自动止盈止损的核心,是持续读取持仓成本与最新价格,计算收益率后调用 order_target(security, 0) 卖出。实际使用时,建议结合可卖数量、未完成订单和趋势条件,形成更稳定的风控流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值