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

如何计算TradingView中过去200根K线偏离20 SMA的最大百分比?

问题:获取价格偏离20周期SMA的最大静态值

尝试通过编程确定某资产价格偏离20周期简单移动平均线(20 SMA)最大的时刻。编写代码循环遍历过去200根K线,计算收盘价与20 SMA的百分比差值并存入数组,再通过array.max()计算最大百分比变化。预期maxOverMA为静态值,但实际该值是动态的,无法正确获取价格偏离20 SMA的最大时刻。

原代码:

//@version=5
indicator("Secret Algo", overlay=true, max_labels_count=500)
    
// Functions
pine_sma(source, length) =>
    sum = 0.0
    for i = 0 to length - 1
        sum += source[i] / length
    sum

// Variables
MA = ta.sma(close, 20)
maPercentage = (close - MA) / MA * 100
maHistory = array.new_float(0)

// Determine historical max, min and avg deviation from MA
for i = 1 to 200
    tempMA = pine_sma(close, 20)
    tempMaPercentage = (close - tempMA) / tempMA * 100
    maHistory.push(tempMaPercentage)

// Set MA ranges
maxOverMA = array.max(maHistory)
maxUnderMA = array.min(maHistory)

label.new(bar_index, close, str.tostring(maxOverMA), textcolor=color.red, style=label.style_none)

问题分析

  • 数组未持久化:每根K线都会重新创建maHistory数组,导致每次都要重新填充数据,无法累积历史值。
  • 历史数据回溯错误:循环中计算的始终是当前K线的20周期SMA,没有偏移到过去的K线,数组里存的都是当前K线的偏离值,而非历史200根K线的各自偏离值。
  • 循环逻辑无效:for i=1 to 200只是重复200次添加当前K线的偏离值,并没有遍历过去200根K线。

优化方案

方案1:用内置函数直接计算历史极值(最简)

利用Pine Script内置的ta.highest()和ta.lowest(),直接计算过去200根K线中偏离值的最大/最小值:

//@version=5
indicator("Secret Algo", overlay=true, max_labels_count=500)

// 计算当前K线的价格偏离20SMA百分比
ma20 = ta.sma(close, 20)
deviation_pct = (close - ma20) / ma20 * 100

// 计算过去200根K线中的最大/最小偏离值(200根K线后变为静态值)
lookback_length = 200
maxOverMA = ta.highest(deviation_pct, lookback_length)
maxUnderMA = ta.lowest(deviation_pct, lookback_length)

// 仅在最后一根K线显示标签,避免重复绘制
if barstate.islast
    label.new(bar_index, close, str.tostring(maxOverMA, "#.##"), textcolor=color.red, style=label.style_none)

方案2:手动维护历史数组(适合自定义逻辑)

用var声明数组确保只初始化一次,通过偏移i获取过去每根K线的偏离值:

//@version=5
indicator("Secret Algo", overlay=true, max_labels_count=500)

// 计算每根K线的偏离值序列
ma20 = ta.sma(close, 20)
deviation_pct = (close - ma20) / ma20 * 100

// var声明数组,确保仅初始化一次
var float[] maHistory = array.new_float()
lookback_length = 200

// 当K线数足够时,填充过去200根K线的偏离值(仅执行一次)
if bar_index == lookback_length - 1
    for i = 0 to lookback_length - 1
        // 偏移i获取过去第i根K线的偏离值
        array.push(maHistory, deviation_pct[i])

// 获取数组中的极值
maxOverMA = array.size(maHistory) > 0 ? array.max(maHistory) : na
maxUnderMA = array.size(maHistory) > 0 ? array.min(maHistory) : na

// 最后一根K线显示结果
if barstate.islast
    label.new(bar_index, close, str.tostring(maxOverMA, "#.##"), textcolor=color.red, style=label.style_none)

关键优化点说明

  • var关键字:声明持久化变量,避免数组在每根K线重新创建,保留历史数据。
  • 历史数据偏移:通过deviation_pct[i]获取过去第i根K线的偏离值,而非重复使用当前值。
  • barstate.islast:仅在最后一根K线绘制标签,避免重复创建标签,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:32:49