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

基于5分钟K线手动计算15分钟ATR偏移问题排查

自定义15分钟ATR与原生ATR偏移问题排查与修复

问题描述

我尝试通过修改版TR(真实波幅)和RMA函数,基于security函数获取的数据计算15分钟K线的ATR,开发已接近完成,但发现自定义计算的ATR与原生ATR存在偏移,无法定位问题原因,特附上Pine Script代码寻求帮助。

原代码

//@version=5
indicator("Table with Indicators", overlay=true, dynamic_requests=true)

if timeframe.period != "5"
    log.error("This script runs on 5m timeframe only.")
    label.new(bar_index, high, "Please use 5m timeframe only!", color=color.red, textcolor=color.white, size=size.small)
    runtime.error("This script runs on 5m timeframe only.")

rma(x, y, preSumIndex) =>
    alpha = y
    var float sum = na
    sum := (x + (alpha - 1) * nz(sum[preSumIndex])) / alpha

tr(_high, _low, preClose) =>
    math.max(_high - _low, math.max(math.abs(_high - preClose), math.abs(_low - preClose)))

var float atr15 = na
var float trueRange = na
var fixChartTimeframe = timeframe.period
var timeframe = 15

period_length = timeframe/str.tonumber(fixChartTimeframe)

timeframe_in_ms = timeframe * 60 * 1000
length = 14

current_time = time
start_time = current_time - (current_time % timeframe_in_ms)
time_elapsed = (current_time - start_time) / 1000
bars_since_period_start = int(time_elapsed / (5 * 60))  // 5 Minuten = 300 Sekunden
int period_offset = math.round(bars_since_period_start % period_length)
pre_candle_index = period_offset + 1

[h5, l5, c5] = request.security(syminfo.tickerid, "5", [high, low, close], lookahead=barmerge.lookahead_off)
log.error(str.tostring(period_offset))

float h15 = h5[0]
float l15 = l5[0]
float c15 = c5[0]

bool isCandleEnd = (period_offset == period_length - 1) or barstate.islast

if period_offset > 0
    h15 := ta.highest(h15, period_offset)
    l15 := ta.lowest(l15, period_offset)

if isCandleEnd
    trueRange := tr(h5, l5, c5[pre_candle_index])
    atr15 := rma(trueRange, length, pre_candle_index)

atr15_native = request.security(syminfo.tickerid, str.tostring(timeframe), ta.atr(length), lookahead=barmerge.lookahead_off)

plot(atr15_native, title="ATR 15min native", color=color.red, linewidth=2)
plot(atr15, title="ATR 15min", color=color.blue, linewidth=2)

问题根源

  1. RMA函数逻辑错误:原生RMA的alpha是1/length,而非直接传入length;递归依赖的是前一根目标周期的RMA值,而非自定义的偏移索引preSumIndex,这导致计算的平滑系数和递归逻辑完全错误。
  2. TR计算错误:自定义TR使用的是当前5分钟K线的高低价,而非合并后的15分钟K线高低价;且前收盘价用的是偏移后的5分钟收盘价,不是前一根15分钟K线的收盘价,导致真实波幅计算完全偏离标准。
  3. 周期更新时机错误:isCandleEnd的判断逻辑存在误差,尤其是barstate.islast的加入会导致未闭合的15分钟K线也触发ATR更新,与原生ATR仅在K线闭合时更新的规则不符。

修复后的代码

//@version=5
indicator("Custom 15min ATR vs Native", overlay=false, dynamic_requests=true)

// 仅允许在5分钟周期运行
if timeframe.period != "5"
    label.new(bar_index, high, "请使用5分钟周期!", color=color.red, textcolor=color.white, size=size.small)
    runtime.error("此脚本仅支持5分钟周期")

// 标准RMA实现:alpha = 1/length,递归基于前一根值
rma_custom(x, length) =>
    alpha = 1 / length
    var float rma_val = na
    rma_val := na(rma_val) ? ta.sma(x, length) : alpha * x + (1 - alpha) * nz(rma_val[1])

// 标准TR计算
tr_custom(_high, _low, _pre_close) =>
    math.max(_high - _low, math.max(math.abs(_high - _pre_close), math.abs(_low - _pre_close)))

// 目标周期参数
target_tf = "15"
atr_length = 14

// 获取15分钟周期的高低收数据(包含历史完整K线)
[h15, l15, c15] = request.security(syminfo.tickerid, target_tf, [high, low, close], lookahead=barmerge.lookahead_off)
// 获取前一根15分钟K线的收盘价
pre_c15 = request.security(syminfo.tickerid, target_tf, close[1], lookahead=barmerge.lookahead_off)

// 仅当15分钟K线闭合时计算TR和更新ATR
var float custom_atr = na
if barstate.isrealtime ? ta.change(time(timeframe.period, target_tf)) : true
    current_tr = tr_custom(h15, l15, pre_c15)
    custom_atr := rma_custom(current_tr, atr_length)

// 获取原生15分钟ATR
native_atr = request.security(syminfo.tickerid, target_tf, ta.atr(atr_length), lookahead=barmerge.lookahead_off)

// 绘图对比
plot(native_atr, title="原生15分钟ATR", color=color.red, linewidth=2)
plot(custom_atr, title="自定义15分钟ATR", color=color.blue, linewidth=2)

关键修复点

  • 实现标准RMA算法:初始值用SMA,递归使用alpha * 当前值 + (1-alpha)*前值的标准逻辑
  • 正确计算15分钟TR:使用合并后的15分钟K线高低价,以及前一根15分钟K线的收盘价
  • 精准控制ATR更新时机:仅在15分钟K线闭合时(通过ta.change(time(...))判断周期切换)更新ATR,与原生ATR的更新逻辑完全同步
  • 简化数据获取:直接通过request.security获取完整的15分钟K线数据,避免手动合并5分钟数据的误差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:35:21