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

Pine Script优化需求:仅显示蜡烛突破入场线的首个买入信号

问题描述

当蜡烛高点突破绿色入场线时,当前代码会生成6个重复的买入信号,但实际仅需要第一个突破入场线的蜡烛对应的买入信号。

问题根源

原代码的longCondition通过判断过去6根K线的buyLine值,只要当前K线高点大于其中任意一根的buyLine就触发信号,导致后续连续6根K线都满足条件,从而生成重复信号。

解决方案

添加状态变量记录信号触发状态,限制信号仅触发一次,直到止损后重置状态:

  • 用var类型布尔变量标记是否已触发过信号
  • 用ta.valuewhen()直接获取最近一次信号触发时的关键价格,替代多根K线的冗余判断
  • 仅当首次满足突破条件且未触发过信号时,生成买入/卖出标签
修改后的完整代码
//VWAP ploting
vwapSource = close
vwap = ta.vwap(vwapSource)
plot(vwap, color=color.blue, linewidth=2, title="VWAP")

//date and time input
inputTime =  input.time(timestamp("026 Jul 2023 09:45:00 GMT+5:30"), "Date")

//Searching Bar by time
searchBarTime = timestamp(year(time), month(time), dayofmonth(time), hour(inputTime), minute(inputTime))

// Check if the current bar matches the desired time
isTargetBar = time == searchBarTime

//ploting RSI and avg RSI
len = input(title="RSI Length", defval=14)
src = input(title="RSI Source", defval=close)
buffer = input(0.001, title="Buffer Length")
 
textColor = color.white
noneColor = color.new(color.white, 100)

ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "Bollinger Bands" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

maTypeInput = input.string("SMA", title="MA Type", options=["SMA", "Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA Settings")
maLengthInput = input.int(14, title="MA Length", group="MA Settings")
 
osc = ta.rsi(src, len)
rsiMA = ma(osc, maLengthInput, maTypeInput)

// plot(osc, title="RSI", linewidth=2, color=color.rgb(255, 255, 255, 20))
// plot(rsiMA, "RSI-based MA", color=color.yellow)

bufferHigh = high + (high * buffer)
bufferLow = low - (low * buffer)

bool isVwapAboveCandle = na
bool isVwapBelowCandle = na
bool isRsiAboveAvg = na
bool isRsipBelowAvg = na

if isTargetBar
    isVwapAboveCandle := vwap > close
    isVwapBelowCandle := vwap < close
    isRsiAboveAvg := osc > rsiMA
    isRsipBelowAvg := osc < rsiMA

buySignal = isVwapBelowCandle and isRsiAboveAvg
shortSignal = isVwapAboveCandle and isRsipBelowAvg


if buySignal
    buySignalTriangleUp = label.new(bar_index,(low-(0.004 * low)), style=label.style_triangleup, color=color.lime)

if shortSignal
    shortSignalTriangleDown = label.new(bar_index,(high+(0.004 * high)), style=label.style_triangledown, color=color.red)

// plotshape(buySignal, location = location.belowbar, style = shape.arrowup,  color = color.green, text ="BUY")
// plotshape(shortSignal, location = location.abovebar, style = shape.arrowdown,  color = color.red, text ="SHORT")

// //=====stoploss=====
var float sl = 0.0
for i = 1 to 5
    if buySignal or shortSignal //or shortcondition or pe_signalcondition1[i] or pe_signalcondition2[i])
        sl := bufferHigh - bufferLow
// //=========define target for long trades =======
tp1 = sl
tp2 = sl*2
tp3 = sl*3

if buySignal
    l1 = line.new ( bar_index, bufferHigh , bar_index + 7, bufferHigh, color = color.green, width = 2)
    l2 = line.new ( bar_index, bufferLow , bar_index + 7 , bufferLow , color = color.red , width = 2)
    l3 = line.new (bar_index, bufferHigh + tp1 , bar_index + 10 , bufferHigh+tp1, style=line.style_dotted, color=color.green, width = 1)
    l4 = line.new (bar_index, bufferHigh + tp2 , bar_index + 10 , bufferHigh+tp2, style=line.style_dotted, color=color.green, width = 1)
    l5 = line.new (bar_index, bufferHigh + tp3 , bar_index + 10 , bufferHigh+tp3, style=line.style_dotted, color=color.green, width = 1)
    
if shortSignal
    s1 = line.new ( bar_index, bufferLow , bar_index + 7, bufferLow, color = color.green, width = 2)
    s2 = line.new ( bar_index, bufferHigh , bar_index + 7, bufferHigh, color = color.red, width = 2)
    s3 = line.new ( bar_index, bufferLow - tp1, bar_index + 10, bufferLow - tp1, color = color.green,style=line.style_dotted, width = 1)
    s4 = line.new ( bar_index, bufferLow - tp2, bar_index + 10, bufferLow - tp2, color = color.green,style=line.style_dotted, width = 1)
    s5 = line.new ( bar_index, bufferLow - tp3, bar_index + 10, bufferLow - tp3, color = color.green,style=line.style_dotted, width = 1)

// 新增状态变量:标记是否已触发过信号
var bool hasTriggeredLong = false
var bool hasTriggeredShort = false

// 获取最近一次信号触发时的关键价格
lastBuyLine = ta.valuewhen(buySignal, bufferHigh, 0)
lastStopLossBuy = ta.valuewhen(buySignal, bufferLow, 0)
lastShortLine = ta.valuewhen(shortSignal, bufferLow, 0)
lastStopLossSell = ta.valuewhen(shortSignal, bufferHigh, 0)

longCondition = high >= lastBuyLine
longPositionNegated = low <= lastStopLossBuy
shortCondition = low <= lastShortLine
shortPositionNegated = high >= lastStopLossSell

if longPositionNegated
    pnL = label.new(bar_index,(low- (0.004 * low)), style=label.style_arrowup, color=color.white, text="pNeg", textcolor=color.white)
    label.delete(pnL)
    hasTriggeredLong := false  // 止损后重置状态,允许新信号

else if shortPositionNegated
    pnS = label.new(bar_index,(high+ (0.002 * high)), style=label.style_arrowdown, color=color.white, text="pNeg", textcolor=color.white)
    hasTriggeredShort := false  // 止损后重置状态,允许新信号
    
else if longCondition and not hasTriggeredLong
    p1 = label.new(bar_index,(low- (0.004 * low)), style=label.style_arrowup, color=color.white, text="BUY", textcolor=color.white)
    hasTriggeredLong := true  // 触发信号后标记为已触发

else if shortCondition and not hasTriggeredShort
    p2 = label.new(bar_index,(high+ (0.002 * high)), style=label.style_arrowdown, color=color.white, text="SELL", textcolor=color.white)
    hasTriggeredShort := true  // 触发信号后标记为已触发
关键修改说明
  1. 状态变量控制:新增hasTriggeredLong和hasTriggeredShort变量,确保信号仅触发一次,直到止损后重置
  2. 简化价格判断:用ta.valuewhen()直接获取最近一次信号触发时的入场/止损价格,替代原有的多根K线冗余判断
  3. 信号触发逻辑:仅当满足突破条件且未触发过信号时,才生成标签并标记状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:04:53