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

Pine Script多时间框架策略无报错却无交易执行问题求助

多时间框架趋势跟踪策略无交易执行问题排查

我基于ATR指标与Hull移动均线开发了一款多时间框架(当前时间框架+另外两个时间框架)的趋势跟踪策略脚本。脚本运行无报错,但始终未按设定条件执行任何交易。请帮忙排查代码是否存在问题?

//@version=5
strategy('Multi-Timeframe Trend Following Strategy', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10, calc_on_every_tick=true)

// User Inputs
current_tf = input.timeframe('', title='Current Timeframe')
primary_tf = input.timeframe('360', title='Primary Timeframe')
secondary_tf = input.timeframe('60', title='Secondary Timeframe')
exit_tf_options = input.string('Current Timeframe', title='Exit Timeframe', options=['Current Timeframe', 'Primary Timeframe', 'Secondary Timeframe'])

atrLength = input.int(21, title='ATR Length')
atrMultiplier = input.float(3, title='ATR Multiplier')
hullLength = input.int(21, title='Hull MA Length')
fractalLength = input.int(2, title='Fractal Length')

sensitivity = input.float(0.8, title='Sensitivity [0,1]', minval=0, maxval=1)
showSignals = input.bool(true, title='Reveal Long/Short Signals?')
showBarColor = input.bool(true, title='Show Bar-Color according to signals?')

// Function to calculate the signal logic
f_signal_logic(_src) =>
    sf = sensitivity
    avg = 0.
    src = sf * _src + (1 - sf) * nz(avg[1], _src)
    atr = ta.atr(atrLength)
    up = src - atrMultiplier * atr
    up1 = nz(up[1], up)
    up := close[1] > up1 ? math.max(up, up1) : up
    dn = src + atrMultiplier * atr
    dn1 = nz(dn[1], dn)
    dn := close[1] < dn1 ? math.min(dn, dn) : dn
    trend = 1
    trend := nz(trend[1], trend)
    trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
    [trend, up, dn]

[trend_cur, up_cur, dn_cur] = request.security(syminfo.tickerid, current_tf, f_signal_logic(hl2))
[trend_primary, up_primary, dn_primary] = request.security(syminfo.tickerid, primary_tf, f_signal_logic(hl2))
[trend_secondary, up_secondary, dn_secondary] = request.security(syminfo.tickerid, secondary_tf, f_signal_logic(hl2))

long_signal_current = trend_cur == 1 and trend_cur[1] == -1
short_signal_current = trend_cur == -1 and trend_cur[1] == 1

long_signal_primary = trend_primary == 1 and trend_primary[1] == -1
short_signal_primary = trend_primary == -1 and trend_primary[1] == 1

long_signal_secondary = trend_secondary == 1 and trend_secondary[1] == -1
short_signal_secondary = trend_secondary == -1 and trend_secondary[1] == 1

// Debugging signals to make sure they are being generated
plotshape(series=long_signal_current, location=location.belowbar, color=color.green, style=shape.labelup, text='Buy Current TF')
plotshape(series=short_signal_current, location=location.abovebar, color=color.red, style=shape.labeldown, text='Sell Current TF')
plotshape(series=long_signal_primary, location=location.belowbar, color=color.blue, style=shape.labelup, text='Buy Primary TF')
plotshape(series=short_signal_primary, location=location.abovebar, color=color.orange, style=shape.labeldown, text='Sell Primary TF')
plotshape(series=long_signal_secondary, location=location.belowbar, color=color.purple, style=shape.labelup, text='Buy Secondary TF')
plotshape(series=short_signal_secondary, location=location.abovebar, color=color.yellow, style=shape.labeldown, text='Sell Secondary TF')

longCondition = long_signal_current and long_signal_primary and long_signal_secondary
shortCondition = short_signal_current and short_signal_primary and short_signal_secondary

// Exit signals based on selected timeframe
var bool exit_long_signal = na
var bool exit_short_signal = na

if exit_tf_options == 'Current Timeframe'
    exit_long_signal := trend_cur == -1 and trend_cur[1] == 1
    exit_short_signal := trend_cur == 1 and trend_cur[1] == -1
else if exit_tf_options == 'Primary Timeframe'
    exit_long_signal := trend_primary == -1 and trend_primary[1] == 1
    exit_short_signal := trend_primary == 1 and trend_primary[1] == -1
else if exit_tf_options == 'Secondary Timeframe'
    exit_long_signal := trend_secondary == -1 and trend_secondary[1] == 1
    exit_short_signal := trend_secondary == 1 and trend_secondary[1] == -1

// Debugging prints
var table debug_table = table.new(position.top_right, 1, 10, border_width=1)
if barstate.islast
    table.cell(debug_table, 0, 0, text_color=color.white, bgcolor=color.red, text="Long Condition: " + str.tostring(longCondition))
    table.cell(debug_table, 0, 1, text_color=color.white, bgcolor=color.red, text="Short Condition: " + str.tostring(shortCondition))
    table.cell(debug_table, 0, 2, text_color=color.white, bgcolor=color.red, text="Exit Long Signal: " + str.tostring(exit_long_signal))
    table.cell(debug_table, 0, 3, text_color=color.white, bgcolor=color.red, text="Exit Short Signal: " + str.tostring(exit_short_signal))

