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

Pine Script v5自定义策略无入场信号问题排查求助

Pine Script v5自定义策略无入场信号问题排查与修复

问题描述

编写的Pine Script v5自定义策略无语法错误,但始终无法生成入场信号,已查阅官方手册、搜索同类问题、咨询工具均未解决。

原策略代码

//@version=5
strategy("Custom Strategy", overlay=true)

// First Indicator - v5i
length = input(20, title='Length')
mult = input(2, title='Multiplier')

atr_ = ta.atr(length)

var float max1 = 0.0
var float min1 = 0.0
var bool is_uptrend_prev = false
var float stop = 0.0
var float vstop_prev = 0.0
var float vstop1 = 0.0
var bool is_uptrend = false
var bool is_trend_changed = false
var float max_ = 0.0
var float min_ = 0.0
var float vstop = 0.0

max1 := math.max(nz(max1[1]), close)
min1 := math.min(nz(min1[1]), close)
is_uptrend_prev := nz(is_uptrend_prev[1], true)
stop := is_uptrend_prev ? max1 - mult * atr_ : min1 + mult * atr_
vstop_prev := nz(vstop[1])
vstop1 := is_uptrend_prev ? math.max(vstop_prev, stop) : math.min(vstop_prev, stop)
is_uptrend := close - vstop1 >= 0
is_trend_changed := is_uptrend != is_uptrend_prev
max_ := is_trend_changed ? close : max1
min_ := is_trend_changed ? close : min1
vstop := is_trend_changed ? is_uptrend ? max_ - mult * atr_ : min_ + mult * atr_ : vstop1

buysignal = is_trend_changed and close - vstop1 > 0
sellsignal = is_trend_changed and close - vstop1 < 0

// Debug labels
label.new(bar_index, buysignal ? close : na, text="buysignal: " + str.tostring(buysignal), color=color.green, textcolor=color.white, style=label.style_label_left)
label.new(bar_index, sellsignal ? close : na, text="sellsignal: " + str.tostring(sellsignal), color=color.red, textcolor=color.white, style=label.style_label_left)
label.new(bar_index, vstop, text="vstop: " + str.tostring(vstop), color=color.yellow, textcolor=color.black, style=label.style_label_left)

// Second Indicator - Swing Points and Liquidity
swingSizeR = input.int(10, 'Bars Right-Left', inline='brl')
swingSizeL = input.int(15, '-', inline='brl')

// Pivot calculations
var int prevHighIndex = na
var int prevLowIndex = na
var bool highActive = false
var bool lowActive = false
var bool h = false
var bool l = false
pivHi = ta.pivothigh(high, swingSizeL, swingSizeR)
pivLo = ta.pivotlow(low, swingSizeL, swingSizeR)

// Variables for managing positions and stop loss
var bool longPosition = false
var bool shortPosition = false
var float stopLossLevel = na

lastPivHiHigh = ta.valuewhen(pivHi != 0, high[pivHi], 0)
previousPivHiHigh = ta.valuewhen(pivHi != 0, high[pivHi], 1)
isLastPivHiHigher = lastPivHiHigh > previousPivHiHigh
lastPivLoLow = ta.valuewhen(pivLo != 0, low[pivLo], 0)
previousPivLoLow = ta.valuewhen(pivLo != 0, low[pivLo], 1)
isLastPivLoLow = lastPivLoLow < previousPivLoLow

// Entry conditions and management
if buysignal and not longPosition
    longPosition := true
    stopLossLevel := ta.valuewhen(pivLo != 0, low[pivLo], 1)
    strategy.entry("Long", strategy.long)
    strategy.exit("Long TP", "Long", limit=vstop)
    strategy.exit("Long SL", "Long", stop=isLastPivHiHigher ? (ta.valuewhen(pivHi != 0, high[pivHi], 0)) : stopLossLevel)

if sellsignal and not shortPosition
    shortPosition := true
    stopLossLevel := ta.valuewhen(pivHi != 0, high[pivHi], 1)
    strategy.entry("Short", strategy.short)
    strategy.exit("Short TP", "Short", limit=vstop)
    strategy.exit("Short SL", "Short", stop=isLastPivLoLow ? (ta.valuewhen(pivLo != 0, low[pivLo], 0)) : stopLossLevel)

plot(pivHi != 0 ? high[pivHi] : na, title="Pivot High", color=color.red, style=plot.style_circles, linewidth=2, transp=0)
plot(pivLo != 0 ? low[pivLo] : na, title="Pivot Low", color=color.green, style=plot.style_circles, linewidth=2, transp=0)

核心问题分析

  1. 初始值设置错误:

    • max1和min1初始为0.0,与真实行情价格偏差极大,导致初始阶段vstop1计算完全失真。
    • is_uptrend_prev初始设为true,结合错误的vstop1,使得is_uptrend始终为true,is_trend_changed永远不会触发,最终buysignal和sellsignal始终为false。
  2. 趋势变更判断逻辑失效:
    由于初始值异常,is_uptrend从未发生变化,直接导致入场信号的核心触发条件is_trend_changed始终不成立。

修复后的策略代码

//@version=5
strategy("Custom Strategy Fixed", overlay=true)

