注释独立if语句为何影响前置if语句的运行结果?
问题解释:注释/取消注释
if barstate.isconfirmed为何影响if barstate.isnew的运行结果? 在Bybit平台BTCUSDT.P合约1M周期运行以下Pine Script脚本时,注释或取消注释if barstate.isconfirmed代码块,会改变前置if barstate.isnew代码块的标签显示结果:注释该块时,标签从最早的bar(bar_index=0)就开始显示;取消注释后,标签仅从2020年12月左右(第3根3M K线收盘后)才开始显示,原因如下:
// Run this on 1M timeframe for BTCUSDT.P on Bybit //@version=5 indicator("HTF bar_index", overlay = true) type htfData int htfBi htfF1(htfData _htf) => _htf.htfBi := bar_index _htf var htfD = htfData.new() var naHtfD = htfData.new() htfD := request.security(syminfo.tickerid, "3M", (timeframe.period == "3M") ? htfF1(htfD) : na, lookahead = barmerge.lookahead_off) htfD := na(htfD) ? naHtfD : htfD if barstate.isnew lb = label.new(bar_index, high, str.tostring(htfD.htfBi), style = label.style_label_down, color = color.rgb(70, 255, 240)) // if the following block is commented then the above block prints labels from the 0's bar // but if the folloiwing block is uncommented the labels only appear starting from Dec'20, the (3'rd 3M bar close) // if barstate.isconfirmed // lb2 = label.new(bar_index, low, str.tostring(htfD.htfBi), style = label.style_label_up, color = color.yellow) plotchar(na(htfD) ? na : htfD.htfBi, "htfD.htfBi","", location.belowbar)
核心原因拆解
var变量的跨周期共享特性
脚本里的htfD是用var声明的自定义类型变量,属于全局共享变量——1M周期的主脚本,和request.security调用的3M周期子脚本会共用同一个htfD实例,子脚本对htfD的修改会直接同步到主脚本中。request.security的执行时机与barstate的交互- 注释
if barstate.isconfirmed的情况:
主脚本只在barstate.isnew(1M K线刚生成)阶段执行代码,此时request.security会在每个新1M K线生成时调用3M周期子脚本。对于最早的一批1M K线,3M周期的子脚本会直接将htfD.htfBi设为3M周期的初始bar_index=0,并返回这个有效值,所以主脚本的if barstate.isnew块能生成显示0的标签。 - 取消注释
if barstate.isconfirmed的情况:
主脚本会在barstate.isconfirmed(1M K线收盘)阶段也执行代码,这会触发request.security在1M K线收盘时再次调用3M周期子脚本。由于设置了lookahead=barmerge.lookahead_off,request.security只会返回3M周期已收盘K线的数据——在前两根3M K线未收盘时,子脚本返回na,主脚本会把htfD替换为初始值naHtfD(其htfBi为na),导致str.tostring(na)无法生成有效标签。直到第3根3M K线收盘后,request.security才会返回带有有效bar_index的htfD,标签才开始正常显示。
- 注释
多次
request.security调用的变量覆盖
当存在if barstate.isconfirmed块时,主脚本在isnew和isconfirmed阶段都会调用request.security。如果3M K线尚未收盘,isconfirmed阶段的调用会返回na,将htfD重置为naHtfD,覆盖掉isnew阶段可能获取到的临时值,最终导致标签无法显示。
内容的提问来源于stack exchange,提问作者Moebius
相关产品推荐
相关产品推荐

