Pine Script告警消息中strategy.position_size取值异常问题咨询
Pine Script策略告警获取最新持仓量方案
问题描述
- 需求:在Pine Script策略内部获取订单成交后的最新持仓量(对应TradingView告警占位符
{{strategy.market_position_size}}),用于拼接webhook POST请求的告警消息体 - 初始实现逻辑:
- 调用内置变量
strategy.position_size拼接告警消息 - 在告警创建页面的「Message」输入框填入
{{strategy.order.alert_message}}占位符,调用脚本内预拼接的消息内容 - 告警配置界面:

- 调用内置变量
- 初始测试代码:
//@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
相关产品推荐
相关产品推荐

