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

Pine Script中价格穿越Box下沿时标签不显示问题求助

Pine Script:价格穿越Box下沿时标签无法显示的修复方案

问题概述

编写的Pine Script代码可在满足特定条件时生成Box并存入数组,图表中Box能正常绘制,且价格穿越平均线时Box会自动截断。但尝试在价格high穿越Box下沿(boxlowzone或bear_box_low)时绘制标签,标签始终无法显示。代码可编译但条件从未触发,尝试过将标签逻辑嵌套在主条件内、单独编写、从数组调用Box值等方式,均无效。

核心原因

  1. 原代码将标签判断逻辑放在了Bear FVG生成的if块内,仅在生成Box的那根K线执行判断,而价格穿越Box下沿的动作几乎都发生在后续K线,此时该代码块不会执行,条件自然不会触发。
  2. 未对数组中已存在的所有Box进行遍历检查,仅关注了当前生成的Box,遗漏了历史Box的穿越情况。

修复方案

  1. 新增专门检查价格穿越Box下沿的函数,在每根K线遍历所有未被截断的Box,判断穿越条件。
  2. 将标签绘制逻辑从Box生成的代码块中移出,放入该函数内执行。
  3. 添加标记机制,避免同一Box被多次触发标签绘制。

修复后的完整代码

//@version=5
indicator("My FVG Detector - Tester"
  , overlay = true
  , max_boxes_count = 500
  , max_labels_count = 500
  , max_lines_count = 500)
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
//Fair Value Gaps
show_fvg = input(true, 'Fair Value Gaps (FVG)'
  , inline = 'fvg_css'
  , group = 'Fair Value Gaps')

bull_fvg_css = input.color(#2157f3, ''
  , inline = 'fvg_css'
  , group = 'Fair Value Gaps')

bear_fvg_css = input.color(#ff1100, ''
  , inline = 'fvg_css'
  , group = 'Fair Value Gaps')

fvg_usewidth = input(true, 'Min Width'
  , inline = 'fvg_width'
  , group = 'Fair Value Gaps')

fvg_gapwidth = input.float(1.95, ''
  , inline = 'fvg_width'
  , group = 'Fair Value Gaps')

fvg_method = input.string('ATR', ''
  , options = ['Points', '%', 'ATR']
  , inline = 'fvg_width'
  , group = 'Fair Value Gaps')

fvg_extend = input.int(3, 'Extend FVG'
  , minval = 0
  , group = 'Fair Value Gaps')

bull_entry = input.int(80, 'Bull Entry Threshold'
  , minval = 0
  , group = 'Fair Value Gaps')

bull_exit = input.int(80, 'Bull Exit Threshold'
  , minval = 0
  , group = 'Fair Value Gaps')

adboxcount = input.int (50, "Maximum Imb Displayed", 1, group = "Chart Customization")

//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{


n = bar_index
atr = ta.atr(200)

//Detect imbalance and return count over time
imbalance_detection(show, usewidth, method, width, top, btm, condition, wide)=>
    var is_width = true
    var count = 0
    
    if usewidth
        dist = top - btm
        bull_wide = top - btm

        is_width := switch method
            'Points' => dist > width
            '%' => dist / btm * 100 > width
            'ATR' => dist > atr * width

    is_true = show and condition and is_width
    count += is_true ? 1 : 0
    
    [is_true, count]

    
//-----------------------------------------------------------------------------}
//Arrays
//-----------------------------------------------------------------------------{

var box[] imbboxarray = array.new_box()
var line[] bear_avg_line = array.new_line()
var float[] bear_boxlow = array.new_float()
var bool[] box_label_triggered = array.new_bool() // 记录是否已绘制标签


//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
//Bullish
[bull_fvg, bull_fvg_count] = imbalance_detection(
  show_fvg
  , fvg_usewidth
  , fvg_method
  , fvg_gapwidth
  , low
  , high[2]
  , low > high[2] and close[1] > high[2]
  , high[2] - low)
