Pine Script牛/熊旗形线延伸异常问题求助
Pine Script v5 牛/熊旗形线延伸问题修复思路
需求与问题
- 需求:绘制牛/熊旗形线,价格处于旗形上下线区间内时线条持续延伸;价格离开区间后,后续再回到区间时线条不再延伸。
- 当前问题:原代码在价格后续返回区间时会错误延伸线条;添加
closed变量控制后,线条完全无法延伸。
原代码
//@version=5 indicator("Line Extension", overlay=true, max_lines_count=20) ph = ta.pivothigh(high,5,5) pl = ta.pivotlow(low,5,5) plotshape(ph, color=#FF0000, location=location.abovebar, offset=-5) plotshape(pl, color=#00E600, location=location.belowbar, offset=-5) var line [] flag_array = array.new_line() var flag_price = array.new_float() var flag_index = array.new_int() var flag_price2 = array.new_float() var flag_index2 = array.new_int() var lastIn = 0 arraySize = input.int(20, title="Array Size") add_to_array(_price,_index,_val) => array.unshift(_price,_val) array.unshift(_index,bar_index) if array.size(_index)>arraySize array.pop(_price) array.pop(_index) if ph add_to_array(flag_price,flag_index,ph) if pl add_to_array(flag_price2,flag_index2,pl) draw_lines(_price, _index, _lineArray)=> if array.size(_index)>=4 x1 = array.get(_index,1)-5 y1 = array.get(_price,1) x2 = array.get(_index,0)-5 y2 = array.get(_price,0) array.push(_lineArray, line.new(x1,y1,x2,y2, color=color.white)) array.clear(_price) array.clear(_index) extend_lines(lineArray,_close,_index)=> if array.size(lineArray)>1 recentLine = array.get(lineArray,0) olderLine = array.get(lineArray,1) x1 = line.get_x1(recentLine) y1 = line.get_y1(recentLine) x2 = line.get_x2(recentLine) y2 = line.get_y2(recentLine) x11 = line.get_x1(olderLine) y11 = line.get_y1(olderLine) x22 = line.get_x2(olderLine) y22 = line.get_y2(olderLine) slope = (y2-y1)/(x2-x1) slope2 = (y22-y11)/(x22-x11) currentDistance = _index - x2 currentDistance2 = _index - x22 currentY2 = y2 + (currentDistance*slope) currentY22 = y22 + (currentDistance2*slope2) var closed = false if _close<=currentY2 and _close>=currentY22 and closed==false //Price within the Flags slope, extend to current price/bar line.set_x2(recentLine,_index) line.set_y2(recentLine,currentY2) line.set_x2(olderLine,_index) line.set_y2(olderLine,currentY22) //If price exits flag area cancel extension posibility if _close>currentY2 or _close<currentY22 closed := true //plot(close) if array.size(flag_index)>4 draw_lines(flag_price, flag_index, flag_array) if array.size(flag_index2)>4 draw_lines(flag_price2, flag_index2, flag_array) if array.size(flag_array)>2 extend_lines(flag_array, close, bar_index)
问题根源分析
- 变量作用域错误:
extend_lines函数内的var closed = false是全局共享变量,一旦价格第一次离开区间,closed被设为true后永远不会重置,导致所有线条后续都无法延伸。 - 状态未分组管理:所有旗形线共用同一个
closed状态,无法单独控制每组线条的延伸权限。
修复方案
1. 添加分组状态数组
创建与flag_array对应的布尔数组,单独记录每组旗形线是否停止延伸:
var bool[] flag_closed = array.new_bool()
2. 修改draw_lines函数,同步初始化状态
在创建新线条时,向flag_closed添加初始状态false:
draw_lines(_price, _index, _lineArray, closedArray)=> if array.size(_index)>=4 x1 = array.get(_index,1)-5 y1 = array.get(_price,1) x2 = array.get(_index,0)-5 y2 = array.get(_price,0) array.push(_lineArray, line.new(x1,y1,x2,y2, color=color.white)) array.push(closedArray, false) // 初始化该组线条为允许延伸 array.clear(_price) array.clear(_index)
3. 重构extend_lines函数,使用分组状态
遍历每组旗形线,根据对应状态判断是否允许延伸:
extend_lines(lineArray,_close,_index, closedArray)=> // 遍历所有成对的旗形线(每组2条线) for i from 0 to array.size(lineArray)-1 step 2 if i+1 >= array.size(lineArray) break // 获取当前组的两条线和对应的关闭状态 line1 = array.get(lineArray, i) line2 = array.get(lineArray, i+1) isClosed = array.get(closedArray, i/2) if not isClosed // 计算第一条线的延伸Y值 x1_line1 = line.get_x1(line1) y1_line1 = line.get_y1(line1) x2_line1 = line.get_x2(line1) y2_line1 = line.get_y2(line1) slope_line1 = (y2_line1 - y1_line1)/(x2_line1 - x1_line1) dist_line1 = _index - x2_line1 currentY_line1 = y2_line1 + (dist_line1 * slope_line1) // 计算第二条线的延伸Y值 x1_line2 = line.get_x1(line2) y1_line2 = line.get_y1(line2) x2_line2 = line.get_x2(line2) y2_line2 = line.get_y2(line2) slope_line2 = (y2_line2 - y1_line2)/(x2_line2 - x1_line2) dist_line2 = _index - x2_line2 currentY_line2 = y2_line2 + (dist_line2 * slope_line2) // 确定区间上下限(避免斜率导致的顺序颠倒) upperY = math.max(currentY_line1, currentY_line2) lowerY = math.min(currentY_line1, currentY_line2) if _close >= lowerY and _close <= upperY // 价格在区间内,延伸线条 line.set_x2(line1, _index) line.set_y2(line1, currentY_line1) line.set_x2(line2, _index) line.set_y2(line2, currentY_line2) else // 价格离开区间,标记该组为已关闭 array.set(closedArray, i/2, true)
4. 更新调用逻辑
在调用draw_lines和extend_lines时传入状态数组:
if array.size(flag_index)>4 draw_lines(flag_price, flag_index, flag_array, flag_closed) if array.size(flag_index2)>4 draw_lines(flag_price2, flag_index2, flag_array, flag_closed) if array.size(flag_array)>=2 extend_lines(flag_array, close, bar_index, flag_closed)
完整修复后代码
//@version=5 indicator("Line Extension Fixed", overlay=true, max_lines_count=20) ph = ta.pivothigh(high,5,5) pl = ta.pivotlow(low,5,5) plotshape(ph, color=#FF0000, location=location.abovebar, offset=-5) plotshape(pl, color=#00E600, location=location.belowbar, offset=-5) var line[] flag_array = array.new_line() var bool[] flag_closed = array.new_bool() // 记录每组旗形线是否停止延伸 var flag_price = array.new_float() var flag_index = array.new_int() var flag_price2 = array.new_float() var flag_index2 = array.new_int() arraySize = input.int(20, title="Array Size") add_to_array(_price,_index,_val) => array.unshift(_price,_val) array.unshift(_index,bar_index) if array.size(_index)>arraySize array.pop(_price) array.pop(_index) if ph add_to_array(flag_price,flag_index,ph) if pl add_to_array(flag_price2,flag_index2,pl) draw_lines(_price, _index, _lineArray, closedArray)=> if array.size(_index)>=4 x1 = array.get(_index,1)-5 y1 = array.get(_price,1) x2 = array.get(_index,0)-5 y2 = array.get(_price,0) array.push(_lineArray, line.new(x1,y1,x2,y2, color=color.white)) array.push(closedArray, false) // 初始化该组为允许延伸 array.clear(_price) array.clear(_index) extend_lines(lineArray,_close,_index, closedArray)=> // 按每组2条线遍历 for i from 0 to array.size(lineArray)-1 step 2 if i+1 >= array.size(lineArray) break line1 = array.get(lineArray, i) line2 = array.get(lineArray, i+1) groupIdx = i/2 isClosed = array.get(closedArray, groupIdx) if not isClosed // 计算第一条线的延伸参数 x1_line1 = line.get_x1(line1) y1_line1 = line.get_y1(line1) x2_line1 = line.get_x2(line1) y2_line1 = line.get_y2(line1) slope_line1 = (y2_line1 - y1_line1)/(x2_line1 - x1_line1) dist_line1 = _index - x2_line1 currentY_line1 = y2_line1 + (dist_line1 * slope_line1) // 计算第二条线的延伸参数 x1_line2 = line.get_x1(line2) y1_line2 = line.get_y1(line2) x2_line2 = line.get_x2(line2) y2_line2 = line.get_y2(line2) slope_line2 = (y2_line2 - y1_line2)/(x2_line2 - x1_line2) dist_line2 = _index - x2_line2 currentY_line2 = y2_line2 + (dist_line2 * slope_line2) // 确定区间上下限 upperY = math.max(currentY_line1, currentY_line2) lowerY = math.min(currentY_line1, currentY_line2) if _close >= lowerY and _close <= upperY // 价格在区间内,延伸线条 line.set_x2(line1, _index) line.set_y2(line1, currentY_line1) line.set_x2(line2, _index) line.set_y2(line2, currentY_line2) else // 价格离开,标记该组关闭 array.set(closedArray, groupIdx, true) // 调用逻辑 if array.size(flag_index)>4 draw_lines(flag_price, flag_index, flag_array, flag_closed) if array.size(flag_index2)>4 draw_lines(flag_price2, flag_index2, flag_array, flag_closed) if array.size(flag_array)>=2 extend_lines(flag_array, close, bar_index, flag_closed)
内容的提问来源于stack exchange,提问作者Acta Non Verba
相关产品推荐
相关产品推荐

