You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pine Script告警消息中strategy.position_size取值异常问题咨询

Pine Script策略告警获取最新持仓量方案

问题描述

  • 需求:在Pine Script策略内部获取订单成交后的最新持仓量(对应TradingView告警占位符{{strategy.market_position_size}}),用于拼接webhook POST请求的告警消息体
  • 初始实现逻辑:
    1. 调用内置变量strategy.position_size拼接告警消息
    2. 在告警创建页面的「Message」输入框填入{{strategy.order.alert_message}}占位符,调用脚本内预拼接的消息内容
    3. 告警配置界面:
      创建告警对话框
  • 初始测试代码:
//@version=5
// Webhook message test
strategy("Webhook test", overlay=true, initial_capital=1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 10)
alertID =""
// Limit processing time span
startDate = input.time(title="Start Date", defval=timestamp("30 Jun 2022 06:00:00 GMT-4"))
endDate = input.time(title="End Date", defval=timestamp("01 Jan 2024 06:00:00 GMT-4"))
BetweenDates = startDate <= time and time <= endDate

timeStamp = str.tostring(year, '0000')+str.tostring(month, '00')+str.tostring(dayofmonth, '00')+str.tostring(hour, '00')+str.tostring(minute, '00')
POSTmessage = '"Symbol": "'+syminfo.ticker+'", "timestamp": "'+timeStamp+'"'

EntryCondition = BetweenDates and ta.crossover(close, ta.sma(close,3))
ExitCondition = BetweenDates and ta.crossunder(close,ta.sma(close,3))

if EntryCondition
    alertID := str.tostring(timeStamp+syminfo.ticker)
    POSTmessage := POSTmessage +', "order_id": "'+alertID+', "order_action": "buy"'
if ExitCondition
    POSTmessage := POSTmessage +', "order_id": "'+alertID+', "order_action": "sell"'

//Order execution and alert
strategy.entry(id=alertID, direction=strategy.long, when = EntryCondition, alert_message='{'+POSTmessage+', "order_contratcs": '+str.tostring(strategy.position_size)+'}')
strategy.close(id=alertID, when = ExitCondition, alert_message='{'+POSTmessage+', "order_contratcs": '+str.tostring(strategy.position_size)+'}')
//paste into in [ Creat Alert > Message ] box:
//      {{strategy.order.alert_message}} 
  • 异常现象:触发strategy.entry开仓告警时,消息中持仓字段返回值为0,即平仓后的空仓状态,和开仓后实际持仓不符,告警效果如下:
    开仓触发时的告警弹窗

根因说明

Pine Script策略的持仓状态更新存在时序差:单根K线的脚本逻辑全部计算完成、所有订单指令提交给交易引擎后,才会更新strategy.position_size的返回值。因此在触发开仓/平仓指令的当根K线执行阶段,脚本内读取到的strategy.position_size永远是订单执行前的持仓值,对应占位符{{strategy.prev_market_position_size}},无法直接获取当笔订单成交后的最新持仓。


可行解决方案

方案1:脚本内自行计算成交后持仓(推荐,配置维护成本低)

不需要依赖内置持仓变量,直接根据订单方向、下单规则手动计算当笔订单成交后的持仓值,拼接到告警消息即可:

  • 开多场景:最新持仓 = 订单执行前持仓 + 本次开仓下单量
  • 全平场景:最新持仓 = 0
  • 部分平仓/开空场景逻辑可按相同规则推导

针对示例代码的修正逻辑如下,替换原有持仓取值部分即可:

// 提前计算当笔订单成交后的预期持仓
new_position_size = 0.0
if EntryCondition
    // 示例策略默认开10%权益的多仓,按此规则计算开仓后的持仓量
    // 固定仓位场景直接替换为对应下单数值即可
    qty = strategy.equity * 0.1 / close
    new_position_size := strategy.position_size + qty
if ExitCondition
    // strategy.close为全平指令,成交后持仓为0
    new_position_size := 0.0

// 订单与告警配置,替换原有的strategy.position_size为计算值
// 注意:原代码字段名order_contratcs存在拼写错误,建议修正为order_contracts避免webhook解析失败
strategy.entry(id=alertID, direction=strategy.long, when = EntryCondition, alert_message='{'+POSTmessage+', "order_contracts": '+str.tostring(new_position_size)+'}')
strategy.close(id=alertID, when = ExitCondition, alert_message='{'+POSTmessage+', "order_contracts": '+str.tostring(new_position_size)+'}')

方案2:告警配置页直接拼接内置占位符

无需在脚本内拼接持仓字段,直接在告警创建页的Message输入框中,调用TradingView内置的{{strategy.market_position_size}}占位符,该占位符会在告警触发时自动填充订单成交后的准确持仓值,配置示例:

{
    {{strategy.order.alert_message}},
    "order_contracts": {{strategy.market_position_size}}
}

该方案的缺点是消息结构拆分在脚本和告警配置两个位置维护,多策略批量部署时容易出现配置遗漏。


内容的提问来源于stack exchange,提问作者s21jb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:09:31