bull_top = bull_fvg
bull_width = high[2] - low
bull_avg = math.avg(low, high[2])

//Bearish
[bear_fvg, bear_fvg_count] = imbalance_detection(
  show_fvg
  , fvg_usewidth
  , fvg_method
  , fvg_gapwidth
  , low[2]
  , high
  , high < low[2] and close[1] < low[2]
  , low[2] - high)
bear_top = bear_fvg
bear_width = low[2] - high
bear_avg = math.avg(low[2], high)
bearplot = high > low[1] ? 1 : 0


// Box & Line Calc {
f_choppedoffimb(imbboxarray, bear_avg_line) =>
    if array.size(imbboxarray) > 0 and array.size(bear_avg_line) > 0
        for i = array.size(imbboxarray) - 1 to 0 by 1
            cutbox = array.get(imbboxarray, i)
            cutline = array.get(bear_avg_line, i)
            boxhighzone = box.get_top(cutbox)
            boxlowzone = box.get_bottom(cutbox)
            boxrightzone = box.get_right(cutbox)
            bear_avg_right = line.get_x2(cutline)
            if na or bar_index - 1 == boxrightzone and not (high > boxhighzone)
                box.set_right(array.get(imbboxarray, i), bar_index)
                line.set_x2(array.get(bear_avg_line, i), bar_index)

// 检查价格穿越Box下沿并绘制标签
f_check_box_cross(imbboxarray, bear_avg_line) =>
    if array.size(imbboxarray) > 0 and array.size(bear_avg_line) > 0
        for i = array.size(imbboxarray) - 1 to 0 by 1
            // 跳过已触发过标签的Box
            if array.size(box_label_triggered) > i and array.get(box_label_triggered, i)
                continue
                
            target_box = array.get(imbboxarray, i)
            target_line = array.get(bear_avg_line, i)
            box_low = box.get_bottom(target_box)
            box_avg = line.get_y1(target_line)
            
            // 判断当前high是否上穿Box下沿
            if ta.crossover(high, box_low)
                label.new(bar_index, box_avg, "Bear", xloc = xloc.bar_index, color = color.red, style = label.style_arrowdown, textcolor = color.white, size = size.tiny)
                // 标记该Box已触发标签
                if array.size(box_label_triggered) <= i
                    array.push(box_label_triggered, true)
                else
                    array.set(box_label_triggered, i, true)

// }

// Box Draw {
if bear_top and bear_width > 0
    boxhighzone = low[2]
    boxlowzone = high[0]
    bear_box_low = low[1]
    bear_avg_right = bar_index
    imbbox = box.new(bar_index, boxhighzone, bar_index, boxlowzone, bear_fvg_css, border_style = line.style_dashed, bgcolor = color.new(bear_fvg_css, 80))
    midline = line.new(bar_index, bear_avg, bear_avg_right, bear_avg, color = color.red, style = line.style_solid)
    if array.size(imbboxarray) > adboxcount
        box.delete(array.shift(imbboxarray))
        line.delete(array.shift(bear_avg_line))
        array.shift(box_label_triggered) // 同步移除标记
    array.push(imbboxarray, imbbox)
    array.push(bear_avg_line, midline)
    array.push(bear_boxlow, low[1])
    array.push(box_label_triggered, false) // 初始化标记为未触发

// 执行截断检查和穿越检查
f_choppedoffimb(imbboxarray, bear_avg_line)
f_check_box_cross(imbboxarray, bear_avg_line)
// }

关键修复点

  • 新增box_label_triggered数组,记录每个Box是否已触发标签,避免重复绘制。
  • 新增f_check_box_cross函数,在每根K线遍历所有Box,检查high是否上穿Box下沿,满足条件则绘制标签。
  • 将标签绘制逻辑从Box生成的代码块中移出,确保每根K线都会执行检查。
  • 同步维护box_label_triggered数组,与Box数组的增删操作保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:17:04