TradingView策略警报止盈止损语法、返回值及Python配置问题
TradingView策略技术问题解答
止盈、止损的警报配置语法
- 止盈(TP)、止损(SL)的逻辑必须通过
strategy.exit()函数实现,绑定到对应strategy.entry()创建的持仓订单,无法通过普通strategy.order()实现可被警报识别的TP/SL逻辑。 - 核心参数写法:
- 按价差配置:
profit参数填写止盈触发的点数价差,loss参数填写止损触发的点数价差,示例:// 绑定id为long_my的多单,价差120点止盈,60点止损 strategy.exit("exit_long", "long_my", profit=120, loss=60) - 按固定价格配置:
limit参数填写止盈触发的具体价格,stop参数填写止损触发的具体价格,示例:// 绑定id为short_my的空单,价格跌到当前价95%止盈,涨到当前价103%止损 strategy.exit("exit_short", "short_my", limit=close*0.95, stop=close*1.03)
- 按价差配置:
- 警报创建规则:新建警报时选择对应策略实例,触发条件勾选「订单止盈触发」「订单止损触发」即可,不需要额外编写自定义触发条件,只要Pine Script中
strategy.exit写法正确,平台会自动捕获TP/SL触发事件。
注意:
strategy.exit必须传入对应开仓订单的ID(即strategy.entry的第一个参数),否则TP/SL不会绑定到对应持仓,警报无法正常触发。
TP/SL触发时strategy.order.action返回值与自动化交易适配
占位符返回值规则
TP/SL触发属于平仓类订单,strategy.order.action的返回值和平仓方向对应,和主动开反向仓的返回值完全一致,无法单独通过该字段区分是主动开仓还是TP/SL平仓:
- 多单TP/SL触发(平多卖出):返回
"sell" - 空单TP/SL触发(平空买入):返回
"buy"
适配方案
必须通过strategy.order.alert_message自定义占位符给不同类型的订单打标记,才能在webhook接收端区分信号类型,避免误触发开仓逻辑。
- 第一步:在Pine Script中给所有订单加自定义标记
// 主动开多信号 if (你的开多条件) strategy.entry("long_my", strategy.long, alert_message="sig_open_long") // 主动开空信号 if (你的开空条件) strategy.entry("short_my", strategy.short, alert_message="sig_open_short") // 多单TP/SL strategy.exit("exit_long_tp", "long_my", profit=120, alert_message="sig_tp_long") strategy.exit("exit_long_sl", "long_my", loss=60, alert_message="sig_sl_long") // 空单TP/SL strategy.exit("exit_short_tp", "short_my", profit=120, alert_message="sig_tp_short") strategy.exit("exit_short_sl", "short_my", loss=60, alert_message="sig_sl_short")
- 第二步:配置webhook推送的消息体,把标记字段带上
{ "action": "{{strategy.order.action}}", "signal_tag": "{{strategy.order.alert_message}}", "symbol": "{{ticker}}", "trigger_price": "{{close}}" }
- 第三步:编写Python webhook接收端逻辑,适配交易规则
预设规则为「收到buy信号平空开多」,TP/SL触发时仅平仓、不开新仓,参考实现如下:
from flask import Flask, request import json app = Flask(__name__) # 持仓状态记录,生产环境替换为交易接口的实时持仓查询 position = { "side": "short", # 可选值: long/short/empty "volume": 1 } # 交易动作封装,替换为实际对接的券商/交易所接口 def close_position(side): if side == "long": print("执行平多单操作") else: print("执行平空单操作") position["side"] = "empty" position["volume"] = 0 def open_position(side, volume=1): if side == "long": print(f"执行开{volume}单位多单操作") else: print(f"执行开{volume}单位空单操作") position["side"] = side position["volume"] = volume @app.route("/tv_webhook", methods=["POST"]) def handle_signal(): try: signal = json.loads(request.data) except: return "invalid format", 400 action = signal.get("action") tag = signal.get("signal_tag") # 优先处理止盈信号,仅平仓不开仓 if tag == "sig_tp_long": close_position("long") return "success", 200 if tag == "sig_tp_short": close_position("short") return "success", 200 # 止损信号逻辑和止盈一致,可按需扩展 if tag == "sig_sl_long": close_position("long") return "success", 200 if tag == "sig_sl_short": close_position("short") return "success", 200 # 处理主动开仓信号 if action == "buy" and tag == "sig_open_long": # 有空单先平 if position["side"] == "short": close_position("short") # 开多单 open_position("long") return "success", 200 if action == "sell" and tag == "sig_open_short": if position["side"] == "long": close_position("long") open_position("short") return "success", 200 return "unknown signal", 400 if __name__ == "__main__": app.run(host="0.0.0.0", port=8080)
关键注意点:绝对不要跳过自定义标记步骤,直接用strategy.order.action判断信号类型,否则会把TP/SL触发的平仓返回值误判为主动开仓信号,导致反向开仓、仓位错乱。
内容的提问来源于stack exchange,提问作者Mayank Agarwal
相关产品推荐
相关产品推荐