// Entry conditions
long_condition = longCondition
short_condition = shortCondition

// Exit conditions
exit_long_condition = exit_long_signal
exit_short_condition = exit_short_signal

// Execute trades
if (long_condition)
    strategy.entry('Long', strategy.long)
if (exit_long_condition)
    strategy.close('Long')

if (short_condition)
    strategy.entry('Short', strategy.short)
if (exit_short_condition)
    strategy.close('Short')

// Plotting for visual confirmation
plotshape(series=long_condition and showSignals ? low : na, location=location.belowbar, color=color.new(color.green, 0), style=shape.labelup, text='Buy')
plotshape(series=short_condition and showSignals ? high : na, location=location.abovebar, color=color.new(color.red, 0), style=shape.labeldown, text='Sell')

bgcolor(long_condition and showBarColor ? color.new(color.green, 90) : na)
bgcolor(short_condition and showBarColor ? color.new(color.red, 90) : na)

// Debugging plots to verify signal generation
plot(series=long_signal_current ? 1 : na, color=color.green, title='Long Signal Current TF')
plot(series=short_signal_current ? 1 : na, color=color.red, title='Short Signal Current TF')
plot(series=long_signal_primary ? 1 : na, color=color.blue, title='Long Signal Primary TF')
plot(series=short_signal_primary ? 1 : na, color=color.orange, title='Short Signal Primary TF')
plot(series=long_signal_secondary ? 1 : na, color=color.purple, title='Long Signal Secondary TF')
plot(series=short_signal_secondary ? 1 : na, color=color.yellow, title='Short Signal Secondary TF')

核心问题排查

1. 信号逻辑函数f_signal_logic存在多处错误

  • 未实现Hull移动均线:代码声明了hullLength参数,但函数完全没有计算Hull MA,直接用hl2做错误的平滑处理,趋势判断逻辑和设计初衷完全不符。
  • 平滑变量avg初始化错误:avg = 0.是局部变量,每次调用函数都会重置,导致src = sf * _src + (1 - sf) * nz(avg[1], _src)等价于src = _src,平滑逻辑完全失效。
  • 下行轨道dn更新逻辑错误:dn := close[1] < dn1 ? math.min(dn, dn) : dn中math.min(dn, dn)等于原值,导致下行轨道永远不会更新,趋势反转判断完全错误。

2. 多时间框架开仓条件过于严苛

longCondition = long_signal_current and long_signal_primary and long_signal_secondary要求三个时间框架同时在同一根K线出现趋势反转信号,这种情况在实盘中几乎不可能发生,直接导致无法触发开仓。

3. 当前时间框架输入配置错误

current_tf = input.timeframe('', title='Current Timeframe')设置为空输入,request.security无法正确识别当前图表时间框架,导致trend_cur的信号数据异常。

修复方案

1. 修正信号逻辑函数,加入Hull MA计算

// Function to calculate the signal logic
f_signal_logic(_src) =>
    // 计算Hull移动均线
    hull_ma = ta.wma(2 * ta.wma(_src, math.round(hullLength / 2)) - ta.wma(_src, hullLength), math.round(math.sqrt(hullLength)))
    sf = sensitivity
    // 使用var声明avg,保留上一根K线的平滑值
    var float avg = na
    avg := na(avg) ? hull_ma : sf * hull_ma + (1 - sf) * avg
    src = avg
    atr = ta.atr(atrLength)
    up = src - atrMultiplier * atr
    up1 = nz(up[1], up)
    up := close[1] > up1 ? math.max(up, up1) : up
    dn = src + atrMultiplier * atr
    dn1 = nz(dn[1], dn)
    // 修正下行轨道更新逻辑
    dn := close[1] < dn1 ? math.min(dn, dn1) : dn
    trend = 1
    trend := nz(trend[1], trend)
    trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
    [trend, up, dn]

2. 调整开仓条件,降低触发门槛

改为要求三个时间框架趋势方向一致,同时当前时间框架出现反转信号:

// 多头开仓:三个时间框架均为多头趋势,且当前时间框架出现反转信号
longCondition = trend_cur == 1 and trend_primary == 1 and trend_secondary == 1 and long_signal_current
// 空头开仓:三个时间框架均为空头趋势,且当前时间框架出现反转信号
shortCondition = trend_cur == -1 and trend_primary == -1 and trend_secondary == -1 and short_signal_current

3. 修正当前时间框架输入

默认使用图表当前周期,避免空输入导致的异常:

current_tf = input.timeframe(timeframe.period, title='Current Timeframe')

额外调试建议

  • 观察plotshape绘制的单时间框架信号是否正常生成,确认每个时间框架的趋势逻辑修复生效。
  • 查看右上角调试表格的Long Condition和Short Condition值,确认开仓条件是否能被触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:05:54