本方案由 EasyQuant AI量化助手 提供。
问题背景
实盘策略不能只考虑买入信号,还需要定义明确的退出规则。常见做法是:持仓盈利达到目标比例时止盈,持仓亏损达到风险阈值时止损,同时叠加均线或技术指标作为卖出条件。
PTrade 可以通过 get_position() 获取持仓成本和数量,再使用 order_target() 或 order_target_value() 将目标持仓调整为 0,实现自动卖出。order_target_value() 在实盘使用时需要注意持仓同步时滞,避免短时间重复下单。
实现思路
策略每次运行时执行以下步骤:
-
获取当前持仓;
-
计算最新价格相对持仓成本的收益率;
-
判断是否达到止盈或止损线;
-
检查是否存在未完成委托;
-
满足条件后卖出全部持仓。
完整示例代码
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) 卖出。实际使用时,建议结合可卖数量、未完成订单和趋势条件,形成更稳定的风控流程。

1590

被折叠的 条评论
为什么被折叠?