// First Indicator - v5i
length = input(20, title='Length')
mult = input(2, title='Multiplier')

atr_ = ta.atr(length)

// 修正初始值:用第一个bar的真实价格初始化核心变量
var float max1 = na
var float min1 = na
var bool is_uptrend_prev = na
var float stop = na
var float vstop_prev = na
var float vstop1 = na
var bool is_uptrend = na
var bool is_trend_changed = false
var float max_ = na
var float min_ = na
var float vstop = na

// 手动初始化第一个bar的变量,避免0值干扰
if bar_index == 0
    max1 := close
    min1 := close
    is_uptrend_prev := true
    stop := max1 - mult * atr_
    vstop_prev := stop
    vstop1 := stop
    is_uptrend := true
else
    max1 := math.max(max1[1], close)
    min1 := math.min(min1[1], close)
    is_uptrend_prev := is_uptrend[1]
    stop := is_uptrend_prev ? max1 - mult * atr_ : min1 + mult * atr_
    vstop_prev := vstop[1]
    vstop1 := is_uptrend_prev ? math.max(vstop_prev, stop) : math.min(vstop_prev, stop)
    is_uptrend := close > vstop1
    is_trend_changed := is_uptrend != is_uptrend_prev
    max_ := is_trend_changed ? close : max1
    min_ := is_trend_changed ? close : min1
    vstop := is_trend_changed ? (is_uptrend ? max_ - mult * atr_ : min_ + mult * atr_) : vstop1

// 简化买卖信号判断逻辑
buysignal = is_trend_changed and is_uptrend
sellsignal = is_trend_changed and not is_uptrend

// Debug labels
label.new(bar_index, buysignal ? close : na, text="buysignal: " + str.tostring(buysignal), color=color.green, textcolor=color.white, style=label.style_label_left)
label.new(bar_index, sellsignal ? close : na, text="sellsignal: " + str.tostring(sellsignal), color=color.red, textcolor=color.white, style=label.style_label_left)
label.new(bar_index, vstop, text="vstop: " + str.tostring(vstop), color=color.yellow, textcolor=color.black, style=label.style_label_left)

// Second Indicator - Swing Points and Liquidity
swingSizeR = input.int(10, 'Bars Right-Left', inline='brl')
swingSizeL = input.int(15, '-', inline='brl')

// Pivot calculations
var int prevHighIndex = na
var int prevLowIndex = na
var bool highActive = false
var bool lowActive = false
var bool h = false
var bool l = false
pivHi = ta.pivothigh(high, swingSizeL, swingSizeR)
pivLo = ta.pivotlow(low, swingSizeL, swingSizeR)

// Variables for managing positions and stop loss
var bool longPosition = false
var bool shortPosition = false
var float stopLossLevel = na

lastPivHiHigh = ta.valuewhen(pivHi != 0, high[pivHi], 0)
previousPivHiHigh = ta.valuewhen(pivHi != 0, high[pivHi], 1)
isLastPivHiHigher = lastPivHiHigh > previousPivHiHigh
lastPivLoLow = ta.valuewhen(pivLo != 0, low[pivLo], 0)
previousPivLoLow = ta.valuewhen(pivLo != 0, low[pivLo], 1)
isLastPivLoLow = lastPivLoLow < previousPivLoLow

// Entry conditions and management
if buysignal and not longPosition and not na(pivLo)
    longPosition := true
    shortPosition := false
    stopLossLevel := ta.valuewhen(pivLo != 0, low[pivLo], 1)
    strategy.entry("Long", strategy.long)
    // 合并止盈止损设置,避免重复调用异常
    strategy.exit("Long Exit", "Long", limit=vstop, stop=isLastPivHiHigher ? ta.valuewhen(pivHi != 0, high[pivHi], 0) : stopLossLevel)

if sellsignal and not shortPosition and not na(pivHi)
    shortPosition := true
    longPosition := false
    stopLossLevel := ta.valuewhen(pivHi != 0, high[pivHi], 1)
    strategy.entry("Short", strategy.short)
    strategy.exit("Short Exit", "Short", limit=vstop, stop=isLastPivLoLow ? ta.valuewhen(pivLo != 0, low[pivLo], 0) : stopLossLevel)

plot(pivHi != 0 ? high[pivHi] : na, title="Pivot High", color=color.red, style=plot.style_circles, linewidth=2, transp=0)
plot(pivLo != 0 ? low[pivLo] : na, title="Pivot Low", color=color.green, style=plot.style_circles, linewidth=2, transp=0)

修复说明

  1. 变量初始化修正:在第一个bar手动用真实价格初始化核心变量,彻底解决0值导致的价格偏差问题。
  2. 趋势判断逻辑优化:简化买卖信号的判断逻辑,直接基于趋势变更和当前趋势方向,提升可读性和可靠性。
  3. 入场条件增强:添加枢轴点非空判断,避免因枢轴点未生成导致的无效入场操作。
  4. 仓位状态同步:开仓时同步更新对立仓位状态,避免逻辑冲突。
  5. 止盈止损合并:将同一仓位的止盈止损合并到单个strategy.exit调用中,避免重复设置引发的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:25:02